Line data Source code
1 : // rbOOmit: An implementation of the Certified Reduced Basis method.
2 : // Copyright (C) 2009, 2010 David J. Knezevic
3 :
4 : // This file is part of rbOOmit.
5 :
6 : // rbOOmit is free software; you can redistribute it and/or
7 : // modify it under the terms of the GNU Lesser General Public
8 : // License as published by the Free Software Foundation; either
9 : // version 2.1 of the License, or (at your option) any later version.
10 :
11 : // rbOOmit is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : // Lesser General Public License for more details.
15 :
16 : // You should have received a copy of the GNU Lesser General Public
17 : // License along with this library; if not, write to the Free Software
18 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 :
20 : #ifndef LIBMESH_RB_EVALUATION_H
21 : #define LIBMESH_RB_EVALUATION_H
22 :
23 : // rbOOmit includes
24 : #include "libmesh/rb_parametrized.h"
25 :
26 : // libMesh includes
27 : #include "libmesh/dense_matrix.h"
28 : #include "libmesh/dense_vector.h"
29 : #include "libmesh/parallel_object.h"
30 :
31 : // C++ includes
32 : #include <memory>
33 :
34 : namespace libMesh
35 : {
36 :
37 : class System;
38 : template <typename T> class NumericVector;
39 : class RBThetaExpansion;
40 :
41 : /**
42 : * This class is part of the rbOOmit framework.
43 : *
44 : * RBEvaluation encapsulates the functionality required
45 : * to _evaluate_ a given reduced basis model.
46 : *
47 : * \author David J. Knezevic
48 : * \date 2011
49 : */
50 64 : class RBEvaluation : public RBParametrized,
51 : public ParallelObject
52 : {
53 : public:
54 :
55 : /**
56 : * Constructor.
57 : */
58 : RBEvaluation (const Parallel::Communicator & comm);
59 :
60 : /**
61 : * Special functions.
62 : * - This class contains unique_ptrs, so it can't be default copy
63 : * constructed/assigned.
64 : * - The destructor is defaulted out of line.
65 : */
66 : RBEvaluation (RBEvaluation &&) = default;
67 : RBEvaluation (const RBEvaluation &) = delete;
68 : RBEvaluation & operator= (const RBEvaluation &) = delete;
69 : RBEvaluation & operator= (RBEvaluation &&) = default;
70 : virtual ~RBEvaluation ();
71 :
72 : /**
73 : * Clear this RBEvaluation object. Delete the basis functions
74 : * and clear and extra data in subclasses.
75 : */
76 : virtual void clear() override;
77 :
78 : /**
79 : * Set the RBThetaExpansion object.
80 : */
81 : void set_rb_theta_expansion(RBThetaExpansion & rb_theta_expansion_in);
82 :
83 : /**
84 : * Get a reference to the rb_theta_expansion.
85 : */
86 : RBThetaExpansion & get_rb_theta_expansion();
87 : const RBThetaExpansion & get_rb_theta_expansion() const;
88 :
89 : /**
90 : * \returns \p true if the theta expansion has been initialized.
91 : */
92 : bool is_rb_theta_expansion_initialized() const;
93 :
94 : /**
95 : * Resize and clear the data vectors corresponding to the value of
96 : * \p Nmax. Optionally resize the data structures required for the
97 : * error bound. Override to also clear and resize any extra data in
98 : * subclasses.
99 : */
100 : virtual void resize_data_structures(const unsigned int Nmax,
101 : bool resize_error_bound_data=true);
102 :
103 : /**
104 : * Get a reference to the i^th basis function.
105 : */
106 : NumericVector<Number> & get_basis_function(unsigned int i);
107 : const NumericVector<Number> & get_basis_function(unsigned int i) const;
108 :
109 : /**
110 : * Perform online solve with the N RB basis functions, for the
111 : * set of parameters in current_params, where 0 <= N <= RB_size.
112 : * \returns The (absolute) error bound associated with
113 : * the RB approximation.
114 : * With an empty RB space (N=0), our RB solution is zero, but we
115 : * still obtain a meaningful error bound associated with the
116 : * forcing terms.
117 : */
118 : virtual Real rb_solve(unsigned int N);
119 :
120 : /**
121 : * The same as above, except that we pass in evaluated_thetas
122 : * instead of recomputing the theta values.
123 : */
124 : virtual Real rb_solve(unsigned int N,
125 : const std::vector<Number> * evaluated_thetas);
126 :
127 : /**
128 : * \returns A scaling factor that we can use to provide a consistent
129 : * scaling of the RB error bound across different parameter values.
130 : */
131 : virtual Real get_error_bound_normalization();
132 :
133 : /**
134 : * Compute the dual norm of the residual for the solution
135 : * saved in RB_solution_vector.
136 : */
137 : virtual Real compute_residual_dual_norm(const unsigned int N);
138 :
139 : /**
140 : * The same as above, except that we pass in evaluated thetas
141 : * instead of recomputing the theta values.
142 : */
143 : virtual Real compute_residual_dual_norm(const unsigned int N,
144 : const std::vector<Number> * evaluated_thetas);
145 :
146 : /**
147 : * Specifies the residual scaling on the denominator to
148 : * be used in the a posteriori error bound. Override
149 : * in subclass in order to obtain the desired error bound.
150 : */
151 : virtual Real residual_scaling_denom(Real alpha_LB);
152 :
153 : /**
154 : * Evaluate the dual norm of output \p n for the current parameters,
155 : * or using the pre-evaluted theta values provided in the "evaluated_thetas"
156 : * array.
157 : */
158 : Real eval_output_dual_norm(unsigned int n, const std::vector<Number> * evaluated_thetas);
159 :
160 : /**
161 : * Get a lower bound for the stability constant (e.g. coercivity constant or
162 : * inf-sup constant) at the current parameter value.
163 : */
164 : virtual Real get_stability_lower_bound();
165 :
166 : /**
167 : * Get the current number of basis functions.
168 : */
169 1105790 : virtual unsigned int get_n_basis_functions() const
170 1184354 : { return cast_int<unsigned int>(basis_functions.size()); }
171 :
172 : /**
173 : * Set the number of basis functions. Useful when reading in
174 : * stored data.
175 : */
176 : virtual void set_n_basis_functions(unsigned int n_bfs);
177 :
178 : /**
179 : * Clear all the Riesz representors that are used to compute the RB residual
180 : * (and hence error bound). This is useful since once we complete the Greedy
181 : * we may not need the representors any more.
182 : */
183 : virtual void clear_riesz_representors();
184 :
185 : /**
186 : * Write out all the data to text files in order to segregate the
187 : * Offline stage from the Online stage.
188 : *
189 : * \note This is a legacy method, use RBDataSerialization instead.
190 : */
191 : virtual void legacy_write_offline_data_to_files(const std::string & directory_name = "offline_data",
192 : const bool write_binary_data=true);
193 :
194 : /**
195 : * Read in the saved Offline reduced basis data
196 : * to initialize the system for Online solves.
197 : *
198 : * \note This is a legacy method, use RBDataSerialization instead.
199 : */
200 : virtual void legacy_read_offline_data_from_files(const std::string & directory_name = "offline_data",
201 : bool read_error_bound_data=true,
202 : const bool read_binary_data=true);
203 :
204 : /**
205 : * Write out all the basis functions to file.
206 : * \p sys is used for file IO
207 : * \p directory_name specifies which directory to write files to
208 : * \p read_binary_basis_functions indicates whether to expect
209 : * binary or ASCII data
210 : */
211 : virtual void write_out_basis_functions(System & sys,
212 : const std::string & directory_name = "offline_data",
213 : const bool write_binary_basis_functions = true);
214 :
215 : /**
216 : * Same as write_out_basis_functions, except in this case we pass in the vectors to be
217 : * written.
218 : */
219 : static void write_out_vectors(System & sys,
220 : std::vector<NumericVector<Number>*> & vectors,
221 : const std::string & directory_name = "offline_data",
222 : const std::string & data_name = "bf",
223 : const bool write_binary_basis_functions = true);
224 :
225 : /**
226 : * Read in all the basis functions from file.
227 : *
228 : * \param sys Used for file IO.
229 : * \param directory_name Specifies which directory to write files to.
230 : * \param read_binary_basis_functions Indicates whether to expect binary or ASCII data.
231 : */
232 : virtual void read_in_basis_functions(System & sys,
233 : const std::string & directory_name = "offline_data",
234 : const bool read_binary_basis_functions = true);
235 :
236 : /**
237 : * Same as read_in_basis_functions, except in this case we pass in the vectors to be
238 : * written. We assume that the size of vectors indicates the number of vectors
239 : * that need to be read in.
240 : */
241 : static void read_in_vectors(System & sys,
242 : std::vector<std::unique_ptr<NumericVector<Number>>> & vectors,
243 : const std::string & directory_name,
244 : const std::string & data_name,
245 : const bool read_binary_vectors);
246 :
247 : /**
248 : * Performs read_in_vectors for a list of directory names and data names.
249 : * Reading in vectors requires us to renumber the dofs in a partition-independent
250 : * way. This function only renumbers the dofs once at the start (and reverts
251 : * it at the end), which can save a lot of work compared to renumbering on every read.
252 : */
253 : static void read_in_vectors_from_multiple_files(System & sys,
254 : std::vector<std::vector<std::unique_ptr<NumericVector<Number>>> *> multiple_vectors,
255 : const std::vector<std::string> & multiple_directory_names,
256 : const std::vector<std::string> & multiple_data_names,
257 : const bool read_binary_vectors);
258 :
259 : //----------- PUBLIC DATA MEMBERS -----------//
260 :
261 : /**
262 : * The libMesh vectors storing the finite element coefficients
263 : * of the RB basis functions.
264 : */
265 : std::vector<std::unique_ptr<NumericVector<Number>>> basis_functions;
266 :
267 : /**
268 : * The list of parameters selected by the Greedy algorithm in generating
269 : * the Reduced Basis associated with this RBEvaluation object.
270 : */
271 : std::vector<RBParameters> greedy_param_list;
272 :
273 : /**
274 : * The inner product matrix. This should be close to the identity,
275 : * we need to calculate this rather than assume diagonality in order
276 : * to accurately perform projections since orthogonality degrades
277 : * with increasing N.
278 : */
279 : DenseMatrix<Number> RB_inner_product_matrix;
280 :
281 : /**
282 : * Dense matrices for the RB computations.
283 : */
284 : std::vector<DenseMatrix<Number>> RB_Aq_vector;
285 :
286 : /**
287 : * Dense vector for the RHS.
288 : */
289 : std::vector<DenseVector<Number>> RB_Fq_vector;
290 :
291 : /**
292 : * The RB solution vector.
293 : */
294 : DenseVector<Number> RB_solution;
295 :
296 : /**
297 : * The vectors storing the RB output vectors.
298 : */
299 : std::vector<std::vector<DenseVector<Number>>> RB_output_vectors;
300 :
301 : /**
302 : * The vectors storing the RB output values and
303 : * corresponding error bounds.
304 : */
305 : std::vector<Number > RB_outputs;
306 : std::vector<Real > RB_output_error_bounds;
307 :
308 : /**
309 : * Vectors storing the residual representor inner products
310 : * to be used in computing the residuals online.
311 : * These values are independent of a basis, hence they can
312 : * be copied over directly from an RBSystem.
313 : */
314 : std::vector<Number> Fq_representor_innerprods;
315 :
316 : /**
317 : * Vectors storing the residual representor inner products
318 : * to be used in computing the residuals online.
319 : * We store the Aq-dependent representor inner products because they depend
320 : * on a reduced basis space. The basis independent representors
321 : * are stored in RBSystem.
322 : */
323 : std::vector<std::vector<std::vector<Number>>> Fq_Aq_representor_innerprods;
324 : std::vector<std::vector<std::vector<Number>>> Aq_Aq_representor_innerprods;
325 :
326 : /**
327 : * The vector storing the dual norm inner product terms
328 : * for each output.
329 : * These values are independent of a basis, hence they can
330 : * be copied over directly from an RBSystem.
331 : */
332 : std::vector<std::vector<Number >> output_dual_innerprods;
333 :
334 : /**
335 : * Vector storing the residual representors associated with the
336 : * left-hand side.
337 : * These are basis dependent and hence stored here, whereas
338 : * the Fq_representors are stored in RBSystem.
339 : */
340 : std::vector<std::vector<std::unique_ptr<NumericVector<Number>>>> Aq_representor;
341 :
342 : /**
343 : * Boolean to indicate whether we evaluate a posteriori error bounds
344 : * when rb_solve is called.
345 : */
346 : bool evaluate_RB_error_bound;
347 :
348 : /**
349 : * Boolean flag to indicate whether we compute the RB_inner_product_matrix.
350 : */
351 : bool compute_RB_inner_product;
352 :
353 : protected:
354 :
355 : /**
356 : * Helper function that checks if \p file_name exists.
357 : */
358 : static void assert_file_exists(const std::string & file_name);
359 :
360 : private:
361 :
362 : /**
363 : * A pointer to to the object that stores the theta expansion.
364 : * This is not a std::unique_ptr since we may want to share it.
365 : *
366 : * \note A \p shared_ptr would be a good option here.
367 : */
368 : RBThetaExpansion * rb_theta_expansion;
369 :
370 : /**
371 : * For interfaces like rb_solve() and compute_residual_dual_norm() that optinally
372 : * take a vector of "pre-evaluated" theta values, this function checks to make sure
373 : * that, when provided, it is the right size.
374 : */
375 : void check_evaluated_thetas_size(const std::vector<Number> * evaluated_thetas) const;
376 : };
377 :
378 : }
379 :
380 : #endif // LIBMESH_RB_EVALUATION_H
|