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
22using namespace libMesh;
23
25 : _point_locator(), _point_equal_distance_sq(libMesh::TOLERANCE * libMesh::TOLERANCE)
26{
27}
28
30
31void
32DiracKernelInfo::addPoint(const Elem * elem, const Point & p, const Real & value)
33{
34 _elements.insert(elem);
35
36 std::pair<std::vector<Point>, std::vector<Real>> & multi_point_list = _points[elem];
37
38 const unsigned int npoint = multi_point_list.first.size();
39 mooseAssert(npoint == multi_point_list.second.size(),
40 "Different sizes for location and point value data");
41
42 for (unsigned int i = 0; i < npoint; ++i)
43 if (pointsFuzzyEqual(multi_point_list.first[i], p))
44 {
45 // A point at the same (within a tolerance) location as p exists, accumulate its value.
46 multi_point_list.second[i] += value;
47 return;
48 }
49
50 // No prior point found at this location, add it with its initial value.
51 multi_point_list.first.push_back(p);
52 multi_point_list.second.push_back(value);
53}
54
55void
57{
58 _elements.clear();
59 _points.clear();
60}
61
62bool
63DiracKernelInfo::hasPoint(const Elem * elem, const Point & p)
64{
65 std::vector<Point> & point_list = _points[elem].first;
66
67 for (const auto & pt : point_list)
68 if (pointsFuzzyEqual(pt, p))
69 return true;
70
71 // If we haven't found it, we don't have it.
72 return false;
73}
74
75void
77{
78 // Note: we could update the PointLocator *every* time we call this
79 // function, but that may introduce an unacceptable overhead in
80 // problems which don't need a PointLocator at all. This issue will
81 // most likely become a moot point when we eventually add a shared
82 // "CachingPointLocator" to MOOSE.
83 // _point_locator = PointLocatorBase::build(TREE_LOCAL_ELEMENTS, mesh);
84
85 // Construct the PointLocator object if *any* processors have Dirac
86 // points. Note: building a PointLocator object is a parallel_only()
87 // function, so this is an all-or-nothing thing.
88 unsigned pl_needs_rebuild = _elements.size();
89 mesh.comm().max(pl_needs_rebuild);
90
91 if (pl_needs_rebuild)
92 {
93 // PointLocatorBase::build() is a parallel_only function! So we
94 // can't skip building it just becuase our local _elements is
95 // empty, it might be non-empty on some other processor!
97
98 // We may be querying for points which are not in the semilocal
99 // part of a distributed mesh.
100 _point_locator->enable_out_of_mesh_mode();
101 }
102 else
103 {
104 // There are no elements with Dirac points, but we have been
105 // requested to update the PointLocator so we have to assume the
106 // old one is invalid. Therefore we reset it to NULL... however
107 // adding this line causes the code to hang because it triggers
108 // the PointLocator to be rebuilt in a non-parallel-only segment
109 // of the code later... so it's commented out for now even though
110 // it's probably the right behavior.
111 // _point_locator.reset(NULL);
112 }
113}
114
115const Elem *
117 const MooseMesh & mesh,
118 const std::set<SubdomainID> & blocks,
119 const PointNotFoundBehavior point_not_found_behavior,
120 const MooseBase & consumer)
121{
122 // If the PointLocator has never been created, do so now. NOTE - WE
123 // CAN'T DO THIS if findPoint() is only called on some processors,
124 // PointLocatorBase::build() is a 'parallel_only' method!
125 if (_point_locator.get() == NULL)
126 {
128 _point_locator->enable_out_of_mesh_mode();
129 }
130
131 // Check that the PointLocator is ready to start locating points.
132 // So far I do not have any tests that trip this...
133 if (_point_locator->initialized() == false)
134 consumer.mooseError("PointLocator is not initialized!");
135
136 // Note: The PointLocator object returns NULL when the Point is not
137 // found within the Mesh. This is not considered to be an error as
138 // far as the DiracKernels are concerned: sometimes the Mesh moves
139 // out from the Dirac point entirely and in that case the Point just
140 // gets "deactivated".
141 const Elem * elem = (*_point_locator)(p, &blocks);
142
143 // The processors may not agree on which Elem the point is in. This
144 // can happen if a Dirac point lies on the processor boundary, and
145 // two or more neighboring processors think the point is in the Elem
146 // on *their* side.
147 dof_id_type elem_id = elem ? elem->id() : DofObject::invalid_id;
148
149 // We are going to let the element with the smallest ID "win", all other
150 // procs will return NULL.
151 dof_id_type min_elem_id = elem_id;
152 mesh.comm().min(min_elem_id);
153
154 if (min_elem_id == DofObject::invalid_id)
155 {
156 std::stringstream msg;
157 msg << "Point " << p << " not found in block(s) " << Moose::stringify(blocks, ", ") << ".\n";
158 switch (point_not_found_behavior)
159 {
160 case PointNotFoundBehavior::ERROR:
161 consumer.mooseError(msg.str());
162 break;
163 case PointNotFoundBehavior::WARNING:
164 mooseDoOnce(consumer.mooseWarning(msg.str() + "This message will not be repeated."));
165 break;
166 case PointNotFoundBehavior::IGNORE:
167 break;
168 default:
169 consumer.mooseError("Internal enum error.");
170 }
171 }
172
173 // But we notably need the processor which owns elem_id to return it!
174 if (min_elem_id != DofObject::invalid_id)
175 if (const auto min_elem = mesh.queryElemPtr(min_elem_id);
176 min_elem && min_elem->processor_id() == mesh.processor_id())
177 return min_elem;
178 return nullptr;
179}
180
181bool
183{
184 const Real dist_sq = (a - b).norm_sq();
185 return dist_sq < _point_equal_distance_sq;
186}
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
void max(const T &r, T &o, Request &req) const
void min(const T &r, T &o, Request &req) const
static constexpr dof_id_type invalid_id
dof_id_type id() const
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
static std::unique_ptr< PointLocatorBase > build(PointLocatorType t, const MeshBase &mesh, const PointLocatorBase *master=nullptr)
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...
static constexpr Real TOLERANCE
uint8_t dof_id_type
TREE_LOCAL_ELEMENTS
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real