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 #include "DelimitedFileReader.h"
16 #include "LayeredBase.h"
17 
18 // Forward Declarations
19 class UserObject;
20 
28 template <typename UserObjectType, typename BaseType>
29 class NearestPointBase : public BaseType
30 {
31 public:
33 
34  NearestPointBase(const InputParameters & parameters);
36 
37  virtual void initialize() override;
38  virtual void execute() override;
39  virtual void finalize() override;
40  virtual void threadJoin(const UserObject & y) override;
41 
49  virtual Real spatialValue(const Point & p) const override;
50 
55  virtual const std::vector<Point> & getPoints() const { return _points; }
56 
57  virtual const std::vector<Point> spatialPoints() const override;
58 
59 protected:
64  void fillPoints();
65 
72  UserObjectType & nearestUserObject(const Point & p) const;
73 
74  std::vector<Point> _points;
75  std::vector<std::unique_ptr<UserObjectType>> _user_objects;
76 
77  // To specify whether the distance is defined based on point or radius
78  const unsigned int _dist_norm;
79  // The axis around which the radius is determined
80  const unsigned int _axis;
81 
82  using BaseType::_communicator;
83  using BaseType::_current_elem;
84  using BaseType::isParamValid;
85  using BaseType::processor_id;
86  using MooseBase::name;
87 };
88 
89 template <typename UserObjectType, typename BaseType>
92 {
94 
95  params.addParam<std::vector<Point>>("points",
96  "Computations will be lumped into values at these points.");
97  params.addParam<FileName>("points_file",
98  "A filename that should be looked in for points. Each "
99  "set of 3 values in that file will represent a Point. "
100  "This and 'points' cannot be both supplied.");
101 
102  MooseEnum distnorm("point=0 radius=1", "point");
103  params.addParam<MooseEnum>(
104  "dist_norm", distnorm, "To specify whether the distance is defined based on point or radius");
105  MooseEnum axis("x=0 y=1 z=2", "z");
106  params.addParam<MooseEnum>("axis", axis, "The axis around which the radius is determined");
107 
108  params.addParamNamesToGroup("points points_file dist_norm axis", "Points and distance to points");
109 
110  // Add in the valid parameters
111  params += UserObjectType::validParams();
112 
113  return params;
114 }
115 
116 template <typename UserObjectType, typename BaseType>
118  : BaseType(parameters),
119  _dist_norm(this->template getParam<MooseEnum>("dist_norm")),
120  _axis(this->template getParam<MooseEnum>("axis"))
121 {
122  if (this->template getParam<MooseEnum>("dist_norm") != "radius" &&
123  parameters.isParamSetByUser("axis"))
124  this->template paramError("axis",
125  "'axis' should only be set if 'dist_norm' is set to 'radius'");
126 
127  fillPoints();
128 
129  _user_objects.resize(_points.size());
130 
131  // Build each of the UserObject objects that we will manage manually
132  // If you're looking at this in the future and want to replace this behavior,
133  // _please_ don't do it. MOOSE should manage these objects.
134  for (MooseIndex(_points) i = 0; i < _points.size(); ++i)
135  {
136  const auto uo_type = MooseUtils::prettyCppType<UserObjectType>();
137  auto sub_params = this->_app.getFactory().getValidParams(uo_type);
138  sub_params.applyParameters(parameters, {}, true);
139 
140  const auto sub_name = name() + "_sub" + std::to_string(i);
141  auto uo = this->_app.getFactory().template createUnique<UserObjectType>(
142  uo_type, sub_name, sub_params, this->_tid);
143  _user_objects[i] = std::move(uo);
144  }
145 }
146 
147 template <typename UserObjectType, typename BaseType>
149 {
150 }
151 
152 template <typename UserObjectType, typename BaseType>
153 void
155 {
156  if (isParamValid("points") && isParamValid("points_file"))
157  mooseError(name(), ": Both 'points' and 'points_file' cannot be specified simultaneously.");
158 
159  if (isParamValid("points"))
160  {
161  _points = this->template getParam<std::vector<Point>>("points");
162  }
163  else if (isParamValid("points_file"))
164  {
165  const FileName & points_file = this->template getParam<FileName>("points_file");
166 
167  MooseUtils::DelimitedFileReader file(points_file, &_communicator);
169  file.read();
170  _points = file.getDataAsPoints();
171  }
172  else
173  mooseError(name(), ": You need to supply either 'points' or 'points_file' parameter.");
174 }
175 
176 template <typename UserObjectType, typename BaseType>
177 void
179 {
180  for (auto & user_object : _user_objects)
181  user_object->initialize();
182 }
183 
184 template <typename UserObjectType, typename BaseType>
185 void
187 {
188  nearestUserObject(_current_elem->vertex_average()).execute();
189 }
190 
191 template <typename UserObjectType, typename BaseType>
192 void
194 {
195  for (auto & user_object : _user_objects)
196  user_object->finalize();
197 }
198 
199 template <typename UserObjectType, typename BaseType>
200 void
202 {
203  auto & npla = static_cast<const NearestPointBase &>(y);
204 
205  for (MooseIndex(_user_objects) i = 0; i < _user_objects.size(); ++i)
206  _user_objects[i]->threadJoin(*npla._user_objects[i]);
207 }
208 
209 template <typename UserObjectType, typename BaseType>
210 Real
212 {
213  return nearestUserObject(p).spatialValue(p);
214 }
215 
216 template <typename UserObjectType, typename BaseType>
217 UserObjectType &
219 {
220  unsigned int closest = 0;
221  Real closest_distance = std::numeric_limits<Real>::max();
222 
223  for (auto it : Moose::enumerate(_points))
224  {
225  const auto & current_point = it.value();
226 
227  Real current_distance;
228  if (_dist_norm == 0)
229  // the distance is computed using standard norm
230  current_distance = (p - current_point).norm();
231  else
232  {
233  // the distance is to be computed based on radii
234  // in that case, we need to determine the 2 coordinate indices
235  // that define the radius
236  unsigned int i = 0;
237  unsigned int j = 1;
238 
239  if (_axis == 0)
240  i = 2;
241  else if (_axis == 1)
242  j = 2;
243 
244  current_distance = std::abs(
245  std::sqrt(p(i) * p(i) + p(j) * p(j)) -
246  std::sqrt(current_point(i) * current_point(i) + current_point(j) * current_point(j)));
247  }
248 
249  if (current_distance < closest_distance)
250  {
251  closest_distance = current_distance;
252  closest = it.index();
253  }
254  }
255 
256  return *_user_objects[closest];
257 }
258 
259 template <typename UserObjectType, typename BaseType>
260 const std::vector<Point>
262 {
263  std::vector<Point> points;
264 
265  for (MooseIndex(_points) i = 0; i < _points.size(); ++i)
266  {
267  auto layered_base = dynamic_cast<LayeredBase *>(_user_objects[i].get());
268  if (layered_base)
269  {
270  const auto & layers = layered_base->getLayerCenters();
271  auto direction = layered_base->direction();
272 
273  for (const auto & l : layers)
274  {
275  Point pt = _points[i];
276  pt(direction) = l;
277  points.push_back(pt);
278  }
279  }
280  }
281 
282  return points;
283 }
std::string name(const ElemQuality q)
virtual void finalize() override
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:284
This UserObject computes averages of a variable storing partial sums for the specified number of inte...
Utility class for reading delimited data (e.g., CSV data).
NearestPointBase(const InputParameters &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
virtual const std::vector< Point > spatialPoints() const override
std::vector< std::unique_ptr< UserObjectType > > _user_objects
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
static InputParameters validParams()
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
InputParameters validParams()
void fillPoints()
Fills in the _points variable from either &#39;points&#39; or &#39;points_file&#39; parameter.
virtual const std::vector< Point > & getPoints() const
Get the points at which the nearest operation is performed.
auto max(const L &left, const R &right)
const unsigned int _axis
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
UserObjectType & nearestUserObject(const Point &p) const
Get the UserObject that is closest to the point.
virtual void threadJoin(const UserObject &y) override
virtual void execute() override
const std::vector< Real > & getLayerCenters() const
Get the center coordinates for the layers (along given direction)
Definition: LayeredBase.h:67
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
auto norm(const T &a) -> decltype(std::abs(a))
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was by the user.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
This base class computes volume integrals of a variable storing partial sums for the specified number...
Definition: LayeredBase.h:36
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...
const unsigned int _dist_norm
std::vector< Point > _points
virtual void initialize() override
Base class for user-specific data.
Definition: UserObject.h:39
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...