www.mooseframework.org
NearestPointBase.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 #pragma once
11 
12 // MOOSE includes
14 #include "Enumerate.h"
15 
16 // Forward Declarations
17 class UserObject;
18 
28 template <typename UserObjectType, typename BaseType>
31 {
32  InputParameters params = validParams<BaseType>();
33 
34  params.addParam<std::vector<Point>>("points",
35  "Computations will be lumped into values at these points.");
36  params.addParam<FileName>("points_file",
37  "A filename that should be looked in for points. Each "
38  "set of 3 values in that file will represent a Point. "
39  "This and 'points' cannot be both supplied.");
40 
41  // Add in the valid parameters
42  params += validParams<UserObjectType>();
43 
44  return params;
45 }
46 
54 template <typename UserObjectType, typename BaseType>
55 class NearestPointBase : public BaseType
56 {
57 public:
58  NearestPointBase(const InputParameters & parameters);
60 
61  virtual void initialize() override;
62  virtual void execute() override;
63  virtual void finalize() override;
64  virtual void threadJoin(const UserObject & y) override;
65 
73  virtual Real spatialValue(const Point & p) const override;
74 
75 protected:
80  void fillPoints();
81 
88  std::shared_ptr<UserObjectType> nearestUserObject(const Point & p) const;
89 
90  std::vector<Point> _points;
91  std::vector<std::shared_ptr<UserObjectType>> _user_objects;
92 
93  // The list of InputParameter objects. This is a list because these cannot be copied (or moved).
94  std::list<InputParameters> _sub_params;
95 
96  using BaseType::_communicator;
97  using BaseType::_current_elem;
98  using BaseType::isParamValid;
99  using BaseType::name;
100  using BaseType::processor_id;
101 };
102 
103 template <typename UserObjectType, typename BaseType>
105  : BaseType(parameters)
106 {
107  fillPoints();
108 
109  _user_objects.reserve(_points.size());
110 
111  // Build each of the UserObject objects:
112  for (MooseIndex(_points) i = 0; i < _points.size(); ++i)
113  {
114  auto sub_params = emptyInputParameters();
115  sub_params += parameters;
116  sub_params.set<std::string>("_object_name") = name() + "_sub" + std::to_string(i);
117 
118  _sub_params.push_back(sub_params);
119  _user_objects.emplace_back(std::make_shared<UserObjectType>(_sub_params.back()));
120  }
121 }
122 
123 template <typename UserObjectType, typename BaseType>
125 {
126 }
127 
128 template <typename UserObjectType, typename BaseType>
129 void
131 {
132  if (isParamValid("points") && isParamValid("points_file"))
133  mooseError(name(), ": Both 'points' and 'points_file' cannot be specified simultaneously.");
134 
135  if (isParamValid("points"))
136  {
137  _points = this->template getParam<std::vector<Point>>("points");
138  }
139  else if (isParamValid("points_file"))
140  {
141  const FileName & points_file = this->template getParam<FileName>("points_file");
142  std::vector<Real> points_vec;
143 
144  if (processor_id() == 0)
145  {
146  MooseUtils::checkFileReadable(points_file);
147 
148  std::ifstream is(points_file.c_str());
149  std::istream_iterator<Real> begin(is), end;
150  points_vec.insert(points_vec.begin(), begin, end);
151 
152  if (points_vec.size() % LIBMESH_DIM != 0)
153  mooseError(name(),
154  ": Number of entries in 'points_file' ",
155  points_file,
156  " must be divisible by ",
157  LIBMESH_DIM);
158  }
159 
160  // Broadcast the vector to all processors
161  std::size_t num_points = points_vec.size();
162  _communicator.broadcast(num_points);
163  points_vec.resize(num_points);
164  _communicator.broadcast(points_vec);
165 
166  for (std::size_t i = 0; i < points_vec.size(); i += LIBMESH_DIM)
167  {
168  Point point;
169  for (std::size_t j = 0; j < LIBMESH_DIM; j++)
170  point(j) = points_vec[i + j];
171 
172  _points.push_back(point);
173  }
174  }
175  else
176  mooseError(name(), ": You need to supply either 'points' or 'points_file' parameter.");
177 }
178 
179 template <typename UserObjectType, typename BaseType>
180 void
182 {
183  for (auto & user_object : _user_objects)
184  user_object->initialize();
185 }
186 
187 template <typename UserObjectType, typename BaseType>
188 void
190 {
191  nearestUserObject(_current_elem->centroid())->execute();
192 }
193 
194 template <typename UserObjectType, typename BaseType>
195 void
197 {
198  for (auto & user_object : _user_objects)
199  user_object->finalize();
200 }
201 
202 template <typename UserObjectType, typename BaseType>
203 void
205 {
206  auto & npla = static_cast<const NearestPointBase &>(y);
207 
208  for (MooseIndex(_user_objects) i = 0; i < _user_objects.size(); ++i)
209  _user_objects[i]->threadJoin(*npla._user_objects[i]);
210 }
211 
212 template <typename UserObjectType, typename BaseType>
213 Real
215 {
216  return nearestUserObject(p)->spatialValue(p);
217 }
218 
219 template <typename UserObjectType, typename BaseType>
220 std::shared_ptr<UserObjectType>
222 {
223  unsigned int closest = 0;
224  Real closest_distance = std::numeric_limits<Real>::max();
225 
226  for (auto it : Moose::enumerate(_points))
227  {
228  const auto & current_point = it.value();
229 
230  Real current_distance = (p - current_point).norm();
231 
232  if (current_distance < closest_distance)
233  {
234  closest_distance = current_distance;
235  closest = it.index();
236  }
237  }
238 
239  return _user_objects[closest];
240 }
241 
virtual void finalize() override
InputParameters nearestPointBaseValidParams()
Because this is a templated base class and template partial specializations are not allowed...
std::vector< std::shared_ptr< UserObjectType > > _user_objects
std::shared_ptr< UserObjectType > nearestUserObject(const Point &p) const
Get the UserObject that is closest to the point.
virtual Real spatialValue(const Point &p) const override
Given a Point return the integral value associated with the layer that point falls in for the layered...
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:207
This UserObject computes averages of a variable storing partial sums for the specified number of inte...
NearestPointBase(const InputParameters &parameters)
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
_enumerate_range< Iterator > enumerate(Iterator first, Iterator last, typename std::iterator_traits< Iterator >::difference_type initial)
Enumerate function for iterating over a range and obtaining both a reference to the underlying type a...
Definition: Enumerate.h:52
std::list< InputParameters > _sub_params
void fillPoints()
Fills in the _points variable from either &#39;points&#39; or &#39;points_file&#39; parameter.
InputParameters emptyInputParameters()
bool checkFileReadable(const std::string &filename, bool check_line_endings=false, bool throw_on_unreadable=true)
Checks to see if a file is readable (exists and permissions)
Definition: MooseUtils.C:146
virtual void threadJoin(const UserObject &y) override
virtual void execute() override
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
std::vector< Point > _points
virtual void initialize() override
Base class for user-specific data.
Definition: UserObject.h:37