https://mooseframework.inl.gov
NearestPointBase.h
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 #pragma once
11 
12 // MOOSE includes
14 #include "Enumerate.h"
15 #include "DelimitedFileReader.h"
16 #include "LayeredBase.h"
17 #include "FEProblemBase.h"
18 #include "Positions.h"
19 
20 // Forward Declarations
21 class UserObject;
22 
30 template <typename UserObjectType, typename BaseType>
32 {
33 public:
35 
36  NearestPointBase(const InputParameters & parameters);
38 
39  virtual void initialize() override;
40  virtual void execute() override;
41  virtual void finalize() override;
42  virtual void threadJoin(const UserObject & y) override;
43 
51  virtual Real spatialValue(const Point & p) const override;
52 
57  virtual const std::vector<Point> & getPoints() const { return _points; }
58 
59  virtual const std::vector<Point> spatialPoints() const override;
60 
61 protected:
66  void fillPoints();
67 
74  UserObjectType & nearestUserObject(const Point & p) const;
75 
76  std::vector<Point> _points;
77  std::vector<std::unique_ptr<UserObjectType>> _user_objects;
78 
79  // To specify whether the distance is defined based on point or radius
80  const unsigned int _dist_norm;
81  // The axis around which the radius is determined
82  const unsigned int _axis;
83 
84  using BaseType::_communicator;
85  using BaseType::_current_elem;
86  using BaseType::isParamValid;
87  using BaseType::processor_id;
88  using MooseBase::name;
89 };
90 
91 template <typename UserObjectType, typename BaseType>
94 {
96 
97  params.addParam<std::vector<Point>>("points",
98  "Computations will be lumped into values at these points.");
99  params.addParam<FileName>("points_file",
100  "A filename that should be looked in for points. Each "
101  "set of 3 values in that file will represent a Point. "
102  "This and 'points' cannot be both supplied.");
103  params.addParam<PositionsName>(
104  "positions_object",
105  "The name of a Positions object that will contain "
106  "the locations. This, 'points' and 'points(_file)' cannot be both supplied. "
107  "Note that only the vector of initial Positions are used at this time. "
108  "Updates to the 'positions' vector are not supported.");
109 
110  MooseEnum distnorm("point=0 radius=1", "point");
111  params.addParam<MooseEnum>(
112  "dist_norm", distnorm, "To specify whether the distance is defined based on point or radius");
113  MooseEnum axis("x=0 y=1 z=2", "z");
114  params.addParam<MooseEnum>("axis", axis, "The axis around which the radius is determined");
115 
116  params.addParamNamesToGroup("points points_file dist_norm axis", "Points and distance to points");
117 
118  // Add in the valid parameters
119  params += UserObjectType::validParams();
120 
121  return params;
122 }
123 
124 template <typename UserObjectType, typename BaseType>
126  : SpatialUserObjectFunctor<BaseType>(parameters),
127  _dist_norm(this->template getParam<MooseEnum>("dist_norm")),
128  _axis(this->template getParam<MooseEnum>("axis"))
129 {
130  if (this->template getParam<MooseEnum>("dist_norm") != "radius" &&
131  parameters.isParamSetByUser("axis"))
132  this->paramError("axis", "'axis' should only be set if 'dist_norm' is set to 'radius'");
133 
134  fillPoints();
135 
136  _user_objects.resize(_points.size());
137 
138  // Build each of the UserObject objects that we will manage manually
139  // If you're looking at this in the future and want to replace this behavior,
140  // _please_ don't do it. MOOSE should manage these objects.
141  for (MooseIndex(_points) i = 0; i < _points.size(); ++i)
142  {
143  const auto uo_type = MooseUtils::prettyCppType<UserObjectType>();
144  auto sub_params = this->_app.getFactory().getValidParams(uo_type);
145  sub_params.applyParameters(parameters, {}, true);
146 
147  const auto sub_name = name() + "_sub" + std::to_string(i);
148  auto uo = this->_app.getFactory().template createUnique<UserObjectType>(
149  uo_type, sub_name, sub_params, this->_tid);
150  _user_objects[i] = std::move(uo);
151  }
152 }
153 
154 template <typename UserObjectType, typename BaseType>
156 {
157 }
158 
159 template <typename UserObjectType, typename BaseType>
160 void
162 {
163  if (isParamValid("points"))
164  {
165  _points = this->template getParam<std::vector<Point>>("points");
166  if (isParamValid("points_file"))
167  this->paramError("points_file", "Cannot be specified together with 'points'");
168  if (isParamValid("positions_object"))
169  this->paramError("positions_object", "Cannot be specified together with 'points'");
170  }
171  else if (isParamValid("points_file"))
172  {
173  const FileName & points_file = this->template getParam<FileName>("points_file");
174 
175  MooseUtils::DelimitedFileReader file(points_file, &_communicator);
177  file.read();
178  _points = file.getDataAsPoints();
179 
180  if (isParamValid("positions_object"))
181  this->paramError("positions_object", "Cannot be specified together with 'points_file'");
182  }
183  else if (isParamValid("positions_object"))
184  {
185  const auto & positions_name = this->template getParam<PositionsName>("positions_object");
186  const auto problem = this->template getCheckedPointerParam<FEProblemBase *>("_fe_problem_base");
187  _points = problem->getPositionsObject(positions_name).getPositions(/*initial_positions*/ true);
188  }
189  else
190  mooseError(
191  name(),
192  ": You need to supply either 'points', 'points_file' or 'positions_object' parameter.");
193 }
194 
195 template <typename UserObjectType, typename BaseType>
196 void
198 {
199  for (auto & user_object : _user_objects)
200  user_object->initialize();
201 }
202 
203 template <typename UserObjectType, typename BaseType>
204 void
206 {
207  nearestUserObject(_current_elem->vertex_average()).execute();
208 }
209 
210 template <typename UserObjectType, typename BaseType>
211 void
213 {
214  for (auto & user_object : _user_objects)
215  user_object->finalize();
216 }
217 
218 template <typename UserObjectType, typename BaseType>
219 void
221 {
222  auto & npla = static_cast<const NearestPointBase &>(y);
223 
224  for (MooseIndex(_user_objects) i = 0; i < _user_objects.size(); ++i)
225  _user_objects[i]->threadJoin(*npla._user_objects[i]);
226 }
227 
228 template <typename UserObjectType, typename BaseType>
229 Real
231 {
232  return nearestUserObject(p).spatialValue(p);
233 }
234 
235 template <typename UserObjectType, typename BaseType>
236 UserObjectType &
238 {
239  unsigned int closest = 0;
240  Real closest_distance = std::numeric_limits<Real>::max();
241 
242  for (auto it : Moose::enumerate(_points))
243  {
244  const auto & current_point = it.value();
245 
246  Real current_distance;
247  if (_dist_norm == 0)
248  // the distance is computed using standard norm
249  current_distance = (p - current_point).norm();
250  else
251  {
252  // the distance is to be computed based on radii
253  // in that case, we need to determine the 2 coordinate indices
254  // that define the radius
255  unsigned int i = 0;
256  unsigned int j = 1;
257 
258  if (_axis == 0)
259  i = 2;
260  else if (_axis == 1)
261  j = 2;
262 
263  current_distance = std::abs(
264  std::sqrt(p(i) * p(i) + p(j) * p(j)) -
265  std::sqrt(current_point(i) * current_point(i) + current_point(j) * current_point(j)));
266  }
267 
268  if (current_distance < closest_distance)
269  {
270  closest_distance = current_distance;
271  closest = it.index();
272  }
273  }
274 
275  return *_user_objects[closest];
276 }
277 
278 template <typename UserObjectType, typename BaseType>
279 const std::vector<Point>
281 {
282  std::vector<Point> points;
283 
284  for (MooseIndex(_points) i = 0; i < _points.size(); ++i)
285  {
286  auto layered_base = dynamic_cast<LayeredBase *>(_user_objects[i].get());
287  if (layered_base)
288  {
289  const auto & layers = layered_base->getLayerCenters();
290  auto direction = layered_base->direction();
291 
292  for (const auto & l : layers)
293  {
294  Point pt = _points[i];
295  pt(direction) = l;
296  points.push_back(pt);
297  }
298  }
299  }
300 
301  return points;
302 }
std::string name(const ElemQuality q)
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:42
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:333
This UserObject computes averages of a variable storing partial sums for the specified number of inte...
NearestPointBase(const InputParameters &parameters)
static InputParameters validParams()
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
static InputParameters validParams()
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
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:99
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:33
auto norm(const T &a) -> decltype(std::abs(a))
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was set by the user.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Utility class for reading delimited data (e.g., CSV data).
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
This base class computes volume integrals of a variable storing partial sums for the specified number...
Definition: LayeredBase.h:36
Base class for creating a user object with the SpatialUserObject and Moose::Functor APIs...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional 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:40
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...