libMesh
Public Member Functions | Private Member Functions | Private Attributes | List of all members
libMesh::VariationalSmootherConstraint Class Reference

#include <variational_smoother_constraint.h>

Inheritance diagram for libMesh::VariationalSmootherConstraint:
[legend]

Public Member Functions

 VariationalSmootherConstraint (System &sys, const bool &preserve_subdomain_boundaries)
 
virtual ~VariationalSmootherConstraint () override
 
virtual void constrain () override
 Constraint function. More...
 

Private Member Functions

void fix_node (const Node &node)
 

Private Attributes

System_sys
 
const bool _preserve_subdomain_boundaries
 Whether nodes on subdomain boundaries are subject to change via smoothing. More...
 

Detailed Description

Definition at line 34 of file variational_smoother_constraint.h.

Constructor & Destructor Documentation

◆ VariationalSmootherConstraint()

libMesh::VariationalSmootherConstraint::VariationalSmootherConstraint ( System sys,
const bool &  preserve_subdomain_boundaries 
)

Definition at line 25 of file variational_smoother_constraint.C.

26  :
27  Constraint(),
28  _sys(sys),
29  _preserve_subdomain_boundaries(preserve_subdomain_boundaries)
30  {}
const bool _preserve_subdomain_boundaries
Whether nodes on subdomain boundaries are subject to change via smoothing.

◆ ~VariationalSmootherConstraint()

libMesh::VariationalSmootherConstraint::~VariationalSmootherConstraint ( )
overridevirtualdefault

Member Function Documentation

◆ constrain()

void libMesh::VariationalSmootherConstraint::constrain ( )
overridevirtual

Constraint function.

This function will be called to constrain the system prior to a solve and must be provided by the user in a derived class.

Implements libMesh::System::Constraint.

Definition at line 34 of file variational_smoother_constraint.C.

References _preserve_subdomain_boundaries, _sys, libMesh::MeshTools::build_nodes_to_elem_map(), libMesh::MeshTools::find_boundary_nodes(), libMesh::MeshTools::find_nodal_neighbors(), fix_node(), libMesh::System::get_mesh(), and mesh.

35 {
36  auto & mesh = _sys.get_mesh();
37 
38  // Only compute the node to elem map once
39  std::unordered_map<dof_id_type, std::vector<const Elem *>> nodes_to_elem_map;
40  MeshTools::build_nodes_to_elem_map(mesh, nodes_to_elem_map);
41 
42  const auto boundary_node_ids = MeshTools::find_boundary_nodes (mesh);
43  for (const auto & bid : boundary_node_ids)
44  {
45  const auto & node = mesh.node_ref(bid);
46  // Find all the nodal neighbors... that is the nodes directly connected
47  // to this node through one edge
48  std::vector<const Node *> neighbors;
49  MeshTools::find_nodal_neighbors(mesh, node, nodes_to_elem_map, neighbors);
50 
51  // Remove any neighbors that are not boundary nodes
52  neighbors.erase(
53  std::remove_if(neighbors.begin(), neighbors.end(),
54  [&boundary_node_ids](const Node * neigh) {
55  return boundary_node_ids.find(neigh->id()) == boundary_node_ids.end();
56  }
57  ),
58  neighbors.end()
59  );
60 
61  // if 2D, determine if node and neighbors lie on the same line
62  // if 3D, determine if node and neighbors lie on the same plane
63  // if not same line/plane, then node is either part of a curved surface or
64  // it is the vertex where two boundary surfaces meet. In the first case,
65  // we should just fix the node. For the latter case:
66  // - 2D: just fix the node
67  // - 3D: If the node is at the intersection of 3 surfaces (i.e., the
68  // vertex of a cube), fix the node. If the node is at the intersection
69  // of 2 surfaces (i.e., the edge of a cube), constrain it to slide along
70  // this edge.
71 
72  // But for now, just fix all the boundary nodes to not move
73  this->fix_node(node);
74 
75  }// end bid
76 
77  // Constrain subdomain boundary nodes, if requested
79  {
80  auto already_constrained_node_ids = boundary_node_ids;
81  for (const auto * elem : mesh.active_element_ptr_range())
82  {
83  const auto & subdomain_id = elem->subdomain_id();
84  for (const auto side : elem->side_index_range())
85  {
86  const auto * neighbor = elem->neighbor_ptr(side);
87  if (neighbor == nullptr)
88  continue;
89 
90  const auto & neighbor_subdomain_id = neighbor->subdomain_id();
91  if (subdomain_id != neighbor_subdomain_id)
92  {
93  for (const auto local_node_id : elem->nodes_on_side(side))
94  {
95  const auto & node = mesh.node_ref(elem->node_id(local_node_id));
96  // Make sure we haven't already constrained this node
97  if (
98  std::find(already_constrained_node_ids.begin(),
99  already_constrained_node_ids.end(),
100  node.id()) == already_constrained_node_ids.end()
101  )
102  {
103  this->fix_node(node);
104  already_constrained_node_ids.insert(node.id());
105  }
106  }//for local_node_id
107  }
108  }// for side
109  }// for elem
110  }
111 
112 }
MeshBase & mesh
void find_nodal_neighbors(const MeshBase &mesh, const Node &n, const std::vector< 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...
Definition: mesh_tools.C:1036
void build_nodes_to_elem_map(const MeshBase &mesh, std::vector< std::vector< dof_id_type >> &nodes_to_elem_map)
After calling this function the input vector nodes_to_elem_map will contain the node to element conne...
Definition: mesh_tools.C:449
const MeshBase & get_mesh() const
Definition: system.h:2358
std::unordered_set< dof_id_type > find_boundary_nodes(const MeshBase &mesh)
Calling this function on a 2D mesh will convert all the elements to triangles.
Definition: mesh_tools.C:517
const bool _preserve_subdomain_boundaries
Whether nodes on subdomain boundaries are subject to change via smoothing.

◆ fix_node()

void libMesh::VariationalSmootherConstraint::fix_node ( const Node node)
private

Definition at line 114 of file variational_smoother_constraint.C.

References _sys, libMesh::DofMap::add_constraint_row(), libMesh::DofObject::dof_number(), libMesh::System::get_dof_map(), libMesh::System::get_mesh(), libMesh::make_range(), libMesh::MeshBase::mesh_dimension(), and libMesh::System::number().

Referenced by constrain().

115 {
116  for (const auto d : make_range(_sys.get_mesh().mesh_dimension()))
117  {
118  const auto constrained_dof_index = node.dof_number(_sys.number(), d, 0);
119  DofConstraintRow constraint_row;
120  // Leave the constraint row as all zeros so this dof is independent from other dofs
121  const auto constrained_value = node(d);
122  // Simply constrain this dof to retain it's current value
123  _sys.get_dof_map().add_constraint_row( constrained_dof_index, constraint_row, constrained_value, true);
124  }
125 }
const MeshBase & get_mesh() const
Definition: system.h:2358
unsigned int number() const
Definition: system.h:2350
void add_constraint_row(const dof_id_type dof_number, const DofConstraintRow &constraint_row, const Number constraint_rhs, const bool forbid_constraint_overwrite)
Adds a copy of the user-defined row to the constraint matrix, using an inhomogeneous right-hand-side ...
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
A row of the Dof constraint matrix.
Definition: dof_map.h:100
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
unsigned int mesh_dimension() const
Definition: mesh_base.C:372
const DofMap & get_dof_map() const
Definition: system.h:2374

Member Data Documentation

◆ _preserve_subdomain_boundaries

const bool libMesh::VariationalSmootherConstraint::_preserve_subdomain_boundaries
private

Whether nodes on subdomain boundaries are subject to change via smoothing.

Definition at line 41 of file variational_smoother_constraint.h.

Referenced by constrain().

◆ _sys

System& libMesh::VariationalSmootherConstraint::_sys
private

Definition at line 38 of file variational_smoother_constraint.h.

Referenced by constrain(), and fix_node().


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