Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 :
4 : // This library is free software; you can redistribute it and/or
5 : // modify it under the terms of the GNU Lesser General Public
6 : // License as published by the Free Software Foundation; either
7 : // version 2.1 of the License, or (at your option) any later version.
8 :
9 : // This library is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : // Lesser General Public License for more details.
13 :
14 : // You should have received a copy of the GNU Lesser General Public
15 : // License along with this library; if not, write to the Free Software
16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 :
18 :
19 :
20 : #ifndef LIBMESH_SENSITIVITY_DATA_H
21 : #define LIBMESH_SENSITIVITY_DATA_H
22 :
23 :
24 : // Local Includes
25 : #include "libmesh/libmesh_common.h"
26 : #include "libmesh/parameter_vector.h"
27 : #include "libmesh/system.h"
28 :
29 : // C++ Includes
30 : #include <vector>
31 :
32 : namespace libMesh
33 : {
34 :
35 : // Forward declarations
36 : class QoISet;
37 :
38 : /**
39 : * Data structure for holding completed parameter sensitivity
40 : * calculations.
41 : *
42 : * \author Roy Stogner
43 : * \date 2009
44 : * \brief Holds completed parameter sensitivity calculations.
45 : */
46 4216 : class SensitivityData
47 : {
48 : public:
49 : class Row
50 : {
51 : public:
52 0 : Row(SensitivityData & sd, unsigned int qoi) : _sd(sd), _qoi(qoi) {}
53 :
54 0 : Number & operator[] (unsigned int parameter) { return _sd.derivative(_qoi, parameter); }
55 : private:
56 : SensitivityData & _sd;
57 : unsigned int _qoi;
58 : };
59 :
60 : class ConstRow
61 : {
62 : public:
63 : ConstRow(const SensitivityData & sd, unsigned int qoi) : _sd(sd), _qoi(qoi) {}
64 :
65 : const Number & operator[] (unsigned int parameter) { return _sd.derivative(_qoi, parameter); }
66 : private:
67 : const SensitivityData & _sd;
68 : unsigned int _qoi;
69 : };
70 :
71 : /**
72 : * Default constructor: empty data set
73 : */
74 : SensitivityData() {}
75 :
76 : /**
77 : * Constructor from QoISet and ParameterVector: allocates space
78 : * for all required sensitivities
79 : */
80 : SensitivityData(const QoISet & qoi_indices,
81 : const System & sys,
82 : const ParameterVector & parameter_vector);
83 :
84 : /**
85 : * Clears and deallocates all data
86 : */
87 : void clear() { _grad_data.clear(); }
88 :
89 : /**
90 : * Given QoISet and ParameterVector, allocates space
91 : * for all required first derivative data
92 : */
93 : void allocate_data(const QoISet & qoi_indices,
94 : const System & sys,
95 : const ParameterVector & parameter_vector);
96 :
97 : /**
98 : * Given QoISet and ParameterVector, allocates space
99 : * for all required second derivative data
100 : */
101 : void allocate_hessian_data(const QoISet & qoi_indices,
102 : const System & sys,
103 : const ParameterVector & parameter_vector);
104 :
105 : /**
106 : * \returns The parameter sensitivity derivative for the specified
107 : * quantity of interest for the specified parameter
108 : */
109 : const Number & derivative (unsigned int qoi_index,
110 : unsigned int parameter_index) const;
111 :
112 : /**
113 : * \returns The parameter sensitivity derivative for the specified
114 : * quantity of interest for the specified pair of parameters
115 : */
116 : const Number & second_derivative (unsigned int qoi_index,
117 : unsigned int parameter_index1,
118 : unsigned int parameter_index2) const;
119 :
120 : /**
121 : * Gets/sets the parameter sensitivity derivative for the specified
122 : * quantity of interest for the specified parameter
123 : */
124 : Number & derivative (unsigned int qoi_index,
125 : unsigned int parameter_index);
126 :
127 : /**
128 : * Gets/sets the parameter sensitivity second derivative for the
129 : * specified quantity of interest for the specified pair of
130 : * parameters
131 : */
132 : Number & second_derivative (unsigned int qoi_index,
133 : unsigned int parameter_index1,
134 : unsigned int parameter_index2);
135 :
136 : /**
137 : * Vector address type operator: sd[q][p] is an alias for
138 : * sd.derivative(q,p)
139 : */
140 : ConstRow operator[] (unsigned int qoi) const { return ConstRow(*this, qoi); }
141 :
142 0 : Row operator[] (unsigned int qoi) { return Row(*this, qoi); }
143 :
144 : private:
145 : /**
146 : * Data storage; currently pretty trivial
147 : */
148 : std::vector<std::vector<Number>> _grad_data;
149 : std::vector<std::vector<std::vector<Number>>> _hess_data;
150 : };
151 :
152 :
153 :
154 : // ------------------------------------------------------------
155 : // SensitivityData inline methods
156 :
157 :
158 :
159 : inline
160 8432 : SensitivityData::SensitivityData(const QoISet & qoi_indices,
161 : const System & sys,
162 8680 : const ParameterVector & parameter_vector)
163 : {
164 8432 : this->allocate_data(qoi_indices, sys, parameter_vector);
165 8432 : }
166 :
167 :
168 :
169 : inline
170 450 : void SensitivityData::allocate_data(const QoISet & qoi_indices,
171 : const System & sys,
172 : const ParameterVector & parameter_vector)
173 : {
174 0 : const std::size_t Np = parameter_vector.size();
175 0 : const unsigned int Nq = sys.n_qois();
176 :
177 900 : if (_grad_data.size() < Nq)
178 248 : _grad_data.resize(Nq);
179 :
180 900 : for (unsigned int i=0; i != Nq; ++i)
181 450 : if (qoi_indices.has_index(i))
182 : {
183 450 : _grad_data[i].clear();
184 450 : _grad_data[i].resize(Np);
185 : }
186 450 : }
187 :
188 :
189 :
190 : inline
191 0 : void SensitivityData::allocate_hessian_data(const QoISet & qoi_indices,
192 : const System & sys,
193 : const ParameterVector & parameter_vector)
194 : {
195 0 : const std::size_t Np = parameter_vector.size();
196 0 : const unsigned int Nq = sys.n_qois();
197 :
198 0 : if (_hess_data.size() < Nq)
199 0 : _hess_data.resize(Nq);
200 :
201 0 : for (unsigned int i=0; i != Nq; ++i)
202 0 : if (qoi_indices.has_index(i))
203 : {
204 0 : _hess_data[i].clear();
205 0 : _hess_data[i].resize(Np);
206 0 : for (std::size_t j=0; j != Np; ++j)
207 0 : _hess_data[i][j].resize(Np);
208 : }
209 0 : }
210 :
211 :
212 :
213 : inline
214 : const Number & SensitivityData::derivative(unsigned int qoi_index,
215 : unsigned int parameter_index) const
216 : {
217 : libmesh_assert_less (qoi_index, _grad_data.size());
218 : libmesh_assert_less (parameter_index, _grad_data[qoi_index].size());
219 :
220 : return _grad_data[qoi_index][parameter_index];
221 : }
222 :
223 :
224 :
225 : inline
226 0 : Number & SensitivityData::derivative(unsigned int qoi_index,
227 : unsigned int parameter_index)
228 : {
229 0 : libmesh_assert_less (qoi_index, _grad_data.size());
230 0 : libmesh_assert_less (parameter_index, _grad_data[qoi_index].size());
231 :
232 5260 : return _grad_data[qoi_index][parameter_index];
233 : }
234 :
235 :
236 :
237 : inline
238 : const Number & SensitivityData::second_derivative(unsigned int qoi_index,
239 : unsigned int parameter_index1,
240 : unsigned int parameter_index2) const
241 : {
242 : libmesh_assert_less (qoi_index, _hess_data.size());
243 : libmesh_assert_less (parameter_index1, _hess_data[qoi_index].size());
244 : libmesh_assert_less (parameter_index2, _hess_data[qoi_index][parameter_index1].size());
245 :
246 : return _hess_data[qoi_index][parameter_index1][parameter_index2];
247 : }
248 :
249 :
250 :
251 : inline
252 0 : Number & SensitivityData::second_derivative(unsigned int qoi_index,
253 : unsigned int parameter_index1,
254 : unsigned int parameter_index2)
255 : {
256 0 : libmesh_assert_less (qoi_index, _hess_data.size());
257 0 : libmesh_assert_less (parameter_index1, _hess_data[qoi_index].size());
258 0 : libmesh_assert_less (parameter_index2, _hess_data[qoi_index][parameter_index1].size());
259 :
260 0 : return _hess_data[qoi_index][parameter_index1][parameter_index2];
261 : }
262 :
263 : } // namespace libMesh
264 :
265 : #endif // LIBMESH_SENSITIVITY_DATA_H
|