https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PODReducedBasisSurrogate.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{
18 params.addClassDescription("Evaluates POD-RB surrogate model with reduced operators "
19 "computed from PODReducedBasisTrainer.");
20 params.addParam<std::vector<std::string>>("change_rank",
21 std::vector<std::string>(0),
22 "Names of variables whose rank should be changed.");
23 params.addParam<std::vector<unsigned int>>(
24 "new_ranks",
25 std::vector<unsigned int>(0),
26 "The new ranks that each variable in 'change_rank' shall have.");
27 params.addParam<Real>("penalty", 1e5, "The penalty parameter for Dirichlet BCs.");
28 return params;
29}
30
32 : SurrogateModel(parameters),
33 _change_rank(getParam<std::vector<std::string>>("change_rank")),
34 _new_ranks(getParam<std::vector<unsigned int>>("new_ranks")),
35 _var_names(getModelData<std::vector<std::string>>("_var_names")),
36 _tag_types(getModelData<std::vector<std::string>>("_tag_types")),
37 _base(getModelData<std::vector<std::vector<DenseVector<Real>>>>("_base")),
38 _red_operators(getModelData<std::vector<DenseMatrix<Real>>>("_red_operators")),
39 _penalty(getParam<Real>("penalty")),
40 _initialized(false)
41{
42 if (_change_rank.size() != _new_ranks.size())
43 paramError("new_ranks",
44 "The size of 'new_ranks' is not equal to the ",
45 "size of 'change_rank' ",
46 _new_ranks.size(),
47 " != ",
48 _change_rank.size());
49
50 for (unsigned int var_i = 0; var_i < _new_ranks.size(); ++var_i)
51 if (_new_ranks[var_i] == 0)
52 paramError("new_ranks", "The values should be greater than 0!");
53}
54
55void
56PODReducedBasisSurrogate::evaluateSolution(const std::vector<Real> & params)
57{
58 if (!_initialized)
59 {
60 // The containers are initialized (if needed).
63 _initialized = true;
64 }
65
66 // Assembling and solving the reduced equation system.
67 solveReducedSystem(params);
68
69 // Reconstructing the approximate solutions for every variable.
71}
72
73void
74PODReducedBasisSurrogate::evaluateSolution(const std::vector<Real> & params,
75 DenseVector<Real> & inp_vector,
76 std::string var_name)
77{
78 if (!_initialized)
79 {
80 // The containers are initialized (if needed).
82 _initialized = true;
83 }
84
85 // Assembling and solving the reduced equation system.
86 solveReducedSystem(params);
87
88 // Reconstructing the approximate solutions for every variable.
89 reconstructApproximateSolution(inp_vector, var_name);
90}
91
92void
94{
95 // Storing important indices for the assembly loops.
96 _final_ranks.resize(_var_names.size());
97 _comulative_ranks.resize(_var_names.size());
98 unsigned int sum_ranks = 0;
99
100 // Checking if the user wants to overwrite the original ranks for the
101 // variables.
102 for (unsigned int var_i = 0; var_i < _var_names.size(); ++var_i)
103 {
104 _final_ranks[var_i] = _base[var_i].size();
105 for (unsigned int var_j = 0; var_j < _change_rank.size(); ++var_j)
106 {
107 if (_change_rank[var_j] == _var_names[var_i])
108 {
109 if (_new_ranks[var_j] > _base[var_i].size())
110 {
111 mooseWarning("The specified new rank (",
112 _new_ranks[var_j],
113 ") for variable '",
114 _var_names[var_i],
115 "' is higher than the original rank (",
116 _base[var_i].size(),
117 ")! Switched to original rank.");
118 break;
119 }
120
121 _final_ranks[var_i] = _new_ranks[var_j];
122 }
123 }
124 sum_ranks += _final_ranks[var_i];
125 _comulative_ranks[var_i] = sum_ranks;
126 }
127
128 // Resizing containers to match the newly prescribed ranks.
129 _sys_mx = DenseMatrix<Real>(sum_ranks, sum_ranks);
130 _rhs = DenseVector<Real>(sum_ranks);
131 _coeffs = DenseVector<Real>(sum_ranks);
132}
133
134void
136{
137 _approx_solution.resize(_var_names.size());
138 for (unsigned int var_i = 0; var_i < _var_names.size(); var_i++)
139 _approx_solution[var_i] = DenseVector<Real>(_base[var_i][0].size());
140}
141
142void
143PODReducedBasisSurrogate::solveReducedSystem(const std::vector<Real> & params)
144{
145 // Cleaning the containers of the system matrix and right hand side.
146 _sys_mx.zero();
147 _rhs.zero();
148
149 // The assumption here is that the reduced operators in the trainer were
150 // assembled in the order of the parameters. Also, if the number of
151 // parameters is fewer than the number of operators, the operator will
152 // just be added without scaling.
153 for (unsigned int i = 0; i < _red_operators.size(); ++i)
154 {
155 unsigned int row_start = 0;
156
157 // Checking if the reduced operator corresponds to a Dirichlet BC, if
158 // yes introduce the penalty factor.
159 Real factor = 1.0;
160 if (_tag_types[i] == "op_dir" || _tag_types[i] == "src_dir")
161 factor = _penalty;
162
163 // If the user decreased the rank of the reduced bases manually, some parts
164 // of the initial reduced operators have to be omited.
165 for (unsigned int var_i = 0; var_i < _var_names.size(); ++var_i)
166 {
167 for (unsigned int row_i = row_start; row_i < _comulative_ranks[var_i]; row_i++)
168 {
169 if (_tag_types[i] == "op" || _tag_types[i] == "op_dir")
170 {
171
172 unsigned int col_start = 0;
173
174 for (unsigned int var_j = 0; var_j < _var_names.size(); ++var_j)
175 {
176 for (unsigned int col_i = col_start; col_i < _comulative_ranks[var_j]; col_i++)
177 {
178 if (i < params.size())
179 _sys_mx(row_i, col_i) += params[i] * factor * _red_operators[i](row_i, col_i);
180 else
181 _sys_mx(row_i, col_i) += factor * _red_operators[i](row_i, col_i);
182 }
183
184 col_start = _comulative_ranks[var_j];
185 }
186 }
187 else
188 {
189 if (i < params.size())
190 _rhs(row_i) -= params[i] * factor * _red_operators[i](row_i, 0);
191 else
192 _rhs(row_i) -= factor * _red_operators[i](row_i, 0);
193 }
194 row_start = _comulative_ranks[var_i];
195 }
196 }
197 }
198
199 // Solving the reduced system.
201}
202
203void
205{
206 unsigned int counter = 0;
207 for (unsigned int var_i = 0; var_i < _var_names.size(); var_i++)
208 {
209 _approx_solution[var_i].zero();
210
211 // This also takes into account the potential truncation of the bases by
212 // the user.
213 for (unsigned int base_i = 0; base_i < _final_ranks[var_i]; ++base_i)
214 {
215 for (unsigned int dof_i = 0; dof_i < _base[var_i][base_i].size(); ++dof_i)
216 _approx_solution[var_i](dof_i) += _coeffs(counter) * _base[var_i][base_i](dof_i);
217 counter++;
218 }
219 }
220}
221
222void
224 std::string var_name)
225{
226 auto it = std::find(_var_names.begin(), _var_names.end(), var_name);
227 if (it == _var_names.end())
228 mooseError("Variable '", var_name, "' does not exist in the POD-RB surrogate!");
229
230 unsigned int var_i = std::distance(_var_names.begin(), it);
231
232 if (inp_vector.size() != _base[var_i][0].size())
233 mooseError("The size of the input vector (",
234 inp_vector.size(),
235 ") for variable '",
236 var_name,
237 "' does not match the size of the stored base vector (",
238 _base[var_i][0].size(),
239 ") in POD-RB surrogate!");
240
241 inp_vector.zero();
242
243 unsigned int base_begin = 0;
244 if (var_i != 0)
245 base_begin = _comulative_ranks[var_i - 1];
246
247 for (unsigned int base_i = 0; base_i < _final_ranks[var_i]; ++base_i)
248 {
249 for (unsigned int dof_i = 0; dof_i < inp_vector.size(); ++dof_i)
250 inp_vector(dof_i) += _coeffs(base_i + base_begin) * _base[var_i][base_i](dof_i);
251 }
252}
253
254Real
255PODReducedBasisSurrogate::getNodalQoI(std::string var_name, unsigned int qoi_type) const
256{
257 Real val = 0.0;
258
259 auto it = std::find(_var_names.begin(), _var_names.end(), var_name);
260 if (it == _var_names.end())
261 mooseError("Variable '", var_name, "' not found!");
262
263 switch (qoi_type)
264 {
265 case 0:
266 val = _approx_solution[it - _var_names.begin()].max();
267 break;
268
269 case 1:
270 val = _approx_solution[it - _var_names.begin()].min();
271 break;
272
273 case 2:
274 val = _approx_solution[it - _var_names.begin()].l1_norm();
275 break;
276
277 case 3:
278 val = _approx_solution[it - _var_names.begin()].l2_norm();
279 break;
280
281 case 4:
282 val = _approx_solution[it - _var_names.begin()].linfty_norm();
283 break;
284 }
285
286 return (val);
287}
registerMooseObject("StochasticToolsApp", PODReducedBasisSurrogate)
void ErrorVector unsigned int
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
void mooseWarning(Args &&... args) const
PODReducedBasisSurrogate(const InputParameters &parameters)
Real getNodalQoI(std::string var_name, unsigned int qoi_type) const
Get the nodal QoI of the reconstructed solution for a given variable.
void reconstructApproximateSolution()
Reconstruct the approximate solution vector using the stored coefficients.
void solveReducedSystem(const std::vector< Real > &params)
Assemble and solve the reduced equation system.
void initializeReducedSystem()
Initialize reduced matrices, vectors and additional containers.
const Real _penalty
Penalty parameter for Dirichlet BCs.
std::vector< unsigned int > _comulative_ranks
Comulative ranks of the system. Used for indexing only.
static InputParameters validParams()
std::vector< unsigned int > _new_ranks
The new rank the variable should have.
std::vector< DenseVector< Real > > _approx_solution
Reconstructed solution for each variable.
void initializeApproximateSolution()
Initialize approximate solution vector.
const std::vector< std::vector< DenseVector< Real > > > & _base
The basis vectors for all the variables.
std::vector< std::string > _change_rank
A vector containing the number of basis functions each variable should use.
bool _initialized
Switch that is set to see if the ROM matrices and vectors are initialized.
void evaluateSolution(const std::vector< Real > &params)
Get the reduced solution for a given parameter sample.
const std::vector< std::string > & _tag_types
Strings describing which operator is indepedent of the solution and which corresponds to a reduced Di...
const std::vector< DenseMatrix< Real > > & _red_operators
The reduced operators in the same order as given in tag_types.
DenseVector< Real > _rhs
The reduced right hand side.
DenseMatrix< Real > _sys_mx
The reduced system matrix.
std::vector< unsigned int > _final_ranks
The final rank that should be used for every variable.
DenseVector< Real > _coeffs
Coefficients of the reduced order model.
const std::vector< std::string > & _var_names
Vector containing the names of the variables we want to reconstruct.
static InputParameters validParams()
void lu_solve(const DenseVector< T > &b, DenseVector< T > &x)
virtual void zero() override final