https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ParameterMeshFunction.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
12#include "AddVariableAction.h"
13
15
18{
20 params.addClassDescription("Optimization function with parameters represented by a mesh and "
21 "finite-element shape functions.");
22
23 params.addRequiredParam<FileName>("exodus_mesh", "File containing parameter mesh.");
24 params.addParam<MooseEnum>("family",
26 "Family of FE shape functions for parameter.");
27 params.addParam<MooseEnum>("order",
29 "Order of FE shape functions for parameter.");
30
32 "parameter_name", "Reporter or VectorPostprocessor vector containing parameter values.");
33 params.addParam<ReporterName>("time_name",
34 "Name of vector-postprocessor or reporter vector containing time, "
35 "default assumes time independence.");
36 params.addParam<bool>(
37 "project_points", false, "Whether to find the closest point on parameter mesh.");
38 params.addParam<unsigned int>(
39 "kdtree_candidates",
40 5,
41 "Number of nearest node candidates to consider when projecting points to parameter mesh.");
42
43 return params;
44}
45
47 : OptimizationFunction(parameters),
49 _parameter_mesh(AddVariableAction::feType(parameters),
50 getParam<FileName>("exodus_mesh"),
51 getParam<bool>("project_points"),
52 getParam<unsigned int>("kdtree_candidates")),
53 _values(getReporterValue<std::vector<Real>>("parameter_name")),
54 _coordt(isParamValid("time_name") ? getReporterValue<std::vector<Real>>("time_name")
55 : _empty_vec)
56{
57}
58
59Real
60ParameterMeshFunction::value(Real t, const Point & p) const
61{
62 checkSize();
63
64 const auto ti = interpolateTime(t);
65 const dof_id_type offset0 = ti[0].first * _parameter_mesh.size();
66 const dof_id_type offset1 = ti[1].first * _parameter_mesh.size();
67
68 std::vector<dof_id_type> dof_indices;
69 std::vector<Real> weights;
70
71 _parameter_mesh.getIndexAndWeight(p, dof_indices, weights);
72
73 Real val = 0;
74 for (const auto & i : index_range(dof_indices))
75 val += (_values[dof_indices[i] + offset0] * ti[0].second +
76 _values[dof_indices[i] + offset1] * ti[1].second) *
77 weights[i];
78 return val;
79}
80
81RealGradient
82ParameterMeshFunction::gradient(Real t, const Point & p) const
83{
84 checkSize();
85
86 const auto ti = interpolateTime(t);
87 const dof_id_type offset0 = ti[0].first * _parameter_mesh.size();
88 const dof_id_type offset1 = ti[1].first * _parameter_mesh.size();
89
90 std::vector<dof_id_type> dof_indices;
91 std::vector<RealGradient> weights;
92 _parameter_mesh.getIndexAndWeight(p, dof_indices, weights);
93
94 RealGradient val(0, 0, 0);
95 for (const auto & i : index_range(dof_indices))
96 val += (_values[dof_indices[i] + offset0] * ti[0].second +
97 _values[dof_indices[i] + offset1] * ti[1].second) *
98 weights[i];
99 return val;
100}
101
102Real
103ParameterMeshFunction::timeDerivative(Real t, const Point & p) const
104{
105 checkSize();
106
107 const auto ti = interpolateTime(t, true);
108 if (ti[0].first == ti[1].first)
109 return 0.0;
110 const dof_id_type offset0 = ti[0].first * _parameter_mesh.size();
111 const dof_id_type offset1 = ti[1].first * _parameter_mesh.size();
112
113 std::vector<dof_id_type> dof_indices;
114 std::vector<Real> weights;
115 _parameter_mesh.getIndexAndWeight(p, dof_indices, weights);
116
117 Real val = 0;
118 for (const auto & i : index_range(dof_indices))
119 val += (_values[dof_indices[i] + offset0] * ti[0].second +
120 _values[dof_indices[i] + offset1] * ti[1].second) *
121 weights[i];
122 return val;
123}
124
125std::vector<Real>
126ParameterMeshFunction::parameterGradient(Real t, const Point & p) const
127{
128 const auto ti = interpolateTime(t);
129 const dof_id_type offset0 = ti[0].first * _parameter_mesh.size();
130 const dof_id_type offset1 = ti[1].first * _parameter_mesh.size();
131
132 std::vector<dof_id_type> dof_indices;
133 std::vector<Real> weights;
134 _parameter_mesh.getIndexAndWeight(p, dof_indices, weights);
135
136 dof_id_type sz = _parameter_mesh.size();
137 if (!_coordt.empty())
138 sz *= _coordt.size();
139 std::vector<Real> pg(sz, 0.0);
140 for (const auto & i : index_range(dof_indices))
141 {
142 pg[dof_indices[i] + offset0] += weights[i] * ti[0].second;
143 pg[dof_indices[i] + offset1] += weights[i] * ti[1].second;
144 }
145 return pg;
146}
147
148std::array<std::pair<std::size_t, Real>, 2>
149ParameterMeshFunction::interpolateTime(Real t, bool derivative) const
150{
151 std::array<std::pair<std::size_t, Real>, 2> ti;
152 if (_coordt.size() <= 1 || MooseUtils::absoluteFuzzyLessEqual(t, _coordt[0]))
153 {
154 ti[0] = {0, 0.5};
155 ti[1] = {0, 0.5};
156 }
157 else if (MooseUtils::absoluteFuzzyGreaterEqual(t, _coordt.back()))
158 {
159 ti[0] = {_coordt.size() - 1, 0.5};
160 ti[1] = {_coordt.size() - 1, 0.5};
161 }
162 else
163 for (std::size_t i = 1; i < _coordt.size(); ++i)
164 if (MooseUtils::absoluteFuzzyGreaterEqual(_coordt[i], t))
165 {
166 const Real dt = _coordt[i] - _coordt[i - 1];
167 if (derivative)
168 {
169 ti[0] = {i - 1, -1.0 / dt};
170 ti[1] = {i, 1.0 / dt};
171 }
172 else
173 {
174 ti[0] = {i - 1, (_coordt[i] - t) / dt};
175 ti[1] = {i, (t - _coordt[i - 1]) / dt};
176 }
177 break;
178 }
179
180 return ti;
181}
182
183void
185{
186 dof_id_type sz = _parameter_mesh.size();
187 if (!_coordt.empty())
188 sz *= _coordt.size();
189 if (sz != _values.size())
190 paramError("parameter_name",
191 "Size of parameter vector (",
192 _values.size(),
193 ") does not match number of degrees of freedom in mesh (",
194 sz,
195 ").");
196}
const Real p
registerMooseObject("OptimizationApp", ParameterMeshFunction)
void ErrorVector unsigned int
static MooseEnum getNonlinearVariableFamilies()
static MooseEnum getNonlinearVariableOrders()
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
Base class for functions used in inverse optimization The parameterDerivative function is used in adj...
static InputParameters validParams()
const std::vector< Real > & _coordt
Time coordinates from reporter.
ParameterMeshFunction(const InputParameters &parameters)
virtual Real timeDerivative(Real t, const Point &p) const override
virtual RealGradient gradient(Real t, const Point &p) const override
virtual Real value(Real t, const Point &p) const override
const ParameterMesh _parameter_mesh
Parameter mesh.
virtual std::vector< Real > parameterGradient(Real t, const Point &p) const override
std::array< std::pair< std::size_t, Real >, 2 > interpolateTime(Real t, bool derivative=false) const
This function is used to compute the weights for time interpolation.
void checkSize() const
Used to make sure DoFs in '_parameter_mesh' matches number of values in '_values'.
static InputParameters validParams()
const std::vector< Real > & _values
values from reporter
dof_id_type size() const
void getIndexAndWeight(const Point &pt, std::vector< dof_id_type > &dof_indices, std::vector< Real > &weights) const
Interpolate parameters onto the computational mesh getIndexAndWeight is only used by ParameterMeshFun...