14 #include "libmesh/nanoflann.hpp" 15 #include "libmesh/parallel_algebra.h" 16 #include "libmesh/mesh_tools.h" 17 #include "libmesh/int_range.h" 24 #if NANOFLANN_VERSION < 0x150 29 template <
typename T,
typename U>
50 "Name of the material property to average");
51 MooseEnum weights_type(
"constant linear cosine",
"linear");
58 "Padding for communication. This gets added to the radius when determining which QPs to send " 59 "to other processors. Increase this gradually if inconsistent parallel results occur.");
75 _prop(getMaterialProperty<
Real>(
"prop_name")),
76 _radius(getParam<
Real>(
"radius")),
77 _padding(getParam<
Real>(
"padding")),
78 _update_communication_lists(false),
79 _my_pid(processor_id()),
80 _perf_meshchanged(registerTimedSection(
"meshChanged", 3)),
81 _perf_updatelists(registerTimedSection(
"updateCommunicationLists", 3)),
82 _perf_finalize(registerTimedSection(
"finalize", 2))
111 _average.insert(std::make_pair(
id, std::vector<Real>(
_qrule->n_points())));
113 i->second.resize(
_qrule->n_points());
122 unsigned int local_size =
_qp_data.size();
141 std::vector<QPData> receive;
152 send[i].reserve(list.size());
153 for (
const auto & item : list)
169 const auto source_pid = TIMPI::cast_int<processor_id_type>(
status.source());
170 const auto message_size =
status.size(item_type);
173 receive.resize(message_size);
182 Parallel::wait(send_requests);
186 const unsigned int max_leaf_size = 20;
188 _kd_tree = std::make_unique<KDTreeType>(
189 LIBMESH_DIM, point_list, nanoflann::KDTreeSingleIndexAdaptorParams(max_leaf_size));
191 mooseAssert(
_kd_tree !=
nullptr,
"KDTree was not properly initialized.");
198 auto local_range_begin =
_qp_data.begin();
199 auto local_range_end = local_range_begin;
200 std::advance(local_range_end, local_size);
201 Threads::parallel_reduce(
QPDataRange(local_range_begin, local_range_end), rgcl);
209 _average.insert(uo._average.begin(), uo._average.end());
230 const auto end =
mesh.active_local_elements_end();
231 for (
auto it =
mesh.active_local_elements_begin(); it != end; ++it)
233 for (
const auto s :
make_range((*it)->n_sides()))
235 const auto * neighbor = (*it)->neighbor_ptr(s);
236 if (neighbor && neighbor->processor_id() !=
_my_pid)
238 for (
const auto n :
make_range((*it)->n_nodes()))
239 if ((*it)->is_node_on_side(n, s))
257 const unsigned int max_leaf_size = 20;
259 auto kd_tree = std::make_unique<KDTreeType>(
260 LIBMESH_DIM, point_list, nanoflann::KDTreeSingleIndexAdaptorParams(max_leaf_size));
261 mooseAssert(kd_tree !=
nullptr,
"KDTree was not properly initialized.");
262 kd_tree->buildIndex();
264 std::vector<nanoflann::ResultItem<std::size_t, Real>> ret_matches;
272 kd_tree->radiusSearch(
274 for (
auto & match : ret_matches)
279 std::vector<std::pair<Point, Point>> pps(
n_processors());
281 std::pair<Point, Point> mypp = mybb;
285 const auto rpoint = Point(1, 1, 1) *
_radius;
286 std::vector<BoundingBox> bbs;
287 for (
const auto & pp : pps)
288 bbs.emplace_back(pp.first - rpoint, pp.second + rpoint);
293 if (pid !=
_my_pid && bbs[pid].intersects(mypp))
316 #ifdef LIBMESH_HAVE_MPI 326 MPI_Datatype types[] = {
328 int blocklengths[] = {1, 1, 1, 1, 1};
329 MPI_Aint displs[5], start;
331 libmesh_call_mpi(MPI_Get_address(const_cast<RadialAverage::QPData *>(example), &start));
332 libmesh_call_mpi(MPI_Get_address(const_cast<Point *>(&example->
_q_point), &displs[0]));
333 libmesh_call_mpi(MPI_Get_address(const_cast<dof_id_type *>(&example->
_elem_id), &displs[1]));
334 libmesh_call_mpi(MPI_Get_address(const_cast<short *>(&example->
_qp), &displs[2]));
335 libmesh_call_mpi(MPI_Get_address(const_cast<Real *>(&example->
_volume), &displs[3]));
336 libmesh_call_mpi(MPI_Get_address(const_cast<Real *>(&example->
_value), &displs[4]));
338 for (std::size_t i = 0; i < 5; ++i)
342 MPI_Datatype tmptype;
343 libmesh_call_mpi(MPI_Type_create_struct(5, blocklengths, displs, types, &tmptype));
344 libmesh_call_mpi(MPI_Type_commit(&tmptype));
348 libmesh_call_mpi(MPI_Type_free(&tmptype));
352 #endif // LIBMESH_HAVE_MPI 358 #ifdef LIBMESH_HAVE_MPI 359 libmesh_call_mpi(MPI_Type_dup(t.
_datatype, &_datatype));
const Real _radius
cut-off radius
virtual void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job...
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
Real _volume
current value * _JxW
std::set< Point > _boundary_nodes
set of nodes on the boundary of the current processor domain
std::vector< std::set< std::size_t > > _communication_lists
QPData indices to send to the various processors.
A MultiMooseEnum object to hold "execute_on" flags.
const MaterialProperty< Real > & _prop
material to be averaged
const MooseArray< Point > & _q_point
const MooseArray< Real > & _coord
std::unique_ptr< KDTreeType > _kd_tree
spatial index (nanoflann guarantees this to be threadsafe under read-only operations) ...
virtual void finalize() override
Finalize.
static InputParameters validParams()
virtual void execute() override
Execute method.
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
virtual void threadJoin(const UserObject &y) override
Must override.
registerMooseObject("MooseApp", RadialAverage)
const Point & getPoint(const PointObject &item) const
get a Point reference from the PointData object at index idx in the list
WeightsType
distance based weight function
Real _value
variable value
std::set< std::size_t > _boundary_data_indices
set of all _qp_data indices that are within _radius of any _boundary_nodes
processor_id_type _my_pid
StoredRange< std::vector< RadialAverage::QPData >::const_iterator, RadialAverage::QPData > QPDataRange
const Parallel::Communicator & _communicator
void updateCommunicationLists()
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
const Real _padding
communication padding distance
StandardType(const T *example=nullptr)
std::vector< std::vector< const Elem * > > _nodes_to_elem_map
The data structure used to find neighboring elements give a node ID.
static InputParameters validParams()
short _qp
index of the quadrature point
virtual void meshChanged() override
Called on this object when the mesh changes.
RadialAverage(const InputParameters ¶meters)
processor_id_type n_processors() const
void libmesh_ignore(const Args &...)
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
std::vector< QPData > _qp_data
gathered data
const ExecFlagType EXEC_TIMESTEP_BEGIN
status probe(const unsigned int src_processor_id, const MessageTag &tag=any_tag) const
bool _update_communication_lists
RadialAverage threaded loop.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
MooseApp & _app
The MOOSE application this is associated with.
Point _q_point
physical coordinates of the quadrature point
std::pair< T, U > ResultItem
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
const QBase *const & _qrule
const Elem *const & _current_elem
The current element pointer (available during execute())
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
const MooseArray< Real > & _JxW
Result _average
average result
dof_id_type _elem_id
element id
IntRange< T > make_range(T beg, T end)
libMesh::BoundingBox getInflatedProcessorBoundingBox(Real inflation_multiplier=0.01) const
Get a (slightly inflated) processor bounding box.
Gather and communicate a full list of all quadrature points and the values of a selected material pro...
SearchParams SearchParameters
auto index_range(const T &sizable)
Base class for user-specific data.
std::vector< processor_id_type > _candidate_procs
processors to send (potentially empty) data to
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template pow< 2 >(tan(_arg))+1.0) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(sqrt