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 
18 // Forward Declarations
19 class UserObject;
20 
28 template <typename UserObjectType, typename 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  : SpatialUserObjectFunctor<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->paramError("axis", "'axis' should only be set if 'dist_norm' is set to 'radius'");
125 
126  fillPoints();
127 
128  _user_objects.resize(_points.size());
129 
130  // Build each of the UserObject objects that we will manage manually
131  // If you're looking at this in the future and want to replace this behavior,
132  // _please_ don't do it. MOOSE should manage these objects.
133  for (MooseIndex(_points) i = 0; i < _points.size(); ++i)
134  {
135  const auto uo_type = MooseUtils::prettyCppType<UserObjectType>();
136  auto sub_params = this->_app.getFactory().getValidParams(uo_type);
137  sub_params.applyParameters(parameters, {}, true);
138 
139  const auto sub_name = name() + "_sub" + std::to_string(i);
140  auto uo = this->_app.getFactory().template createUnique<UserObjectType>(
141  uo_type, sub_name, sub_params, this->_tid);
142  _user_objects[i] = std::move(uo);
143  }
144 }
145 
146 template <typename UserObjectType, typename BaseType>
148 {
149 }
150 
151 template <typename UserObjectType, typename BaseType>
152 void
154 {
155  if (isParamValid("points") && isParamValid("points_file"))
156  mooseError(name(), ": Both 'points' and 'points_file' cannot be specified simultaneously.");
157 
158  if (isParamValid("points"))
159  {
160  _points = this->template getParam<std::vector<Point>>("points");
161  }
162  else if (isParamValid("points_file"))
163  {
164  const FileName & points_file = this->template getParam<FileName>("points_file");
165 
166  MooseUtils::DelimitedFileReader file(points_file, &_communicator);
168  file.read();
169  _points = file.getDataAsPoints();
170  }
171  else
172  mooseError(name(), ": You need to supply either 'points' or 'points_file' parameter.");
173 }
174 
175 template <typename UserObjectType, typename BaseType>
176 void
178 {
179  for (auto & user_object : _user_objects)
180  user_object->initialize();
181 }
182 
183 template <typename UserObjectType, typename BaseType>
184 void
186 {
187  nearestUserObject(_current_elem->vertex_average()).execute();
188 }
189 
190 template <typename UserObjectType, typename BaseType>
191 void
193 {
194  for (auto & user_object : _user_objects)
195  user_object->finalize();
196 }
197 
198 template <typename UserObjectType, typename BaseType>
199 void
201 {
202  auto & npla = static_cast<const NearestPointBase &>(y);
203 
204  for (MooseIndex(_user_objects) i = 0; i < _user_objects.size(); ++i)
205  _user_objects[i]->threadJoin(*npla._user_objects[i]);
206 }
207 
208 template <typename UserObjectType, typename BaseType>
209 Real
211 {
212  return nearestUserObject(p).spatialValue(p);
213 }
214 
215 template <typename UserObjectType, typename BaseType>
216 UserObjectType &
218 {
219  unsigned int closest = 0;
220  Real closest_distance = std::numeric_limits<Real>::max();
221 
222  for (auto it : Moose::enumerate(_points))
223  {
224  const auto & current_point = it.value();
225 
226  Real current_distance;
227  if (_dist_norm == 0)
228  // the distance is computed using standard norm
229  current_distance = (p - current_point).norm();
230  else
231  {
232  // the distance is to be computed based on radii
233  // in that case, we need to determine the 2 coordinate indices
234  // that define the radius
235  unsigned int i = 0;
236  unsigned int j = 1;
237 
238  if (_axis == 0)
239  i = 2;
240  else if (_axis == 1)
241  j = 2;
242 
243  current_distance = std::abs(
244  std::sqrt(p(i) * p(i) + p(j) * p(j)) -
245  std::sqrt(current_point(i) * current_point(i) + current_point(j) * current_point(j)));
246  }
247 
248  if (current_distance < closest_distance)
249  {
250  closest_distance = current_distance;
251  closest = it.index();
252  }
253  }
254 
255  return *_user_objects[closest];
256 }
257 
258 template <typename UserObjectType, typename BaseType>
259 const std::vector<Point>
261 {
262  std::vector<Point> points;
263 
264  for (MooseIndex(_points) i = 0; i < _points.size(); ++i)
265  {
266  auto layered_base = dynamic_cast<LayeredBase *>(_user_objects[i].get());
267  if (layered_base)
268  {
269  const auto & layers = layered_base->getLayerCenters();
270  auto direction = layered_base->direction();
271 
272  for (const auto & l : layers)
273  {
274  Point pt = _points[i];
275  pt(direction) = l;
276  points.push_back(pt);
277  }
278  }
279  }
280 
281  return points;
282 }
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:302
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()
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
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...