https://mooseframework.inl.gov
FindValueOnLine.C
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 #include "FindValueOnLine.h"
11 
12 // MOOSE includes
13 #include "MooseMesh.h"
14 #include "MooseUtils.h"
15 #include "MooseVariable.h"
16 
18 
21 {
23  params.addClassDescription("Find a specific target value along a sampling line. The variable "
24  "values along the line should change monotonically. The target value "
25  "is searched using a bisection algorithm.");
26  params.addParam<Point>("start_point", "Start point of the sampling line.");
27  params.addParam<Point>("end_point", "End point of the sampling line.");
28  params.addParam<Real>("target", "Target value to locate.");
29  params.addParam<bool>(
30  "error_if_not_found",
31  true,
32  "If true, stop with error if target value is not found on the line. If false, "
33  "return default_value.");
34  params.addParam<Real>("default_value",
35  -1,
36  "Value to return if target value is not found on line and "
37  "error_if_not_found is false.");
38  params.addParam<unsigned int>("depth", 36, "Maximum number of bisections to perform.");
39  params.addParam<Real>(
40  "tol",
41  1e-10,
42  "Stop search if a value is found that is equal to the target with this tolerance applied.");
43  params.addCoupledVar("v", "Variable to inspect");
44  return params;
45 }
46 
48  : GeneralPostprocessor(parameters),
49  Coupleable(this, false),
50  _start_point(getParam<Point>("start_point")),
51  _end_point(getParam<Point>("end_point")),
52  _length((_end_point - _start_point).norm()),
53  _target(getParam<Real>("target")),
54  _error_if_not_found(getParam<bool>("error_if_not_found")),
55  _default_value(getParam<Real>("default_value")),
56  _depth(getParam<unsigned int>("depth")),
57  _tol(getParam<Real>("tol")),
58  _coupled_var(*getVar("v", 0)),
59  _position(0.0),
60  _mesh(_subproblem.mesh()),
61  _point_vec(1)
62 {
63 }
64 
65 void
67 {
68  // We do this here just in case it's been destroyed and recreated becaue of mesh adaptivity.
70  _pl->enable_out_of_mesh_mode();
71 }
72 
73 void
75 {
76  Real s;
77  Real s_left = 0.0;
79  Real s_right = 1.0;
81 
82  // Helper for erroring; won't error if error_if_not_found=false
83  const auto error = [this](auto &&... message)
84  {
86  mooseError(std::scientific, std::setprecision(4), message...);
88  };
89 
94  bool left_to_right = left < right;
95  // Initial bounds check
96  if ((left_to_right && _target < left) || (!left_to_right && _target < right))
97  {
98  error("Target value ",
99  _target,
100  " is less than the minimum sampled value ",
101  std::min(left, right));
102  return;
103  }
104  if ((left_to_right && _target > right) || (!left_to_right && _target > left))
105  {
106  error("Target value ",
107  _target,
108  " is greater than the maximum sampled value ",
109  std::max(left, right));
110  return;
111  }
112 
113  bool found_it = false;
114  Real value = 0;
115  for (unsigned int i = 0; i < _depth; ++i)
116  {
117  // find midpoint
118  s = (s_left + s_right) / 2.0;
119  Point p = s * (_end_point - _start_point) + _start_point;
120 
121  // sample value
122  value = getValueAtPoint(p);
123 
124  // have we hit the target value yet?
126  {
127  found_it = true;
128  break;
129  }
130 
131  // bisect
132  if ((left_to_right && _target < value) || (!left_to_right && _target > value))
133  // to the left
134  s_right = s;
135  else
136  // to the right
137  s_left = s;
138  }
139 
140  // Return error if target value (within tol) was not found within depth bisections
141  if (!found_it)
142  {
143  error("Target value ",
144  _target,
145  " not found on line within tolerance.\nLast sample: ",
146  value,
147  ", difference from target: ",
148  std::abs(_target - value));
149  return;
150  }
151 
152  _position = s * _length;
153 }
154 
155 Real
157 {
158  const Elem * elem = (*_pl)(p);
159 
160  processor_id_type elem_proc_id =
161  elem ? elem->processor_id() : libMesh::DofObject::invalid_processor_id;
162  _communicator.min(elem_proc_id);
163 
164  if (elem_proc_id == libMesh::DofObject::invalid_processor_id)
165  {
166  // there is no element
167  mooseError("No element found at the current search point. Please make sure the sampling line "
168  "stays inside the mesh completely.");
169  }
170 
171  Real value = 0;
172 
173  if (elem)
174  {
175  if (elem->processor_id() == processor_id())
176  {
177  // element is local
178  _point_vec[0] = p;
180  value = _coupled_var.sln()[0];
181  }
182  }
183 
184  // broadcast value
185  _communicator.broadcast(value, elem_proc_id);
186  return value;
187 }
188 
191 {
192  return _position;
193 }
const Point _start_point
line to sample along
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:42
static InputParameters validParams()
virtual void execute() override
Execute method.
const bool & _error_if_not_found
boolean indicating whether to stop with an error if value is not found on the line ...
virtual PostprocessorValue getValue() const override
This will get called to actually grab the final value the postprocessor has calculated.
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:380
const Real _tol
tolerance for comparison to the target value
std::unique_ptr< libMesh::PointLocatorBase > _pl
helper object to locate elements containing points
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & _communicator
This class is here to combine the Postprocessor interface and the base class Postprocessor object alo...
const Real _length
auto max(const L &left, const R &right)
SubProblem & _subproblem
Reference to the Subproblem for this user object.
Definition: UserObject.h:208
static InputParameters validParams()
MooseVariable & _coupled_var
coupled variable
FindValueOnLine(const InputParameters &parameters)
uint8_t processor_id_type
Find a specific target value along a sampling line.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void min(const T &r, T &o, Request &req) const
static const processor_id_type invalid_processor_id
Real getValueAtPoint(const Point &p)
const FieldVariableValue & sln() const override
element solutions
registerMooseObject("MooseApp", FindValueOnLine)
Real PostprocessorValue
various MOOSE typedefs
Definition: MooseTypes.h:202
const Point _end_point
const Real & _default_value
value to return if target value is not found on the line and _error_if_not_found is false ...
MooseMesh & _mesh
The Mesh we&#39;re using.
auto norm(const T &a) -> decltype(std::abs(a))
const Real _target
value to find along the line
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
void addCoupledVar(const std::string &name, const std::string &doc_string)
This method adds a coupled variable name pair.
virtual void reinitElemPhys(const Elem *elem, const std::vector< Point > &phys_points_in_elem, const THREAD_ID tid)=0
Interface for objects that needs coupling capabilities.
Definition: Coupleable.h:45
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const unsigned int _depth
search depth
std::vector< Point > _point_vec
So we don&#39;t have to create and destroy the dummy vector.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
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...
virtual std::unique_ptr< libMesh::PointLocatorBase > getPointLocator() const
Proxy function to get a (sub)PointLocator from either the underlying libMesh mesh (default)...
Definition: MooseMesh.C:3728
processor_id_type processor_id() const
auto min(const L &left, const R &right)
void ErrorVector unsigned int
Real _position
detected interface location