https://mooseframework.inl.gov
Loading...
Searching...
No Matches
NearestReporterCoordinatesFunction.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
11
13
16{
19 "This Function finds the nearest point in the specified vectors of coordinates and returns "
20 "the values specified in the vector of values at the index of the nearest point. All the "
21 "vectors must be specified using either vector postprocessors or reporter vectors. This "
22 "function interpolates linearly in time with transient data.");
23 params.addParam<ReporterName>("x_coord_name",
24 "Name of vector-postprocessor or reporter vector containing "
25 "x-coordinate of points, default is assumed to be all 0s.");
26 params.addParam<ReporterName>("y_coord_name",
27 "Name of vector-postprocessor or reporter vector containing "
28 "y-coordinate of points, default is assumed to be all 0s.");
29 params.addParam<ReporterName>("z_coord_name",
30 "Name of vector-postprocessor or reporter vector containing "
31 "z-coordinate of points, default is assumed to be all 0s.");
32 params.addParam<ReporterName>("time_name",
33 "Name of vector-postprocessor or reporter vector containing time, "
34 "default is assumed to be all 0s.");
36 "value_name", "Name of vector-postprocessor or reporter vector containing value data.");
37 return params;
38}
39
41 const InputParameters & parameters)
42 : OptimizationFunction(parameters),
44 _coordx(isParamValid("x_coord_name") ? getReporterValue<std::vector<Real>>("x_coord_name")
45 : _empty_vec),
46 _coordy(isParamValid("y_coord_name") ? getReporterValue<std::vector<Real>>("y_coord_name")
47 : _empty_vec),
48 _coordz(isParamValid("z_coord_name") ? getReporterValue<std::vector<Real>>("z_coord_name")
49 : _empty_vec),
50 _coordt(isParamValid("time_name") ? getReporterValue<std::vector<Real>>("time_name")
51 : _empty_vec),
52 _values(getReporterValue<std::vector<Real>>("value_name"))
53{
54}
55
56Real
57NearestReporterCoordinatesFunction::value(Real t, const Point & p) const
58{
59 const std::array<std::pair<Real, std::size_t>, 2> tv = findNearestPoint(t, p);
60
61 // If the indices are equal then t is either less than the minimum time in the data
62 // or greater than the maximum time. In which case will extrapolate using a constant
63 // value.
64 if (tv[0].second == tv[1].second)
65 return _values[tv[0].second];
66
67 const Real told = tv[0].first;
68 const Real tnew = tv[1].first;
69 const Real vold = _values[tv[0].second];
70 const Real vnew = _values[tv[1].second];
71 return vold + (vnew - vold) * (t - told) / (tnew - told);
72}
73
74RealGradient
75NearestReporterCoordinatesFunction::gradient(Real /*t*/, const Point & /*p*/) const
76{
77 return RealGradient(0, 0, 0);
78}
79
80Real
82{
83 const std::array<std::pair<Real, std::size_t>, 2> tv = findNearestPoint(t, p);
84
85 if (tv[0].second == tv[1].second)
86 return 0.0;
87
88 const Real told = tv[0].first;
89 const Real tnew = tv[1].first;
90 const Real vold = _values[tv[0].second];
91 const Real vnew = _values[tv[1].second];
92 return (vnew - vold) / (tnew - told);
93}
94
95std::vector<Real>
97{
98 const std::array<std::pair<Real, std::size_t>, 2> tv = findNearestPoint(t, p);
99 std::vector<Real> param_grad(_nval, 0.0);
100
101 if (tv[0].second == tv[1].second)
102 param_grad[tv[0].second] = 1;
103 else
104 {
105 const Real told = tv[0].first;
106 const Real tnew = tv[1].first;
107 param_grad[tv[0].second] = (tnew - t) / (tnew - told);
108 param_grad[tv[1].second] = (t - told) / (tnew - told);
109 }
110 return param_grad;
111}
112
113void
115{
116 // Do some size checks
117 _nval = std::max({_coordx.size(), _coordy.size(), _coordz.size(), _coordt.size()});
118 if (_nval == 0)
119 paramError("value", "At least one coordinate vector must not be empty.");
120 else if (!_coordx.empty() && _coordx.size() != _nval)
121 paramError("x_coord_name",
122 "Number of x coordinates (",
123 _coordx.size(),
124 ") does not match number of values (",
125 _nval,
126 ").");
127 else if (!_coordy.empty() && _coordy.size() != _nval)
128 paramError("y_coord_name",
129 "Number of y coordinates (",
130 _coordy.size(),
131 ") does not match number of values (",
132 _nval,
133 ").");
134 else if (!_coordz.empty() && _coordz.size() != _nval)
135 paramError("z_coord_name",
136 "Number of z coordinates (",
137 _coordz.size(),
138 ") does not match number of values (",
139 _nval,
140 ").");
141 else if (!_coordt.empty() && _coordt.size() != _nval)
142 paramError("time_name",
143 "Number of times (",
144 _coordt.size(),
145 ") does not match number of values (",
146 _nval,
147 ").");
148
149 // Find times for each unique coordinate
150 _coord_mapping.clear();
151 for (const auto & i : make_range(_nval))
152 {
153 Point pt;
154 pt(0) = _coordx.empty() ? 0.0 : _coordx[i];
155 pt(1) = _coordy.empty() ? 0.0 : _coordy[i];
156 pt(2) = _coordz.empty() ? 0.0 : _coordz[i];
157 const Real time = _coordt.empty() ? 0.0 : _coordt[i];
158
159 std::vector<std::pair<Real, std::size_t>> * vec = nullptr;
160 for (auto & it : _coord_mapping)
161 if (pt.absolute_fuzzy_equals(it.first))
162 {
163 vec = &it.second;
164 break;
165 }
166 if (!vec)
167 vec = &_coord_mapping[pt];
168
169 vec->emplace_back(time, i);
170 std::sort(vec->begin(),
171 vec->end(),
172 [](const std::pair<Real, Real> & a, const std::pair<Real, Real> & b)
173 { return a.first < b.first; });
174 }
175}
176
177std::array<std::pair<Real, std::size_t>, 2>
179{
180 if (_coord_mapping.empty())
182
183 // Make sure values is correct size
184 if (_values.size() != _nval)
185 paramError("value_name",
186 "Size of value vector (",
187 _values.size(),
188 ") does not match number of coordinates specified (",
189 _nval,
190 ").");
191
192 const auto & tval =
193 std::min_element(_coord_mapping.begin(),
194 _coord_mapping.end(),
195 [&p](const std::pair<Point, std::vector<std::pair<Real, std::size_t>>> & p1,
196 const std::pair<Point, std::vector<std::pair<Real, std::size_t>>> & p2)
197 { return (p - p1.first).norm_sq() < (p - p2.first).norm_sq(); })
198 ->second;
199
200 if (tval.size() == 1 || MooseUtils::absoluteFuzzyLessEqual(t, tval[0].first))
201 return {tval[0], tval[0]};
202 else if (MooseUtils::absoluteFuzzyGreaterEqual(t, tval.back().first))
203 return {tval.back(), tval.back()};
204 else
205 for (std::size_t ti = 1; ti < tval.size(); ++ti)
206 if (MooseUtils::absoluteFuzzyGreaterEqual(tval[ti].first, t))
207 return {tval[ti - 1], tval[ti]};
208
209 mooseError("Internal error: unable to find nearest point.");
210 return std::array<std::pair<Real, std::size_t>, 2>();
211}
const Real p
registerMooseObject("OptimizationApp", NearestReporterCoordinatesFunction)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
Function based on the nearest point to coordinates and values defined by a vector of values,...
std::map< Point, std::vector< std::pair< Real, std::size_t > > > _coord_mapping
Data structure for all current data.
const std::vector< Real > & _coordy
y-coordinates from reporter
std::size_t _nval
Number of values from coordinate vectors.
virtual Real timeDerivative(Real t, const Point &p) const override
virtual Real value(Real t, const Point &p) const override
const std::vector< Real > & _coordz
z-coordinates from reporter
void buildCoordinateMapping() const
Builds _coord_mapping object with coordinates from input vectors.
virtual RealGradient gradient(Real t, const Point &p) const override
std::array< std::pair< Real, std::size_t >, 2 > findNearestPoint(Real t, const Point &p) const
With an input time and point, gets the closest point and two closest times in _coord_mapping.
NearestReporterCoordinatesFunction(const InputParameters &parameters)
const std::vector< Real > & _coordt
time-coordinates from reporter
const std::vector< Real > & _values
values from reporter
const std::vector< Real > & _coordx
x-coordinates from reporter
virtual std::vector< Real > parameterGradient(Real t, const Point &p) const override
Base class for functions used in inverse optimization The parameterDerivative function is used in adj...
static InputParameters validParams()