https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
21class UserObject;
22
30template <typename UserObjectType, typename BaseType>
32{
33public:
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
61protected:
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
91template <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
124template <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
154template <typename UserObjectType, typename BaseType>
158
159template <typename UserObjectType, typename BaseType>
160void
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
191 name(),
192 ": You need to supply either 'points', 'points_file' or 'positions_object' parameter.");
193}
194
195template <typename UserObjectType, typename BaseType>
196void
198{
199 for (auto & user_object : _user_objects)
200 user_object->initialize();
201}
202
203template <typename UserObjectType, typename BaseType>
204void
206{
207 nearestUserObject(_current_elem->vertex_average()).execute();
208}
209
210template <typename UserObjectType, typename BaseType>
211void
213{
214 for (auto & user_object : _user_objects)
215 user_object->finalize();
216}
217
218template <typename UserObjectType, typename BaseType>
219void
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
228template <typename UserObjectType, typename BaseType>
229Real
231{
232 return nearestUserObject(p).spatialValue(p);
233}
234
235template <typename UserObjectType, typename BaseType>
236UserObjectType &
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
278template <typename UserObjectType, typename BaseType>
279const 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}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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...
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was set by the user.
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.
This base class computes volume integrals of a variable storing partial sums for the specified number...
Definition LayeredBase.h:37
const std::vector< Real > & getLayerCenters() const
Get the center coordinates for the layers (along given direction)
Definition LayeredBase.h:67
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
Utility class for reading delimited data (e.g., CSV data).
const std::vector< Point > getDataAsPoints() const
Get the data in Point format.
void read()
Perform the actual data reading.
This UserObject computes averages of a variable storing partial sums for the specified number of inte...
virtual void finalize() override
virtual void threadJoin(const UserObject &y) override
void fillPoints()
Fills in the _points variable from either 'points' or 'points_file' parameter.
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...
virtual void initialize() override
NearestPointBase(const InputParameters &parameters)
static InputParameters validParams()
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
virtual const std::vector< Point > spatialPoints() const override
virtual const std::vector< Point > & getPoints() const
Get the points at which the nearest operation is performed.
std::vector< std::unique_ptr< UserObjectType > > _user_objects
const unsigned int _dist_norm
const unsigned int _axis
std::vector< Point > _points
UserObjectType & nearestUserObject(const Point &p) const
Get the UserObject that is closest to the point.
virtual void execute() override
Base class for creating a user object with the SpatialUserObject and Moose::Functor APIs.
static InputParameters validParams()
Base class for user-specific data.
Definition UserObject.h:20
_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