https://mooseframework.inl.gov
MeshAlignmentOneToMany.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "MeshAlignmentOneToMany.h"
11 #include "KDTree.h"
12 #include "MooseUtils.h"
13 
15  : MeshAlignmentBase(mesh), _max_coupling_size(0)
16 {
17 }
18 
19 void
21 {
22  // Build the element mapping
23  if (_primary_elem_points.size() > 0 && _secondary_elem_points.size() > 0)
24  {
25  // find the primary elements that are nearest to the secondary elements
27  for (std::size_t i_secondary = 0; i_secondary < _secondary_elem_points.size(); i_secondary++)
28  {
29  unsigned int patch_size = 1;
30  std::vector<std::size_t> return_index(patch_size);
31  kd_tree.neighborSearch(_secondary_elem_points[i_secondary], patch_size, return_index);
32  const std::size_t i_primary = return_index[0];
33 
34  const auto primary_elem_id = _primary_elem_ids[i_primary];
35  const auto secondary_elem_id = _secondary_elem_ids[i_secondary];
36 
37  _secondary_elem_id_to_primary_elem_id[secondary_elem_id] = primary_elem_id;
38 
39  auto it = _primary_elem_id_to_secondary_elem_ids.find(primary_elem_id);
41  _primary_elem_id_to_secondary_elem_ids.insert({primary_elem_id, {secondary_elem_id}});
42  else
43  it->second.push_back(secondary_elem_id);
44  }
45 
46  // Determine max coupling size
47  for (const auto primary_elem_id : _primary_elem_ids)
48  if (hasCoupledSecondaryElemIDs(primary_elem_id))
49  {
50  const auto & secondary_elem_ids = getCoupledSecondaryElemIDs(primary_elem_id);
51  _max_coupling_size = std::max(secondary_elem_ids.size(), _max_coupling_size);
52  }
53  }
54 }
55 
56 void
57 MeshAlignmentOneToMany::checkAlignment(const Point & axis_point,
58  const RealVectorValue & axis_direction)
59 {
60  if (_primary_elem_points.size() > 0 && _secondary_elem_points.size() > 0)
61  {
62  // Check if meshes are aligned: all secondary boundary faces paired to a
63  // primary element/face must have the same axial coordinate.
64  _meshes_are_aligned = true;
65  for (const auto i_primary : index_range(_primary_elem_ids))
66  {
67  const auto primary_elem_id = _primary_elem_ids[i_primary];
68  const auto primary_elem_point = _primary_elem_points[i_primary];
69  const auto primary_ax_coord = axis_direction * (primary_elem_point - axis_point);
70 
71  if (hasCoupledSecondaryElemIDs(primary_elem_id))
72  {
73  const auto & secondary_elem_ids = getCoupledSecondaryElemIDs(primary_elem_id);
74  for (const auto secondary_elem_id : secondary_elem_ids)
75  {
76  auto it =
77  std::find(_secondary_elem_ids.begin(), _secondary_elem_ids.end(), secondary_elem_id);
78  const auto i_secondary = std::distance(_secondary_elem_ids.begin(), it);
79  const auto secondary_elem_point = _secondary_elem_points[i_secondary];
80  const auto secondary_ax_coord = axis_direction * (secondary_elem_point - axis_point);
81  if (!MooseUtils::absoluteFuzzyEqual(secondary_ax_coord, primary_ax_coord))
82  _meshes_are_aligned = false;
83  }
84  }
85  else
86  _meshes_are_aligned = false;
87  }
88  }
89 }
90 
91 bool
93 {
94  return _secondary_elem_id_to_primary_elem_id.find(secondary_elem_id) !=
96 }
97 
100 {
101  mooseAssert(hasCoupledPrimaryElemID(secondary_elem_id),
102  "The element ID has no coupled elements.");
103  return _secondary_elem_id_to_primary_elem_id.find(secondary_elem_id)->second;
104 }
105 
106 bool
108 {
109  return _primary_elem_id_to_secondary_elem_ids.find(primary_elem_id) !=
111 }
112 
113 const std::vector<dof_id_type> &
115 {
116  mooseAssert(hasCoupledSecondaryElemIDs(primary_elem_id),
117  "The element ID has no coupled elements.");
118  return _primary_elem_id_to_secondary_elem_ids.find(primary_elem_id)->second;
119 }
120 
121 unsigned int
123  const unsigned int & secondary_qp) const
124 {
125  auto it = _secondary_elem_id_to_qp_indices.find(secondary_elem_id);
126  mooseAssert(it != _secondary_elem_id_to_qp_indices.end(),
127  "The element ID has no coupled quadrature point indices.");
128  mooseAssert(secondary_qp < it->second.size(), "The quadrature index does not exist in the map.");
129  return it->second[secondary_qp];
130 }
std::vector< Point > _secondary_elem_points
List of secondary element points.
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Builds mapping between two aligned subdomains/boundaries.
bool hasCoupledPrimaryElemID(const dof_id_type &secondary_elem_id) const
Returns true if the given secondary element ID has a coupled primary element.
std::map< dof_id_type, std::vector< unsigned int > > _secondary_elem_id_to_qp_indices
Map of secondary element ID to vector of coupled quadrature points.
const MooseMesh & _mesh
Mesh.
bool _meshes_are_aligned
Flag that meshes are aligned.
unsigned long _max_coupling_size
The maximum number of secondary elements coupled to any primary element.
MeshBase & mesh
std::vector< dof_id_type > _secondary_elem_ids
List of secondary element IDs.
unsigned int getCoupledPrimaryElemQpIndex(const dof_id_type &secondary_elem_id, const unsigned int &secondary_qp) const
Gets the quadrature point index on the primary element corresponding to the quadrature point index on...
void buildMapping()
Builds the mapping using the extracted mesh information.
unsigned int getMaxLeafSize() const
std::vector< Point > _primary_elem_points
List of primary element points.
std::map< dof_id_type, std::vector< dof_id_type > > _primary_elem_id_to_secondary_elem_ids
Map of primary element ID to coupled secondary element IDs.
dof_id_type getCoupledPrimaryElemID(const dof_id_type &secondary_elem_id) const
Gets the coupled primary element ID for a given secondary element ID.
std::map< dof_id_type, dof_id_type > _secondary_elem_id_to_primary_elem_id
Map of secondary element ID to coupled primary element ID.
std::vector< dof_id_type > _primary_elem_ids
List of primary element IDs.
const std::vector< dof_id_type > & getCoupledSecondaryElemIDs(const dof_id_type &primary_elem_id) const
Gets the coupled secondary element IDs for a given primary element ID.
MeshAlignmentOneToMany(const MooseMesh &mesh)
Constructor.
void checkAlignment(const Point &axis_point, const RealVectorValue &axis_direction)
Checks the alignment and sets _mesh_alignment accordingly.
auto index_range(const T &sizable)
bool hasCoupledSecondaryElemIDs(const dof_id_type &primary_elem_id) const
Returns true if the given primary element ID has coupled secondary elements.
uint8_t dof_id_type