https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
65void
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
73void
75{
76 Real s;
77 Real s_left = 0.0;
78 Real left = getValueAtPoint(_start_point);
79 Real s_right = 1.0;
80 Real right = getValueAtPoint(_end_point);
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?
125 if (MooseUtils::absoluteFuzzyEqual(value, _target, _tol))
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
155Real
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
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}
registerMooseObject("MooseApp", FindValueOnLine)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
Real PostprocessorValue
various MOOSE typedefs
Definition MooseTypes.h:230
void ErrorVector unsigned int
Interface for objects that needs coupling capabilities.
Definition Coupleable.h:53
Find a specific target value along a sampling line.
const Real & _default_value
value to return if target value is not found on the line and _error_if_not_found is false
static InputParameters validParams()
MooseVariable & _coupled_var
coupled variable
Real _position
detected interface location
virtual void execute() override
Execute method.
virtual PostprocessorValue getValue() const override
This will get called to actually grab the final value the postprocessor has calculated.
const bool & _error_if_not_found
boolean indicating whether to stop with an error if value is not found on the line
FindValueOnLine(const InputParameters &parameters)
const unsigned int _depth
search depth
std::vector< Point > _point_vec
So we don't have to create and destroy the dummy vector.
const Point _start_point
line to sample along
const Point _end_point
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
MooseMesh & _mesh
The Mesh we're using.
const Real _tol
tolerance for comparison to the target value
Real getValueAtPoint(const Point &p)
const Real _target
value to find along the line
std::unique_ptr< libMesh::PointLocatorBase > _pl
helper object to locate elements containing points
This class is here to combine the Postprocessor interface and the base class Postprocessor object alo...
static InputParameters validParams()
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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.
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 addCoupledVar(const std::string &name, const std::string &doc_string)
This method adds a coupled variable name pair.
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:3838
const FieldVariableValue & sln() const override
element solutions
virtual void reinitElemPhys(const Elem *elem, const std::vector< Point > &phys_points_in_elem, const THREAD_ID tid)=0
void min(const T &r, T &o, Request &req) const
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
SubProblem & _subproblem
Reference to the Subproblem for this user object.
static constexpr processor_id_type invalid_processor_id
const Parallel::Communicator & _communicator
processor_id_type processor_id() const
MeshBase & mesh