libMesh
rb_evaluation.C
Go to the documentation of this file.
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 // rbOOmit includes
21 #include "libmesh/rb_evaluation.h"
22 #include "libmesh/rb_theta_expansion.h"
23 
24 // libMesh includes
25 #include "libmesh/libmesh_common.h"
26 #include "libmesh/libmesh_version.h"
27 #include "libmesh/system.h"
28 #include "libmesh/numeric_vector.h"
29 #include "libmesh/libmesh_logging.h"
30 #include "libmesh/xdr_cxx.h"
31 #include "libmesh/mesh_tools.h"
32 #include "libmesh/utility.h"
33 
34 // TIMPI includes
35 #include "timpi/communicator.h"
36 
37 // C/C++ includes
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <errno.h>
41 #include <fstream>
42 #include <sstream>
43 #include <iomanip>
44 
45 namespace libMesh
46 {
47 
49  :
50  ParallelObject(comm_in),
51  evaluate_RB_error_bound(true),
52  compute_RB_inner_product(false),
53  rb_theta_expansion(nullptr)
54 {
55 }
56 
57 RBEvaluation::~RBEvaluation() = default;
58 
60 {
61  LOG_SCOPE("clear()", "RBEvaluation");
62 
63  // Clear the basis functions
64  basis_functions.clear();
66 
68 
69  // Clear the Greedy param list
70  for (auto & plist : greedy_param_list)
71  plist.clear();
72  greedy_param_list.clear();
73 }
74 
75 void RBEvaluation::set_n_basis_functions(unsigned int n_bfs)
76 {
77  basis_functions.resize(n_bfs);
78 }
79 
81 {
82  rb_theta_expansion = &rb_theta_expansion_in;
83 }
84 
86 {
87  libmesh_error_msg_if(!is_rb_theta_expansion_initialized(),
88  "Error: rb_theta_expansion hasn't been initialized yet");
89 
90  return *rb_theta_expansion;
91 }
92 
94 {
95  libmesh_error_msg_if(!is_rb_theta_expansion_initialized(),
96  "Error: rb_theta_expansion hasn't been initialized yet");
97 
98  return *rb_theta_expansion;
99 }
100 
102 {
103  if (rb_theta_expansion)
104  {
105  return true;
106  }
107  else
108  {
109  return false;
110  }
111 }
112 
113 void RBEvaluation::resize_data_structures(const unsigned int Nmax,
114  bool resize_error_bound_data)
115 {
116  LOG_SCOPE("resize_data_structures()", "RBEvaluation");
117 
118  libmesh_error_msg_if(Nmax < this->get_n_basis_functions(),
119  "Error: Cannot set Nmax to be less than the current number of basis functions.");
120 
121  // Resize/clear inner product matrix
123  RB_inner_product_matrix.resize(Nmax,Nmax);
124 
125  // Allocate dense matrices for RB solves
127 
128  for (unsigned int q=0; q<rb_theta_expansion->get_n_A_terms(); q++)
129  {
130  // Initialize the memory for the RB matrices
131  RB_Aq_vector[q].resize(Nmax,Nmax);
132  }
133 
135 
136  for (unsigned int q=0; q<rb_theta_expansion->get_n_F_terms(); q++)
137  {
138  // Initialize the memory for the RB vectors
139  RB_Fq_vector[q].resize(Nmax);
140  }
141 
142 
143  // Initialize the RB output vectors
145  for (unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
146  {
148  for (unsigned int q_l=0; q_l<rb_theta_expansion->get_n_output_terms(n); q_l++)
149  {
150  RB_output_vectors[n][q_l].resize(Nmax);
151  }
152  }
153 
154  // Initialize vectors storing output data
156 
157 
158  if (resize_error_bound_data)
159  {
160  // Initialize vectors for the norms of the Fq representors
161  unsigned int Q_f_hat = rb_theta_expansion->get_n_F_terms()*(rb_theta_expansion->get_n_F_terms()+1)/2;
162  Fq_representor_innerprods.resize(Q_f_hat);
163 
164  // Initialize vectors for the norms of the representors
166  for (unsigned int i=0; i<rb_theta_expansion->get_n_F_terms(); i++)
167  {
169  for (unsigned int j=0; j<rb_theta_expansion->get_n_A_terms(); j++)
170  {
171  Fq_Aq_representor_innerprods[i][j].resize(Nmax, 0.);
172  }
173  }
174 
175  unsigned int Q_a_hat = rb_theta_expansion->get_n_A_terms()*(rb_theta_expansion->get_n_A_terms()+1)/2;
176  Aq_Aq_representor_innerprods.resize(Q_a_hat);
177  for (unsigned int i=0; i<Q_a_hat; i++)
178  {
179  Aq_Aq_representor_innerprods[i].resize(Nmax);
180  for (unsigned int j=0; j<Nmax; j++)
181  {
182  Aq_Aq_representor_innerprods[i][j].resize(Nmax, 0.);
183  }
184  }
185 
187 
188  // Resize the output dual norm vectors
190  for (unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
191  {
192  unsigned int Q_l_hat = rb_theta_expansion->get_n_output_terms(n)*(rb_theta_expansion->get_n_output_terms(n)+1)/2;
193  output_dual_innerprods[n].resize(Q_l_hat);
194  }
195 
196  // Clear and resize the vector of Aq_representors
198 
200  for (unsigned int q_a=0; q_a<rb_theta_expansion->get_n_A_terms(); q_a++)
201  {
202  Aq_representor[q_a].resize(Nmax);
203  }
204  }
205 }
206 
208 {
209  libmesh_assert_less (i, basis_functions.size());
210 
211  return *(basis_functions[i]);
212 }
213 
215 {
216  libmesh_assert_less (i, basis_functions.size());
217 
218  return *(basis_functions[i]);
219 }
220 
222 {
223  return rb_solve(N, nullptr);
224 }
225 
227  const std::vector<Number> * evaluated_thetas)
228 {
229  LOG_SCOPE("rb_solve()", "RBEvaluation");
230 
231  libmesh_error_msg_if(N > get_n_basis_functions(),
232  "ERROR: N cannot be larger than the number of basis functions in rb_solve");
233 
234  // In case the theta functions have been pre-evaluated, first check the size for consistency. The
235  // size of the input "evaluated_thetas" vector must match the sum of the "A", "F", and "output" terms
236  // in the expansion.
237  this->check_evaluated_thetas_size(evaluated_thetas);
238 
239  const RBParameters & mu = get_parameters();
240 
241  // Resize (and clear) the solution vector
242  RB_solution.resize(N);
243 
244  // Assemble the RB system
245  DenseMatrix<Number> RB_system_matrix(N,N);
246  RB_system_matrix.zero();
247 
248  DenseMatrix<Number> RB_Aq_a;
249  for (unsigned int q_a=0; q_a<rb_theta_expansion->get_n_A_terms(); q_a++)
250  {
251  RB_Aq_vector[q_a].get_principal_submatrix(N, RB_Aq_a);
252 
253  if (evaluated_thetas)
254  RB_system_matrix.add((*evaluated_thetas)[q_a], RB_Aq_a);
255  else
256  RB_system_matrix.add(rb_theta_expansion->eval_A_theta(q_a, mu), RB_Aq_a);
257  }
258 
259  // Assemble the RB rhs
260  DenseVector<Number> RB_rhs(N);
261  RB_rhs.zero();
262 
263  DenseVector<Number> RB_Fq_f;
264  for (unsigned int q_f=0; q_f<rb_theta_expansion->get_n_F_terms(); q_f++)
265  {
266  RB_Fq_vector[q_f].get_principal_subvector(N, RB_Fq_f);
267 
268  if (evaluated_thetas)
269  RB_rhs.add((*evaluated_thetas)[q_f+rb_theta_expansion->get_n_A_terms()], RB_Fq_f);
270  else
271  RB_rhs.add(rb_theta_expansion->eval_F_theta(q_f, mu), RB_Fq_f);
272  }
273 
274  // Solve the linear system
275  if (N > 0)
276  {
277  RB_system_matrix.lu_solve(RB_rhs, RB_solution);
278  }
279 
280  // Place to store the output of get_principal_subvector() calls
281  DenseVector<Number> RB_output_vector_N;
282 
283  // Evaluate RB outputs
284  unsigned int output_counter = 0;
285  for (unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
286  {
287  RB_outputs[n] = 0.;
288  for (unsigned int q_l=0; q_l<rb_theta_expansion->get_n_output_terms(n); q_l++)
289  {
290  RB_output_vectors[n][q_l].get_principal_subvector(N, RB_output_vector_N);
291 
292  // Compute dot product with current output vector and RB_solution
293  auto dot_prod = RB_output_vector_N.dot(RB_solution);
294 
295  // Determine the coefficient depending on whether or not
296  // pre-evaluated thetas were provided. Note that if
297  // pre-evaluated thetas were provided, they must come after
298  // the "A" and "F" thetas and be in "row-major" order. In
299  // other words, there is a possibly "ragged" 2D array of
300  // output thetas ordered by output index "n" and term index
301  // "q_l" which is accessed in row-major order.
302  auto coeff = evaluated_thetas ?
303  (*evaluated_thetas)[output_counter + rb_theta_expansion->get_n_A_terms() + rb_theta_expansion->get_n_F_terms()] :
305 
306  // Finally, accumulate the result in RB_outputs[n]
307  RB_outputs[n] += coeff * dot_prod;
308 
309  // Go to next output
310  output_counter++;
311  }
312  }
313 
314  if (evaluate_RB_error_bound) // Calculate the error bounds
315  {
316  // Evaluate the dual norm of the residual for RB_solution_vector
317  Real epsilon_N = compute_residual_dual_norm(N, evaluated_thetas);
318 
319  // Get lower bound for coercivity constant
320  const Real alpha_LB = get_stability_lower_bound();
321  // alpha_LB needs to be positive to get a valid error bound
322  libmesh_assert_greater ( alpha_LB, 0. );
323 
324  // Evaluate the (absolute) error bound
325  Real abs_error_bound = epsilon_N / residual_scaling_denom(alpha_LB);
326 
327  // Now compute the output error bounds
328  for (unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
329  RB_output_error_bounds[n] = abs_error_bound * this->eval_output_dual_norm(n, evaluated_thetas);
330 
331  return abs_error_bound;
332  }
333  else // Don't calculate the error bounds
334  {
335  // Just return -1. if we did not compute the error bound
336  return -1.;
337  }
338 }
339 
341 {
342  // Normalize the error based on the error bound in the
343  // case of an empty reduced basis. The error bound is based
344  // on the residual F - AU, so with an empty basis this gives
345  // a value based on the norm of F at the current parameters.
346 
347  Real normalization = rb_solve(0);
348  return normalization;
349 }
350 
352 {
353  return compute_residual_dual_norm(N, nullptr);
354 }
355 
357  const std::vector<Number> * evaluated_thetas)
358 {
359  LOG_SCOPE("compute_residual_dual_norm()", "RBEvaluation");
360 
361  // In case the theta functions have been pre-evaluated, first check the size for consistency
362  this->check_evaluated_thetas_size(evaluated_thetas);
363 
364  // If evaluated_thetas is provided, then mu is not actually used for anything
365  const RBParameters & mu = get_parameters();
366 
367  const unsigned int n_A_terms = rb_theta_expansion->get_n_A_terms();
368  const unsigned int n_F_terms = rb_theta_expansion->get_n_F_terms();
369 
370  // Use the stored representor inner product values
371  // to evaluate the residual norm
372  Number residual_norm_sq = 0.;
373 
374  // Lambdas to help with evaluating F_theta and A_theta functions
375  // using either the pre-evaluated thetas (if provided) or by calling
376  // eval_{F,A}_theta()
377  auto eval_F = [&](unsigned int index)
378  {
379  return (evaluated_thetas) ? (*evaluated_thetas)[index + n_A_terms] : rb_theta_expansion->eval_F_theta(index, mu);
380  };
381  auto eval_A = [&](unsigned int index)
382  {
383  return (evaluated_thetas) ? (*evaluated_thetas)[index] : rb_theta_expansion->eval_A_theta(index, mu);
384  };
385 
386  unsigned int q=0;
387  for (unsigned int q_f1=0; q_f1<n_F_terms; q_f1++)
388  {
389  const Number val_q_f1 = eval_F(q_f1);
390 
391  for (unsigned int q_f2=q_f1; q_f2<n_F_terms; q_f2++)
392  {
393  const Number val_q_f2 = eval_F(q_f2);
394 
395  Real delta = (q_f1==q_f2) ? 1. : 2.;
396  residual_norm_sq += delta * libmesh_real(val_q_f1 * libmesh_conj(val_q_f2) * Fq_representor_innerprods[q] );
397 
398  q++;
399  }
400  }
401 
402  for (unsigned int q_f=0; q_f<n_F_terms; q_f++)
403  {
404  const Number val_q_f = eval_F(q_f);
405 
406  for (unsigned int q_a=0; q_a<n_A_terms; q_a++)
407  {
408  const Number val_q_a = eval_A(q_a);
409 
410  for (unsigned int i=0; i<N; i++)
411  {
412  Real delta = 2.;
413  residual_norm_sq +=
414  delta * libmesh_real( val_q_f * libmesh_conj(val_q_a) *
416  }
417  }
418  }
419 
420  q=0;
421  for (unsigned int q_a1=0; q_a1<n_A_terms; q_a1++)
422  {
423  const Number val_q_a1 = eval_A(q_a1);
424 
425  for (unsigned int q_a2=q_a1; q_a2<n_A_terms; q_a2++)
426  {
427  const Number val_q_a2 = eval_A(q_a2);
428 
429  Real delta = (q_a1==q_a2) ? 1. : 2.;
430 
431  for (unsigned int i=0; i<N; i++)
432  {
433  for (unsigned int j=0; j<N; j++)
434  {
435  residual_norm_sq +=
436  delta * libmesh_real( libmesh_conj(val_q_a1) * val_q_a2 *
438  }
439  }
440 
441  q++;
442  }
443  }
444 
445  if (libmesh_real(residual_norm_sq) < 0.)
446  {
447  // libMesh::out << "Warning: Square of residual norm is negative "
448  // << "in RBSystem::compute_residual_dual_norm()" << std::endl;
449 
450  // Sometimes this is negative due to rounding error,
451  // but when this occurs the error is on the order of 1.e-10,
452  // so shouldn't affect error bound much...
453  residual_norm_sq = std::abs(residual_norm_sq);
454  }
455 
456  return std::sqrt( libmesh_real(residual_norm_sq) );
457 }
458 
460 {
461  // Return a default value of 1, this function should
462  // be overloaded to specify a problem-dependent stability
463  // factor lower bound
464  return 1.;
465 }
466 
468 {
469  // Here we implement the residual scaling for a coercive
470  // problem.
471  return alpha_LB;
472 }
473 
475  const std::vector<Number> * evaluated_thetas)
476 {
477  // Return value
478  Number output_bound_sq = 0.;
479 
480  // mu is only used if evaluated_thetas == nullptr
481  const RBParameters & mu = this->get_parameters();
482 
483  // Index into output_dual_innerprods
484  unsigned int q=0;
485  for (unsigned int q_l1=0; q_l1<rb_theta_expansion->get_n_output_terms(n); q_l1++)
486  {
487  for (unsigned int q_l2=q_l1; q_l2<rb_theta_expansion->get_n_output_terms(n); q_l2++)
488  {
489  Real delta = (q_l1==q_l2) ? 1. : 2.;
490 
491  Number val_l1 =
492  evaluated_thetas ?
495 
496  Number val_l2 =
497  evaluated_thetas ?
500 
501  output_bound_sq += delta * libmesh_real(
502  libmesh_conj(val_l1) * val_l2 * output_dual_innerprods[n][q]);
503 
504  q++;
505  }
506  }
507 
508  return libmesh_real(std::sqrt( output_bound_sq ));
509 }
510 
512 {
513  Aq_representor.clear();
514 }
515 
516 void RBEvaluation::legacy_write_offline_data_to_files(const std::string & directory_name,
517  const bool write_binary_data)
518 {
519  LOG_SCOPE("legacy_write_offline_data_to_files()", "RBEvaluation");
520 
521  // Get the number of basis functions
522  unsigned int n_bfs = get_n_basis_functions();
523 
524  // The writing mode: ENCODE for binary, WRITE for ASCII
525  XdrMODE mode = write_binary_data ? ENCODE : WRITE;
526 
527  // The suffix to use for all the files that are written out
528  const std::string suffix = write_binary_data ? ".xdr" : ".dat";
529 
530  if (this->processor_id() == 0)
531  {
532 
533  // Make a directory to store all the data files
534  Utility::mkdir(directory_name.c_str());
535  // if (mkdir(directory_name.c_str(), 0777) == -1)
536  // {
537  // libMesh::out << "In RBEvaluation::write_offline_data_to_files, directory "
538  // << directory_name << " already exists, overwriting contents." << std::endl;
539  // }
540 
541  // First, write out how many basis functions we have generated
542  std::ostringstream file_name;
543  {
544  file_name << directory_name << "/n_bfs" << suffix;
545  Xdr n_bfs_out(file_name.str(), mode);
546  n_bfs_out << n_bfs;
547  n_bfs_out.close();
548  }
549 
550  // Write out the parameter ranges
551  file_name.str("");
552  file_name << directory_name << "/parameter_ranges" << suffix;
553  std::string continuous_param_file_name = file_name.str();
554 
555  // Write out the discrete parameter values
556  file_name.str("");
557  file_name << directory_name << "/discrete_parameter_values" << suffix;
558  std::string discrete_param_file_name = file_name.str();
559 
560  write_parameter_data_to_files(continuous_param_file_name,
561  discrete_param_file_name,
562  write_binary_data);
563 
564  // Write out Fq representor norm data
565  file_name.str("");
566  file_name << directory_name << "/Fq_innerprods" << suffix;
567  Xdr RB_Fq_innerprods_out(file_name.str(), mode);
568  unsigned int Q_f_hat = rb_theta_expansion->get_n_F_terms()*(rb_theta_expansion->get_n_F_terms()+1)/2;
569  for (unsigned int i=0; i<Q_f_hat; i++)
570  {
571  RB_Fq_innerprods_out << Fq_representor_innerprods[i];
572  }
573  RB_Fq_innerprods_out.close();
574 
575  // Write out output data
576  for (unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
577  {
578  file_name.str("");
579  file_name << directory_name << "/output_";
580  file_name << std::setw(3)
581  << std::setprecision(0)
582  << std::setfill('0')
583  << std::right
584  << n;
585 
586  file_name << "_dual_innerprods" << suffix;
587  Xdr output_dual_innerprods_out(file_name.str(), mode);
588 
589  unsigned int Q_l_hat = rb_theta_expansion->get_n_output_terms(n)*(rb_theta_expansion->get_n_output_terms(n)+1)/2;
590  for (unsigned int q=0; q<Q_l_hat; q++)
591  {
592  output_dual_innerprods_out << output_dual_innerprods[n][q];
593  }
594  output_dual_innerprods_out.close();
595  }
596 
597 
598  // Write out output data to multiple files
599  for (unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
600  {
601  for (unsigned int q_l=0; q_l<rb_theta_expansion->get_n_output_terms(n); q_l++)
602  {
603  file_name.str("");
604  file_name << directory_name << "/output_";
605  file_name << std::setw(3)
606  << std::setprecision(0)
607  << std::setfill('0')
608  << std::right
609  << n;
610  file_name << "_";
611  file_name << std::setw(3)
612  << std::setprecision(0)
613  << std::setfill('0')
614  << std::right
615  << q_l;
616  file_name << suffix;
617  Xdr output_n_out(file_name.str(), mode);
618 
619  for (unsigned int j=0; j<n_bfs; j++)
620  {
621  output_n_out << RB_output_vectors[n][q_l](j);
622  }
623  output_n_out.close();
624  }
625  }
626 
628  {
629  // Next write out the inner product matrix
630  file_name.str("");
631  file_name << directory_name << "/RB_inner_product_matrix" << suffix;
632  Xdr RB_inner_product_matrix_out(file_name.str(), mode);
633  for (unsigned int i=0; i<n_bfs; i++)
634  {
635  for (unsigned int j=0; j<n_bfs; j++)
636  {
637  RB_inner_product_matrix_out << RB_inner_product_matrix(i,j);
638  }
639  }
640  RB_inner_product_matrix_out.close();
641  }
642 
643  // Next write out the Fq vectors
644  for (unsigned int q_f=0; q_f<rb_theta_expansion->get_n_F_terms(); q_f++)
645  {
646  file_name.str("");
647  file_name << directory_name << "/RB_F_";
648  file_name << std::setw(3)
649  << std::setprecision(0)
650  << std::setfill('0')
651  << std::right
652  << q_f;
653  file_name << suffix;
654  Xdr RB_Fq_f_out(file_name.str(), mode);
655 
656  for (unsigned int i=0; i<n_bfs; i++)
657  {
658  RB_Fq_f_out << RB_Fq_vector[q_f](i);
659  }
660  RB_Fq_f_out.close();
661  }
662 
663  // Next write out the Aq matrices
664  for (unsigned int q_a=0; q_a<rb_theta_expansion->get_n_A_terms(); q_a++)
665  {
666  file_name.str("");
667  file_name << directory_name << "/RB_A_";
668  file_name << std::setw(3)
669  << std::setprecision(0)
670  << std::setfill('0')
671  << std::right
672  << q_a;
673  file_name << suffix;
674  Xdr RB_Aq_a_out(file_name.str(), mode);
675 
676  for (unsigned int i=0; i<n_bfs; i++)
677  {
678  for (unsigned int j=0; j<n_bfs; j++)
679  {
680  RB_Aq_a_out << RB_Aq_vector[q_a](i,j);
681  }
682  }
683  RB_Aq_a_out.close();
684  }
685 
686  // Next write out Fq_Aq representor norm data
687  file_name.str("");
688  file_name << directory_name << "/Fq_Aq_innerprods" << suffix;
689  Xdr RB_Fq_Aq_innerprods_out(file_name.str(), mode);
690 
691  for (unsigned int q_f=0; q_f<rb_theta_expansion->get_n_F_terms(); q_f++)
692  {
693  for (unsigned int q_a=0; q_a<rb_theta_expansion->get_n_A_terms(); q_a++)
694  {
695  for (unsigned int i=0; i<n_bfs; i++)
696  {
697  RB_Fq_Aq_innerprods_out << Fq_Aq_representor_innerprods[q_f][q_a][i];
698  }
699  }
700  }
701  RB_Fq_Aq_innerprods_out.close();
702 
703  // Next write out Aq_Aq representor norm data
704  file_name.str("");
705  file_name << directory_name << "/Aq_Aq_innerprods" << suffix;
706  Xdr RB_Aq_Aq_innerprods_out(file_name.str(), mode);
707 
708  unsigned int Q_a_hat = rb_theta_expansion->get_n_A_terms()*(rb_theta_expansion->get_n_A_terms()+1)/2;
709  for (unsigned int i=0; i<Q_a_hat; i++)
710  {
711  for (unsigned int j=0; j<n_bfs; j++)
712  {
713  for (unsigned int l=0; l<n_bfs; l++)
714  {
715  RB_Aq_Aq_innerprods_out << Aq_Aq_representor_innerprods[i][j][l];
716  }
717  }
718  }
719  RB_Aq_Aq_innerprods_out.close();
720 
721  // Also, write out the greedily selected parameters
722  {
723  file_name.str("");
724  file_name << directory_name << "/greedy_params" << suffix;
725  Xdr greedy_params_out(file_name.str(), mode);
726 
727  for (const auto & param : greedy_param_list)
728  for (const auto & pr : param)
729  for (const auto & value_vector : pr.second)
730  {
731  // Need to make a copy of the value so that it's not const
732  // Xdr is not templated on const's
733  libmesh_error_msg_if(value_vector.size() != 1,
734  "Error: multi-value RB parameters are not yet supported here.");
735  Real param_value = value_vector[0];
736  greedy_params_out << param_value;
737  }
738  greedy_params_out.close();
739  }
740 
741  }
742 }
743 
744 void RBEvaluation::legacy_read_offline_data_from_files(const std::string & directory_name,
745  bool read_error_bound_data,
746  const bool read_binary_data)
747 {
748  LOG_SCOPE("legacy_read_offline_data_from_files()", "RBEvaluation");
749 
750  // The reading mode: DECODE for binary, READ for ASCII
751  XdrMODE mode = read_binary_data ? DECODE : READ;
752 
753  // The suffix to use for all the files that are written out
754  const std::string suffix = read_binary_data ? ".xdr" : ".dat";
755 
756  // The string stream we'll use to make the file names
757  std::ostringstream file_name;
758 
759  // First, find out how many basis functions we had when Greedy terminated
760  unsigned int n_bfs;
761  {
762  file_name << directory_name << "/n_bfs" << suffix;
763  assert_file_exists(file_name.str());
764 
765  Xdr n_bfs_in(file_name.str(), mode);
766  n_bfs_in >> n_bfs;
767  n_bfs_in.close();
768  }
769  resize_data_structures(n_bfs, read_error_bound_data);
770 
771  // Read in the parameter ranges
772  file_name.str("");
773  file_name << directory_name << "/parameter_ranges" << suffix;
774  std::string continuous_param_file_name = file_name.str();
775 
776  // Read in the discrete parameter values
777  file_name.str("");
778  file_name << directory_name << "/discrete_parameter_values" << suffix;
779  std::string discrete_param_file_name = file_name.str();
780  read_parameter_data_from_files(continuous_param_file_name,
781  discrete_param_file_name,
782  read_binary_data);
783 
784  // Read in output data in multiple files
785  for (unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
786  {
787  for (unsigned int q_l=0; q_l<rb_theta_expansion->get_n_output_terms(n); q_l++)
788  {
789  file_name.str("");
790  file_name << directory_name << "/output_";
791  file_name << std::setw(3)
792  << std::setprecision(0)
793  << std::setfill('0')
794  << std::right
795  << n;
796  file_name << "_";
797  file_name << std::setw(3)
798  << std::setprecision(0)
799  << std::setfill('0')
800  << std::right
801  << q_l;
802  file_name << suffix;
803  assert_file_exists(file_name.str());
804 
805  Xdr output_n_in(file_name.str(), mode);
806 
807  for (unsigned int j=0; j<n_bfs; j++)
808  {
809  Number value;
810  output_n_in >> value;
811  RB_output_vectors[n][q_l](j) = value;
812  }
813  output_n_in.close();
814  }
815  }
816 
818  {
819  // Next read in the inner product matrix
820  file_name.str("");
821  file_name << directory_name << "/RB_inner_product_matrix" << suffix;
822  assert_file_exists(file_name.str());
823 
824  Xdr RB_inner_product_matrix_in(file_name.str(), mode);
825 
826  for (unsigned int i=0; i<n_bfs; i++)
827  {
828  for (unsigned int j=0; j<n_bfs; j++)
829  {
830  Number value;
831  RB_inner_product_matrix_in >> value;
833  }
834  }
835  RB_inner_product_matrix_in.close();
836  }
837 
838  // Next read in the Fq vectors
839  for (unsigned int q_f=0; q_f<rb_theta_expansion->get_n_F_terms(); q_f++)
840  {
841  file_name.str("");
842  file_name << directory_name << "/RB_F_";
843  file_name << std::setw(3)
844  << std::setprecision(0)
845  << std::setfill('0')
846  << std::right
847  << q_f;
848  file_name << suffix;
849  assert_file_exists(file_name.str());
850 
851  Xdr RB_Fq_f_in(file_name.str(), mode);
852 
853  for (unsigned int i=0; i<n_bfs; i++)
854  {
855  Number value;
856  RB_Fq_f_in >> value;
857  RB_Fq_vector[q_f](i) = value;
858  }
859  RB_Fq_f_in.close();
860  }
861 
862  // Next read in the Aq matrices
863  for (unsigned int q_a=0; q_a<rb_theta_expansion->get_n_A_terms(); q_a++)
864  {
865  file_name.str("");
866  file_name << directory_name << "/RB_A_";
867  file_name << std::setw(3)
868  << std::setprecision(0)
869  << std::setfill('0')
870  << std::right
871  << q_a;
872  file_name << suffix;
873  assert_file_exists(file_name.str());
874 
875  Xdr RB_Aq_a_in(file_name.str(), mode);
876 
877  for (unsigned int i=0; i<n_bfs; i++)
878  {
879  for (unsigned int j=0; j<n_bfs; j++)
880  {
881  Number value;
882  RB_Aq_a_in >> value;
883  RB_Aq_vector[q_a](i,j) = value;
884  }
885  }
886  RB_Aq_a_in.close();
887  }
888 
889 
890  if (read_error_bound_data)
891  {
892  // Next read in Fq representor norm data
893  file_name.str("");
894  file_name << directory_name << "/Fq_innerprods" << suffix;
895  assert_file_exists(file_name.str());
896 
897  Xdr RB_Fq_innerprods_in(file_name.str(), mode);
898 
899  unsigned int Q_f_hat = rb_theta_expansion->get_n_F_terms()*(rb_theta_expansion->get_n_F_terms()+1)/2;
900  for (unsigned int i=0; i<Q_f_hat; i++)
901  {
902  RB_Fq_innerprods_in >> Fq_representor_innerprods[i];
903  }
904  RB_Fq_innerprods_in.close();
905 
906  // Read in output data
907  for (unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
908  {
909  file_name.str("");
910  file_name << directory_name << "/output_";
911  file_name << std::setw(3)
912  << std::setprecision(0)
913  << std::setfill('0')
914  << std::right
915  << n;
916  file_name << "_dual_innerprods" << suffix;
917  assert_file_exists(file_name.str());
918 
919  Xdr output_dual_innerprods_in(file_name.str(), mode);
920 
921  unsigned int Q_l_hat = rb_theta_expansion->get_n_output_terms(n)*(rb_theta_expansion->get_n_output_terms(n)+1)/2;
922  for (unsigned int q=0; q<Q_l_hat; q++)
923  {
924  output_dual_innerprods_in >> output_dual_innerprods[n][q];
925  }
926  output_dual_innerprods_in.close();
927  }
928 
929 
930  // Next read in Fq_Aq representor norm data
931  file_name.str("");
932  file_name << directory_name << "/Fq_Aq_innerprods" << suffix;
933  assert_file_exists(file_name.str());
934 
935  Xdr RB_Fq_Aq_innerprods_in(file_name.str(), mode);
936 
937  for (unsigned int q_f=0; q_f<rb_theta_expansion->get_n_F_terms(); q_f++)
938  {
939  for (unsigned int q_a=0; q_a<rb_theta_expansion->get_n_A_terms(); q_a++)
940  {
941  for (unsigned int i=0; i<n_bfs; i++)
942  {
943  RB_Fq_Aq_innerprods_in >> Fq_Aq_representor_innerprods[q_f][q_a][i];
944  }
945  }
946  }
947  RB_Fq_Aq_innerprods_in.close();
948 
949  // Next read in Aq_Aq representor norm data
950  file_name.str("");
951  file_name << directory_name << "/Aq_Aq_innerprods" << suffix;
952  assert_file_exists(file_name.str());
953 
954  Xdr RB_Aq_Aq_innerprods_in(file_name.str(), mode);
955 
956  unsigned int Q_a_hat = rb_theta_expansion->get_n_A_terms()*(rb_theta_expansion->get_n_A_terms()+1)/2;
957  for (unsigned int i=0; i<Q_a_hat; i++)
958  {
959  for (unsigned int j=0; j<n_bfs; j++)
960  {
961  for (unsigned int l=0; l<n_bfs; l++)
962  {
963  RB_Aq_Aq_innerprods_in >> Aq_Aq_representor_innerprods[i][j][l];
964  }
965  }
966  }
967  RB_Aq_Aq_innerprods_in.close();
968  }
969 
970  // Resize basis_functions even if we don't read them in so that
971  // get_n_bfs() returns the correct value. Initialize the pointers
972  // to nullptr.
973  basis_functions.clear();
974  set_n_basis_functions(n_bfs);
975 }
976 
977 void RBEvaluation::assert_file_exists(const std::string & file_name)
978 {
979  libmesh_error_msg_if(!std::ifstream(file_name.c_str()), "File missing: " << file_name);
980 }
981 
983  const std::string & directory_name,
984  const bool write_binary_basis_functions)
985 {
986  LOG_SCOPE("write_out_basis_functions()", "RBEvaluation");
987 
988  std::vector<NumericVector<Number>*> basis_functions_ptrs;
989  for (std::size_t i=0; i<basis_functions.size(); i++)
990  {
991  basis_functions_ptrs.push_back(basis_functions[i].get());
992  }
993 
994  write_out_vectors(sys,
995  basis_functions_ptrs,
996  directory_name,
997  "bf",
998  write_binary_basis_functions);
999 }
1000 
1002  std::vector<NumericVector<Number>*> & vectors,
1003  const std::string & directory_name,
1004  const std::string & data_name,
1005  const bool write_binary_vectors)
1006 {
1007  LOG_SCOPE("write_out_vectors()", "RBEvaluation");
1008 
1009  if (sys.comm().rank() == 0)
1010  {
1011  // Make a directory to store all the data files
1012  Utility::mkdir(directory_name.c_str());
1013  }
1014 
1015  // Make sure processors are synced up before we begin
1016  sys.comm().barrier();
1017 
1018  std::ostringstream file_name;
1019  const std::string basis_function_suffix = (write_binary_vectors ? ".xdr" : ".dat");
1020 
1021  file_name << directory_name << "/" << data_name << "_data" << basis_function_suffix;
1022  Xdr bf_data(file_name.str(),
1023  write_binary_vectors ? ENCODE : WRITE);
1024 
1025  // Following EquationSystems::write(), we should only write the header information
1026  // if we're proc 0
1027  if (sys.comm().rank() == 0)
1028  {
1029  std::string version("libMesh-" + libMesh::get_io_compatibility_version());
1030 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1031  version += " with infinite elements";
1032 #endif
1033  bf_data.data(version ,"# File Format Identifier");
1034 
1035  sys.write_header(bf_data, /*(unused arg)*/ version, /*write_additional_data=*/false);
1036  }
1037 
1038  // Following EquationSystemsIO::write, we use a temporary numbering (node major)
1039  // before writing out the data
1041 
1042  // Write all vectors at once.
1043  {
1044  // Note the API wants pointers to constant vectors, hence this...
1045  std::vector<const NumericVector<Number> *> bf_out;
1046  for (const auto & vec : vectors)
1047  bf_out.push_back(vec);
1048 
1049  // for (auto & val : vectors)
1050  // bf_out.push_back(val);
1051  sys.write_serialized_vectors (bf_data, bf_out);
1052  }
1053 
1054 
1055  // set the current version
1056  bf_data.set_version(LIBMESH_VERSION_ID(LIBMESH_MAJOR_VERSION,
1057  LIBMESH_MINOR_VERSION,
1058  LIBMESH_MICRO_VERSION));
1059 
1060 
1061  // Undo the temporary renumbering
1063 }
1064 
1066  const std::string & directory_name,
1067  const bool read_binary_basis_functions)
1068 {
1069  LOG_SCOPE("read_in_basis_functions()", "RBEvaluation");
1070 
1071  read_in_vectors(sys,
1073  directory_name,
1074  "bf",
1075  read_binary_basis_functions);
1076 }
1077 
1079  std::vector<std::unique_ptr<NumericVector<Number>>> & vectors,
1080  const std::string & directory_name,
1081  const std::string & data_name,
1082  const bool read_binary_vectors)
1083 {
1084  std::vector<std::vector<std::unique_ptr<NumericVector<Number>>> *> vectors_vec;
1085  vectors_vec.push_back(&vectors);
1086 
1087  std::vector<std::string> directory_name_vec;
1088  directory_name_vec.push_back(directory_name);
1089 
1090  std::vector<std::string> data_name_vec;
1091  data_name_vec.push_back(data_name);
1092 
1094  vectors_vec,
1095  directory_name_vec,
1096  data_name_vec,
1097  read_binary_vectors);
1098 }
1099 
1101  std::vector<std::vector<std::unique_ptr<NumericVector<Number>>> *> multiple_vectors,
1102  const std::vector<std::string> & multiple_directory_names,
1103  const std::vector<std::string> & multiple_data_names,
1104  const bool read_binary_vectors)
1105 {
1106  LOG_SCOPE("read_in_vectors_from_multiple_files()", "RBEvaluation");
1107 
1108  std::size_t n_files = multiple_vectors.size();
1109  std::size_t n_directories = multiple_directory_names.size();
1110  libmesh_assert((n_files == n_directories) && (n_files == multiple_data_names.size()));
1111 
1112  if (n_files == 0)
1113  return;
1114 
1115  // Make sure processors are synced up before we begin
1116  sys.comm().barrier();
1117 
1118  std::ostringstream file_name;
1119  const std::string basis_function_suffix = (read_binary_vectors ? ".xdr" : ".dat");
1120 
1121  // Following EquationSystemsIO::read, we use a temporary numbering (node major)
1122  // before writing out the data. For the sake of efficiency, we do this once for
1123  // all the vectors that we read in.
1125 
1126  for (std::size_t data_index=0; data_index<n_directories; data_index++)
1127  {
1128  std::vector<std::unique_ptr<NumericVector<Number>>> & vectors = *multiple_vectors[data_index];
1129 
1130  // Allocate storage for each vector
1131  for (auto & vec : vectors)
1132  {
1133  // vectors should all be nullptr, otherwise we get a memory leak when
1134  // we create the new vectors in RBEvaluation::read_in_vectors.
1135  libmesh_error_msg_if(vec, "Non-nullptr vector passed to read_in_vectors_from_multiple_files");
1136 
1137  vec = NumericVector<Number>::build(sys.comm());
1138 
1139  vec->init (sys.n_dofs(),
1140  sys.n_local_dofs(),
1141  false,
1142  PARALLEL);
1143  }
1144 
1145  file_name.str("");
1146  file_name << multiple_directory_names[data_index]
1147  << "/" << multiple_data_names[data_index]
1148  << "_data" << basis_function_suffix;
1149 
1150  // On processor zero check to be sure the file exists
1151  if (sys.comm().rank() == 0)
1152  {
1153  struct stat stat_info;
1154  int stat_result = stat(file_name.str().c_str(), &stat_info);
1155 
1156  libmesh_error_msg_if(stat_result != 0, "File does not exist: " << file_name.str());
1157  }
1158 
1159  assert_file_exists(file_name.str());
1160  Xdr vector_data(file_name.str(),
1161  read_binary_vectors ? DECODE : READ);
1162 
1163  // Read the header data. This block of code is based on EquationSystems::_read_impl.
1164  {
1165  std::string version;
1166  vector_data.data(version);
1167 
1168  const std::string libMesh_label = "libMesh-";
1169  std::string::size_type lm_pos = version.find(libMesh_label);
1170  libmesh_error_msg_if(lm_pos == std::string::npos, "version info missing in Xdr header");
1171 
1172  std::istringstream iss(version.substr(lm_pos + libMesh_label.size()));
1173  int ver_major = 0, ver_minor = 0, ver_patch = 0;
1174  char dot;
1175  iss >> ver_major >> dot >> ver_minor >> dot >> ver_patch;
1176  vector_data.set_version(LIBMESH_VERSION_ID(ver_major, ver_minor, ver_patch));
1177 
1178  // Actually read the header data. When we do this, set read_header=false
1179  // so that we do not reinit sys, since we assume that it has already been
1180  // set up properly (e.g. the appropriate variables have already been added).
1181  sys.read_header(vector_data, version, /*read_header=*/false, /*read_additional_data=*/false);
1182  }
1183 
1184  // Comply with the System::read_serialized_vectors() interface which uses dumb pointers.
1185  std::vector<NumericVector<Number> *> vec_in;
1186  for (auto & vec : vectors)
1187  vec_in.push_back(vec.get());
1188 
1189  sys.read_serialized_vectors (vector_data, vec_in);
1190  }
1191 
1192  // Undo the temporary renumbering
1194 }
1195 
1196 void RBEvaluation::check_evaluated_thetas_size(const std::vector<Number> * evaluated_thetas) const
1197 {
1198  if (rb_theta_expansion && evaluated_thetas)
1199  {
1200  auto actual_size = evaluated_thetas->size();
1201  auto expected_size =
1205 
1206  libmesh_error_msg_if(actual_size != expected_size,
1207  "ERROR: Evaluated thetas vector has size " <<
1208  actual_size << ", but we expected " <<
1209  rb_theta_expansion->get_n_A_terms() << " A term(s), " <<
1210  rb_theta_expansion->get_n_F_terms() << " F term(s), and " <<
1211  rb_theta_expansion->get_total_n_output_terms() << " output term(s), " <<
1212  "for a total of " << expected_size << " terms.");
1213  }
1214 }
1215 
1216 } // namespace libMesh
T libmesh_real(T a)
Real eval_output_dual_norm(unsigned int n, const std::vector< Number > *evaluated_thetas)
Evaluate the dual norm of output n for the current parameters, or using the pre-evaluted theta values...
std::vector< std::vector< std::unique_ptr< NumericVector< Number > > > > Aq_representor
Vector storing the residual representors associated with the left-hand side.
bool compute_RB_inner_product
Boolean flag to indicate whether we compute the RB_inner_product_matrix.
virtual Number eval_output_theta(unsigned int output_index, unsigned int q_l, const RBParameters &mu) const
Evaluate theta_q_l at the current parameter.
virtual Number eval_A_theta(unsigned int q, const RBParameters &mu) const
Evaluate theta_q_a at the current parameter.
bool evaluate_RB_error_bound
Boolean to indicate whether we evaluate a posteriori error bounds when rb_solve is called...
virtual void write_out_basis_functions(System &sys, const std::string &directory_name="offline_data", const bool write_binary_basis_functions=true)
Write out all the basis functions to file.
std::vector< Number > Fq_representor_innerprods
Vectors storing the residual representor inner products to be used in computing the residuals online...
virtual void zero() override final
Set every element in the vector to 0.
Definition: dense_vector.h:420
T libmesh_conj(T a)
unsigned int get_n_F_terms() const
Get Q_f, the number of terms in the affine expansion for the right-hand side.
virtual void resize_data_structures(const unsigned int Nmax, bool resize_error_bound_data=true)
Resize and clear the data vectors corresponding to the value of Nmax.
DenseVector< Number > RB_solution
The RB solution vector.
void write_parameter_data_to_files(const std::string &continuous_param_file_name, const std::string &discrete_param_file_name, const bool write_binary_data)
Write out the parameter ranges to files.
void write_header(Xdr &io, std::string_view version, const bool write_additional_data) const
Writes the basic data header for this System.
Definition: system_io.C:1120
virtual void zero() override final
Sets all elements of the matrix to 0 and resets any decomposition flag which may have been previously...
Definition: dense_matrix.h:911
DenseMatrix< Number > RB_inner_product_matrix
The inner product matrix.
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:396
void close()
Closes the file if it is open.
Definition: xdr_cxx.C:278
std::vector< std::unique_ptr< NumericVector< Number > > > basis_functions
The libMesh vectors storing the finite element coefficients of the RB basis functions.
void barrier() const
virtual Real compute_residual_dual_norm(const unsigned int N)
Compute the dual norm of the residual for the solution saved in RB_solution_vector.
processor_id_type rank() const
unsigned int get_n_A_terms() const
Get Q_a, the number of terms in the affine expansion for the bilinear form.
const Parallel::Communicator & comm() const
virtual void fix_broken_node_and_element_numbering()=0
There is no reason for a user to ever call this function.
int mkdir(const char *pathname)
Create a directory.
Definition: utility.C:152
std::vector< std::vector< Number > > output_dual_innerprods
The vector storing the dual norm inner product terms for each output.
virtual Real get_error_bound_normalization()
void read_parameter_data_from_files(const std::string &continuous_param_file_name, const std::string &discrete_param_file_name, const bool read_binary_data)
Read in the parameter ranges from files.
static void read_in_vectors_from_multiple_files(System &sys, std::vector< std::vector< std::unique_ptr< NumericVector< Number >>> *> multiple_vectors, const std::vector< std::string > &multiple_directory_names, const std::vector< std::string > &multiple_data_names, const bool read_binary_vectors)
Performs read_in_vectors for a list of directory names and data names.
The libMesh namespace provides an interface to certain functionality in the library.
dof_id_type n_local_dofs() const
Definition: system.C:155
std::vector< RBParameters > greedy_param_list
The list of parameters selected by the Greedy algorithm in generating the Reduced Basis associated wi...
static void read_in_vectors(System &sys, std::vector< std::unique_ptr< NumericVector< Number >>> &vectors, const std::string &directory_name, const std::string &data_name, const bool read_binary_vectors)
Same as read_in_basis_functions, except in this case we pass in the vectors to be written...
unsigned int output_index_1D(unsigned int n, unsigned int q_l) const
Computes the one-dimensional index for output n, term q_l implied by a "row-major" ordering of the ou...
unsigned int get_n_outputs() const
Get n_outputs, the number output functionals.
const MeshBase & get_mesh() const
Definition: system.h:2401
This class stores the set of RBTheta functor objects that define the "parameter-dependent expansion" ...
dof_id_type n_dofs() const
Definition: system.C:118
RBEvaluation(const Parallel::Communicator &comm)
Constructor.
Definition: rb_evaluation.C:48
XdrMODE
Defines an enum for read/write mode in Xdr format.
Definition: enum_xdr_mode.h:35
void data(T &a, std::string_view comment="")
Inputs or outputs a single value.
Definition: xdr_cxx.C:860
std::vector< DenseVector< Number > > RB_Fq_vector
Dense vector for the RHS.
static void write_out_vectors(System &sys, std::vector< NumericVector< Number > *> &vectors, const std::string &directory_name="offline_data", const std::string &data_name="bf", const bool write_binary_basis_functions=true)
Same as write_out_basis_functions, except in this case we pass in the vectors to be written...
std::string get_io_compatibility_version()
Specifier for I/O file compatibility features.
virtual Real get_stability_lower_bound()
Get a lower bound for the stability constant (e.g.
virtual void legacy_write_offline_data_to_files(const std::string &directory_name="offline_data", const bool write_binary_data=true)
Write out all the data to text files in order to segregate the Offline stage from the Online stage...
void read_header(Xdr &io, std::string_view version, const bool read_header=true, const bool read_additional_data=true, const bool read_legacy_format=false)
Reads the basic data header for this System.
Definition: system_io.C:97
virtual void legacy_read_offline_data_from_files(const std::string &directory_name="offline_data", bool read_error_bound_data=true, const bool read_binary_data=true)
Read in the saved Offline reduced basis data to initialize the system for Online solves.
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:98
NumericVector< Number > & get_basis_function(unsigned int i)
Get a reference to the i^th basis function.
libmesh_assert(ctx)
virtual Number eval_F_theta(unsigned int q, const RBParameters &mu) const
Evaluate theta_q_f at the current parameter.
std::vector< Real > RB_output_error_bounds
const RBParameters & get_parameters() const
Get the current parameters.
virtual void read_in_basis_functions(System &sys, const std::string &directory_name="offline_data", const bool read_binary_basis_functions=true)
Read in all the basis functions from file.
virtual void set_n_basis_functions(unsigned int n_bfs)
Set the number of basis functions.
Definition: rb_evaluation.C:75
This class is part of the rbOOmit framework.
Definition: rb_parameters.h:52
std::size_t read_serialized_vectors(Xdr &io, const std::vector< NumericVector< Number > *> &vectors) const
Read a number of identically distributed vectors.
Definition: system_io.C:2018
void globally_renumber_nodes_and_elements(MeshBase &)
There is no reason for a user to ever call this function.
Definition: mesh_tools.C:2657
An object whose state is distributed along a set of processors.
virtual Real residual_scaling_denom(Real alpha_LB)
Specifies the residual scaling on the denominator to be used in the a posteriori error bound...
void set_rb_theta_expansion(RBThetaExpansion &rb_theta_expansion_in)
Set the RBThetaExpansion object.
Definition: rb_evaluation.C:80
This class implements a C++ interface to the XDR (eXternal Data Representation) format.
Definition: xdr_cxx.h:67
std::enable_if< ScalarTraits< T2 >::value, void >::type add(const T2 factor, const DenseVector< T3 > &vec)
Adds factor times vec to this vector.
Definition: dense_vector.h:477
std::vector< std::vector< std::vector< Number > > > Fq_Aq_representor_innerprods
Vectors storing the residual representor inner products to be used in computing the residuals online...
std::size_t write_serialized_vectors(Xdr &io, const std::vector< const NumericVector< Number > *> &vectors) const
Serialize & write a number of identically distributed vectors.
Definition: system_io.C:2114
virtual Real rb_solve(unsigned int N)
Perform online solve with the N RB basis functions, for the set of parameters in current_params, where 0 <= N <= RB_size.
virtual void clear_riesz_representors()
Clear all the Riesz representors that are used to compute the RB residual (and hence error bound)...
CompareTypes< T, T2 >::supertype dot(const DenseVector< T2 > &vec) const
Definition: dense_vector.h:492
std::vector< DenseMatrix< Number > > RB_Aq_vector
Dense matrices for the RB computations.
void lu_solve(const DenseVector< T > &b, DenseVector< T > &x)
Solve the system Ax=b given the input vector b.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
unsigned int get_n_output_terms(unsigned int output_index) const
Get the number of affine terms associated with the specified output.
unsigned int get_total_n_output_terms() const
Returns the total number of affine terms associated with all outputs.
static void assert_file_exists(const std::string &file_name)
Helper function that checks if file_name exists.
virtual unsigned int get_n_basis_functions() const
Get the current number of basis functions.
virtual void clear() override
Clear this RBEvaluation object.
Definition: rb_evaluation.C:59
static const bool value
Definition: xdr_io.C:55
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Definition: dense_matrix.h:895
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
void check_evaluated_thetas_size(const std::vector< Number > *evaluated_thetas) const
For interfaces like rb_solve() and compute_residual_dual_norm() that optinally take a vector of "pre-...
std::vector< Number > RB_outputs
The vectors storing the RB output values and corresponding error bounds.
processor_id_type processor_id() const
RBThetaExpansion * rb_theta_expansion
A pointer to to the object that stores the theta expansion.
RBThetaExpansion & get_rb_theta_expansion()
Get a reference to the rb_theta_expansion.
Definition: rb_evaluation.C:85
std::enable_if< ScalarTraits< T2 >::value, void >::type add(const T2 factor, const DenseMatrix< T3 > &mat)
Adds factor times mat to this matrix.
std::vector< std::vector< std::vector< Number > > > Aq_Aq_representor_innerprods
bool is_rb_theta_expansion_initialized() const
std::vector< std::vector< DenseVector< Number > > > RB_output_vectors
The vectors storing the RB output vectors.