https://mooseframework.inl.gov
Loading...
Searching...
No Matches
DiracKernelInfo.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 "DiracKernelInfo.h"
11#include "MooseMesh.h"
12#include "MooseEnum.h"
13#include "DiracKernelBase.h"
14#include "MooseBase.h"
15
16// LibMesh
17#include "libmesh/point_locator_base.h"
18#include "libmesh/elem.h"
19#include "libmesh/enum_point_locator_type.h"
20#include "libmesh/point.h"
21
23 : _point_locator(), _point_equal_distance_sq(libMesh::TOLERANCE * libMesh::TOLERANCE)
24{
25}
26
28
29void
30DiracKernelInfo::addPoint(const Elem * elem, const Point & p, const Real & value)
31{
32 _elements.insert(elem);
33
34 std::pair<std::vector<Point>, std::vector<Real>> & 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 point value 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, accumulate its value.
44 multi_point_list.second[i] += value;
45 return;
46 }
47
48 // No prior point found at this location, add it with its initial value.
49 multi_point_list.first.push_back(p);
50 multi_point_list.second.push_back(value);
51}
52
53void
55{
56 _elements.clear();
57 _points.clear();
58}
59
60bool
61DiracKernelInfo::hasPoint(const Elem * elem, const 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
73void
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
113const Elem *
115 const MooseMesh & mesh,
116 const std::set<SubdomainID> & blocks,
117 const PointNotFoundBehavior point_not_found_behavior,
118 const MooseBase & consumer)
119{
120 // If the PointLocator has never been created, do so now. NOTE - WE
121 // CAN'T DO THIS if findPoint() is only called on some processors,
122 // PointLocatorBase::build() is a 'parallel_only' method!
123 if (_point_locator.get() == NULL)
124 {
125 _point_locator = PointLocatorBase::build(TREE_LOCAL_ELEMENTS, mesh);
126 _point_locator->enable_out_of_mesh_mode();
127 }
128
129 // Check that the PointLocator is ready to start locating points.
130 // So far I do not have any tests that trip this...
131 if (_point_locator->initialized() == false)
132 consumer.mooseError("PointLocator is not initialized!");
133
134 // Note: The PointLocator object returns NULL when the Point is not
135 // found within the Mesh. This is not considered to be an error as
136 // far as the DiracKernels are concerned: sometimes the Mesh moves
137 // out from the Dirac point entirely and in that case the Point just
138 // gets "deactivated".
139 const Elem * elem = (*_point_locator)(p, &blocks);
140
141 // The processors may not agree on which Elem the point is in. This
142 // can happen if a Dirac point lies on the processor boundary, and
143 // two or more neighboring processors think the point is in the Elem
144 // on *their* side.
145 dof_id_type elem_id = elem ? elem->id() : DofObject::invalid_id;
146
147 // We are going to let the element with the smallest ID "win", all other
148 // procs will return NULL.
149 dof_id_type min_elem_id = elem_id;
150 mesh.comm().min(min_elem_id);
151
152 if (min_elem_id == DofObject::invalid_id)
153 {
154 std::stringstream msg;
155 msg << "Point " << p << " not found in block(s) " << Moose::stringify(blocks, ", ") << ".\n";
156 switch (point_not_found_behavior)
157 {
158 case PointNotFoundBehavior::ERROR:
159 consumer.mooseError(msg.str());
160 break;
161 case PointNotFoundBehavior::WARNING:
162 mooseDoOnce(consumer.mooseWarning(msg.str() + "This message will not be repeated."));
163 break;
164 case PointNotFoundBehavior::IGNORE:
165 break;
166 default:
167 consumer.mooseError("Internal enum error.");
168 }
169 }
170
171 // But we notably need the processor which owns elem_id to return it!
172 if (min_elem_id != DofObject::invalid_id)
173 if (const auto min_elem = mesh.queryElemPtr(min_elem_id);
174 min_elem && min_elem->processor_id() == mesh.processor_id())
175 return min_elem;
176 return nullptr;
177}
178
179bool
180DiracKernelInfo::pointsFuzzyEqual(const Point & a, const Point & b)
181{
182 const Real dist_sq = (a - b).norm_sq();
183 return dist_sq < _point_equal_distance_sq;
184}
char ** blocks
bool hasPoint(const Elem *elem, const Point &p)
Return true if we have Point 'p' in Element 'elem'.
const Real _point_equal_distance_sq
threshold distance squared below which two points are considered identical
MultiPointMap _points
The list of physical xyz Points that need to be evaluated in each element.
virtual ~DiracKernelInfo()
void clearPoints()
Remove all of the current points and elements.
std::unique_ptr< libMesh::PointLocatorBase > _point_locator
The DiracKernelInfo object manages a PointLocator object which is used by all DiracKernels to find Po...
void addPoint(const Elem *elem, const Point &p, const Real &value=1)
Adds a point source.
const Elem * findPoint(const Point &p, const MooseMesh &mesh, const std::set< SubdomainID > &blocks, const PointNotFoundBehavior point_not_found_behavior, const MooseBase &consumer)
Used by client DiracKernel classes to determine the Elem in which the Point p resides.
std::set< const Elem * > _elements
The list of elements that need distributions.
void updatePointLocator(const MooseMesh &mesh)
Called during FEProblemBase::meshChanged() to update the PointLocator object used by the DiracKernels...
bool pointsFuzzyEqual(const Point &, const Point &)
Check if two points are equal with respect to a tolerance.
Base class for everything in MOOSE with a name and a type.
Definition MooseBase.h:50
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition MooseBase.h:271
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
Definition MooseBase.h:299
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition MooseMesh.h:95
MeshBase & mesh
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:64
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...