www.mooseframework.org
DiracKernelInfo.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
15 #include "DiracKernelInfo.h"
16 #include "MooseMesh.h"
17 
18 // LibMesh
19 #include "libmesh/point_locator_base.h"
20 #include "libmesh/elem.h"
21 
23  : _point_locator(), _point_equal_distance_sq(libMesh::TOLERANCE * libMesh::TOLERANCE)
24 {
25 }
26 
28 
29 void
30 DiracKernelInfo::addPoint(const Elem * elem, Point p)
31 {
32  _elements.insert(elem);
33 
34  std::pair<std::vector<Point>, std::vector<unsigned int>> & multi_point_list = _points[elem];
35 
36  const unsigned int npoint = multi_point_list.first.size();
37  mooseAssert(npoint == multi_point_list.second.size(),
38  "Different sizes for location and multiplicity data");
39 
40  for (unsigned int i = 0; i < npoint; ++i)
41  if (pointsFuzzyEqual(multi_point_list.first[i], p))
42  {
43  // a point at the same (within a tolerance) location as p exists, increase its multiplicity
44  multi_point_list.second[i]++;
45  return;
46  }
47 
48  // no prior point found at this location, add it with a multiplicity of one
49  multi_point_list.first.push_back(p);
50  multi_point_list.second.push_back(1);
51 }
52 
53 void
55 {
56  _elements.clear();
57  _points.clear();
58 }
59 
60 bool
61 DiracKernelInfo::hasPoint(const Elem * elem, Point p)
62 {
63  std::vector<Point> & point_list = _points[elem].first;
64 
65  for (const auto & pt : point_list)
66  if (pointsFuzzyEqual(pt, p))
67  return true;
68 
69  // If we haven't found it, we don't have it.
70  return false;
71 }
72 
73 void
75 {
76  // Note: we could update the PointLocator *every* time we call this
77  // function, but that may introduce an unacceptable overhead in
78  // problems which don't need a PointLocator at all. This issue will
79  // most likely become a moot point when we eventually add a shared
80  // "CachingPointLocator" to MOOSE.
81  // _point_locator = PointLocatorBase::build(TREE_LOCAL_ELEMENTS, mesh);
82 
83  // Construct the PointLocator object if *any* processors have Dirac
84  // points. Note: building a PointLocator object is a parallel_only()
85  // function, so this is an all-or-nothing thing.
86  unsigned pl_needs_rebuild = _elements.size();
87  mesh.comm().max(pl_needs_rebuild);
88 
89  if (pl_needs_rebuild)
90  {
91  // PointLocatorBase::build() is a parallel_only function! So we
92  // can't skip building it just becuase our local _elements is
93  // empty, it might be non-empty on some other processor!
94  _point_locator = PointLocatorBase::build(TREE_LOCAL_ELEMENTS, mesh);
95 
96  // We may be querying for points which are not in the semilocal
97  // part of a distributed mesh.
98  _point_locator->enable_out_of_mesh_mode();
99  }
100  else
101  {
102  // There are no elements with Dirac points, but we have been
103  // requested to update the PointLocator so we have to assume the
104  // old one is invalid. Therefore we reset it to NULL... however
105  // adding this line causes the code to hang because it triggers
106  // the PointLocator to be rebuilt in a non-parallel-only segment
107  // of the code later... so it's commented out for now even though
108  // it's probably the right behavior.
109  // _point_locator.reset(NULL);
110  }
111 }
112 
113 const Elem *
114 DiracKernelInfo::findPoint(Point p, const MooseMesh & mesh)
115 {
116  // If the PointLocator has never been created, do so now. NOTE - WE
117  // CAN'T DO THIS if findPoint() is only called on some processors,
118  // PointLocatorBase::build() is a 'parallel_only' method!
119  if (_point_locator.get() == NULL)
120  {
121  _point_locator = PointLocatorBase::build(TREE_LOCAL_ELEMENTS, mesh);
122  _point_locator->enable_out_of_mesh_mode();
123  }
124 
125  // Check that the PointLocator is ready to start locating points.
126  // So far I do not have any tests that trip this...
127  if (_point_locator->initialized() == false)
128  mooseError("Error, PointLocator is not initialized!");
129 
130  // Note: The PointLocator object returns NULL when the Point is not
131  // found within the Mesh. This is not considered to be an error as
132  // far as the DiracKernels are concerned: sometimes the Mesh moves
133  // out from the Dirac point entirely and in that case the Point just
134  // gets "deactivated".
135  const Elem * elem = (*_point_locator)(p);
136 
137  // The processors may not agree on which Elem the point is in. This
138  // can happen if a Dirac point lies on the processor boundary, and
139  // two or more neighboring processors think the point is in the Elem
140  // on *their* side.
141  dof_id_type elem_id = elem ? elem->id() : DofObject::invalid_id;
142 
143  // We are going to let the element with the smallest ID "win", all other
144  // procs will return NULL.
145  dof_id_type min_elem_id = elem_id;
146  mesh.comm().min(min_elem_id);
147 
148  return min_elem_id == elem_id ? elem : NULL;
149 }
150 
151 bool
152 DiracKernelInfo::pointsFuzzyEqual(const Point & a, const Point & b)
153 {
154  const Real dist_sq = (a - b).norm_sq();
155  return dist_sq < _point_equal_distance_sq;
156 }
std::set< const Elem * > _elements
The list of elements that need distributions.
void mooseError(Args &&...args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:182
MultiPointMap _points
The list of physical xyz Points that need to be evaluated in each element.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
const Elem * findPoint(Point p, const MooseMesh &mesh)
Used by client DiracKernel classes to determine the Elem in which the Point p resides.
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:74
void addPoint(const Elem *elem, Point p)
Adds a point source.
void clearPoints()
Remove all of the current points and elements.
bool hasPoint(const Elem *elem, Point p)
Return true if we have Point &#39;p&#39; in Element &#39;elem&#39;.
std::unique_ptr< PointLocatorBase > _point_locator
The DiracKernelInfo object manages a PointLocator object which is used by all DiracKernels to find Po...
const Real _point_equal_distance_sq
threshold distance squared below which two points are considered identical
void updatePointLocator(const MooseMesh &mesh)
Called during FEProblemBase::meshChanged() to update the PointLocator object used by the DiracKernels...
virtual ~DiracKernelInfo()
bool pointsFuzzyEqual(const Point &, const Point &)
Check if two points are equal with respect to a tolerance.