libMesh
rb_data_deserialization.C
Go to the documentation of this file.
1 // rbOOmit: An implementation of the Certified Reduced Basis method.
2 // Copyright (C) 2009, 2010, 2015 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 #include "libmesh/libmesh_config.h"
21 #if defined(LIBMESH_HAVE_CAPNPROTO)
22 
23 //libMesh includes
24 #include "libmesh/rb_eim_evaluation.h"
25 #include "libmesh/string_to_enum.h"
26 #include "libmesh/elem.h"
27 #include "libmesh/mesh.h"
28 #include "libmesh/rb_data_deserialization.h"
29 #include "libmesh/transient_rb_theta_expansion.h"
30 #include "libmesh/transient_rb_evaluation.h"
31 #include "libmesh/rb_eim_evaluation.h"
32 #include "libmesh/rb_scm_evaluation.h"
33 #include "libmesh/rb_parametrized_function.h"
34 #include "libmesh/libmesh_logging.h"
35 
36 // Cap'n'Proto includes
37 #include "capnp/serialize.h"
38 #include "capnp/serialize-packed.h" // for PackedFdMessageReader()
39 
40 // C++ includes
41 #ifdef LIBMESH_HAVE_UNISTD_H
42 #include <unistd.h> // for close()
43 #endif
44 #include <iostream>
45 #include <fstream>
46 #include <fcntl.h>
47 
48 namespace libMesh
49 {
50 
51 namespace
52 {
53 
58 template <typename T>
59 Number load_scalar_value(const T & value)
60 {
61 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
62  return Number(value.getReal(), value.getImag());
63 #else
64  return value;
65 #endif
66 }
67 
68 }
69 
70 namespace RBDataDeserialization
71 {
72 
73 // ---- RBEvaluationDeserialization (BEGIN) ----
74 
76  :
77  _rb_eval(rb_eval)
78 {}
79 
81 
82 void RBEvaluationDeserialization::read_from_file(const std::string &path,
83  bool read_error_bound_data,
84  bool use_packing)
85 {
86  LOG_SCOPE("read_from_file()", "RBEvaluationDeserialization");
87 
88  int fd = open(path.c_str(), O_RDONLY);
89  libmesh_error_msg_if(!fd, "Couldn't open the buffer file: " + path);
90 
91  // Turn off the limit to the amount of data we can read in
92  capnp::ReaderOptions reader_options;
93  reader_options.traversalLimitInWords = std::numeric_limits<uint64_t>::max();
94 
95  std::unique_ptr<capnp::InputStreamMessageReader> message;
96  libmesh_try
97  {
98  // Define the reader type, based on whether or not packing is used.
99  if(use_packing)
100  message = std::make_unique<capnp::PackedFdMessageReader>(fd, reader_options);
101  else
102  message = std::make_unique<capnp::StreamFdMessageReader>(fd, reader_options);
103  }
104  libmesh_catch(...)
105  {
106  libmesh_error_msg("Failed to open capnp buffer");
107  }
108 
109 #ifndef LIBMESH_USE_COMPLEX_NUMBERS
110  RBData::RBEvaluationReal::Reader rb_eval_reader =
111  message->getRoot<RBData::RBEvaluationReal>();
112 #else
113  RBData::RBEvaluationComplex::Reader rb_eval_reader =
114  message->getRoot<RBData::RBEvaluationComplex>();
115 #endif
116 
117  load_rb_evaluation_data(_rb_eval, rb_eval_reader, read_error_bound_data);
118 
119  int error = close(fd);
120  libmesh_error_msg_if(error, "Error closing a read-only file descriptor: " + path);
121 }
122 
123 // ---- RBEvaluationDeserialization (END) ----
124 
125 
126 // ---- TransientRBEvaluationDeserialization (BEGIN) ----
127 
130  _trans_rb_eval(trans_rb_eval)
131 {}
132 
134 
136  bool read_error_bound_data,
137  bool use_packing)
138 {
139  LOG_SCOPE("read_from_file()", "TransientRBEvaluationDeserialization");
140 
141  int fd = open(path.c_str(), O_RDONLY);
142  libmesh_error_msg_if(!fd, "Couldn't open the buffer file: " + path);
143 
144  // Turn off the limit to the amount of data we can read in
145  capnp::ReaderOptions reader_options;
146  reader_options.traversalLimitInWords = std::numeric_limits<uint64_t>::max();
147 
148  std::unique_ptr<capnp::InputStreamMessageReader> message;
149  libmesh_try
150  {
151  if(use_packing)
152  message = std::make_unique<capnp::PackedFdMessageReader>(fd, reader_options);
153  else
154  message = std::make_unique<capnp::StreamFdMessageReader>(fd, reader_options);
155  }
156  libmesh_catch(...)
157  {
158  libmesh_error_msg("Failed to open capnp buffer");
159  }
160 
161 #ifndef LIBMESH_USE_COMPLEX_NUMBERS
162  RBData::TransientRBEvaluationReal::Reader trans_rb_eval_reader =
163  message->getRoot<RBData::TransientRBEvaluationReal>();
164  RBData::RBEvaluationReal::Reader rb_eval_reader =
165  trans_rb_eval_reader.getRbEvaluation();
166 #else
167  RBData::TransientRBEvaluationComplex::Reader trans_rb_eval_reader =
168  message->getRoot<RBData::TransientRBEvaluationComplex>();
169  RBData::RBEvaluationComplex::Reader rb_eval_reader =
170  trans_rb_eval_reader.getRbEvaluation();
171 #endif
172 
174  rb_eval_reader,
175  trans_rb_eval_reader,
176  read_error_bound_data);
177 
178  int error = close(fd);
179  libmesh_error_msg_if(error, "Error closing a read-only file descriptor: " + path);
180 }
181 
182 // ---- TransientRBEvaluationDeserialization (END) ----
183 
184 
185 // ---- RBEIMEvaluationDeserialization (BEGIN) ----
186 
189  _rb_eim_eval(rb_eim_eval)
190 {}
191 
193 
195  bool use_packing)
196 {
197  LOG_SCOPE("read_from_file()", "RBEIMEvaluationDeserialization");
198 
199  int fd = open(path.c_str(), O_RDONLY);
200  libmesh_error_msg_if(!fd, "Couldn't open the buffer file: " + path);
201 
202  // Turn off the limit to the amount of data we can read in
203  capnp::ReaderOptions reader_options;
204  reader_options.traversalLimitInWords = std::numeric_limits<uint64_t>::max();
205 
206  std::unique_ptr<capnp::InputStreamMessageReader> message;
207  libmesh_try
208  {
209  if(use_packing)
210  message = std::make_unique<capnp::PackedFdMessageReader>(fd, reader_options);
211  else
212  message = std::make_unique<capnp::StreamFdMessageReader>(fd, reader_options);
213  }
214  libmesh_catch(...)
215  {
216  libmesh_error_msg("Failed to open capnp buffer");
217  }
218 
219 #ifndef LIBMESH_USE_COMPLEX_NUMBERS
220  RBData::RBEIMEvaluationReal::Reader rb_eim_eval_reader =
221  message->getRoot<RBData::RBEIMEvaluationReal>();
222 #else
223  RBData::RBEIMEvaluationComplex::Reader rb_eim_eval_reader =
224  message->getRoot<RBData::RBEIMEvaluationComplex>();
225 #endif
226 
228  rb_eim_eval_reader);
229 
230  int error = close(fd);
231  libmesh_error_msg_if(error, "Error closing a read-only file descriptor: " + path);
232 }
233 
234 // ---- RBEIMEvaluationDeserialization (END) ----
235 
236 
237 // ---- RBSCMEvaluationDeserialization (BEGIN) ----
238 // RBSCMEvaluationDeserialization is only available if both SLEPC and
239 // GLPK are available.
240 
241 #if defined(LIBMESH_HAVE_SLEPC) && (LIBMESH_HAVE_GLPK)
242 
245  _rb_scm_eval(rb_scm_eval)
246 {}
247 
249 
251  bool use_packing)
252 {
253  LOG_SCOPE("read_from_file()", "RBSCMEvaluationDeserialization");
254 
255  int fd = open(path.c_str(), O_RDONLY);
256  libmesh_error_msg_if(!fd, "Couldn't open the buffer file: " + path);
257 
258  // Turn off the limit to the amount of data we can read in
259  capnp::ReaderOptions reader_options;
260  reader_options.traversalLimitInWords = std::numeric_limits<uint64_t>::max();
261 
262  std::unique_ptr<capnp::InputStreamMessageReader> message;
263  libmesh_try
264  {
265  if(use_packing)
266  message = std::make_unique<capnp::PackedFdMessageReader>(fd, reader_options);
267  else
268  message = std::make_unique<capnp::StreamFdMessageReader>(fd, reader_options);
269  }
270  libmesh_catch(...)
271  {
272  libmesh_error_msg("Failed to open capnp buffer");
273  }
274 
275  RBData::RBSCMEvaluation::Reader rb_scm_eval_reader =
276  message->getRoot<RBData::RBSCMEvaluation>();
277 
279  rb_scm_eval_reader);
280 
281  int error = close(fd);
282  libmesh_error_msg_if(error, "Error closing a read-only file descriptor: " + path);
283 }
284 
285 #endif // LIBMESH_HAVE_SLEPC && LIBMESH_HAVE_GLPK
286 
287 // ---- RBSCMEvaluationDeserialization (END) ----
288 
289 
290 // ---- Helper functions for loading data from buffers (BEGIN) ----
291 
293  RBData::ParameterRanges::Reader & parameter_ranges,
294  RBData::DiscreteParameterList::Reader & discrete_parameters_list)
295 {
296  // Continuous parameters
297  RBParameters parameters_min;
298  RBParameters parameters_max;
299 
300  // Discrete parameters
301  std::map<std::string, std::vector<Real>> discrete_parameter_values;
302 
303  // The RBData::ParameterRanges::Reader (CapnProto class) will throw
304  // an exception if there is a problem with the data file (e.g. if it
305  // doesn't exist). We don't use the libmesh_try/catch() macros here
306  // since they don't really allow you to do any processing of the
307  // exception object.
308 #ifdef LIBMESH_ENABLE_EXCEPTIONS
309  try
310 #endif
311  {
312  const auto & parameter_names = parameter_ranges.getNames();
313  for (auto i : make_range(parameter_names.size()))
314  {
315  parameters_min.set_value(parameter_names[i], parameter_ranges.getMinValues()[i]);
316  parameters_max.set_value(parameter_names[i], parameter_ranges.getMaxValues()[i]);
317  }
318 
319 
320  const auto & discrete_names = discrete_parameters_list.getNames();
321  for (auto i : make_range(discrete_names.size()))
322  {
323  const auto & value_list = discrete_parameters_list.getValues()[i];
324  unsigned int n_values = value_list.size();
325  std::vector<Real> values(n_values);
326  for (unsigned int j=0; j<n_values; ++j)
327  values[j] = value_list[j];
328 
329  discrete_parameter_values[discrete_names[i]] = values;
330  }
331  }
332 #ifdef LIBMESH_ENABLE_EXCEPTIONS
333  catch (std::exception & e)
334  {
335  libmesh_error_msg("Error loading parameter ranges from capnp reader.\n"
336  "This usually means that the training data either doesn't exist or is out of date.\n"
337  "Detailed information about the error is below:\n\n" << e.what() << "\n");
338  }
339 #endif
340 
341  rb_evaluation.initialize_parameters(parameters_min,
342  parameters_max,
343  discrete_parameter_values);
344 }
345 
346 template <typename RBEvaluationReaderNumber>
348  RBEvaluationReaderNumber & rb_evaluation_reader,
349  bool read_error_bound_data)
350 {
351  // Set number of basis functions
352  unsigned int n_bfs = rb_evaluation_reader.getNBfs();
353  rb_evaluation.set_n_basis_functions(n_bfs);
354 
355  rb_evaluation.resize_data_structures(n_bfs, read_error_bound_data);
356 
357  auto parameter_ranges =
358  rb_evaluation_reader.getParameterRanges();
359  auto discrete_parameters_list =
360  rb_evaluation_reader.getDiscreteParameters();
361 
362  load_parameter_ranges(rb_evaluation,
363  parameter_ranges,
364  discrete_parameters_list);
365 
366  const RBThetaExpansion & rb_theta_expansion = rb_evaluation.get_rb_theta_expansion();
367 
368  unsigned int n_F_terms = rb_theta_expansion.get_n_F_terms();
369  unsigned int n_A_terms = rb_theta_expansion.get_n_A_terms();
370 
371  if (read_error_bound_data)
372  {
373 
374  // Fq representor inner-product data
375  {
376  unsigned int Q_f_hat = n_F_terms*(n_F_terms+1)/2;
377 
378  auto fq_innerprods_list = rb_evaluation_reader.getFqInnerprods();
379  libmesh_error_msg_if(fq_innerprods_list.size() != Q_f_hat,
380  "Size error while reading Fq representor norm data from buffer.");
381 
382  for (unsigned int i=0; i < Q_f_hat; ++i)
383  rb_evaluation.Fq_representor_innerprods[i] = load_scalar_value(fq_innerprods_list[i]);
384  }
385 
386  // Fq_Aq representor inner-product data
387  {
388  auto fq_aq_innerprods_list = rb_evaluation_reader.getFqAqInnerprods();
389  libmesh_error_msg_if(fq_aq_innerprods_list.size() != n_F_terms*n_A_terms*n_bfs,
390  "Size error while reading Fq-Aq representor norm data from buffer.");
391 
392  for (unsigned int q_f=0; q_f<n_F_terms; ++q_f)
393  for (unsigned int q_a=0; q_a<n_A_terms; ++q_a)
394  for (unsigned int i=0; i<n_bfs; ++i)
395  {
396  unsigned int offset = q_f*n_A_terms*n_bfs + q_a*n_bfs + i;
397  rb_evaluation.Fq_Aq_representor_innerprods[q_f][q_a][i] =
398  load_scalar_value(fq_aq_innerprods_list[offset]);
399  }
400  }
401 
402  // Aq_Aq representor inner-product data
403  {
404  unsigned int Q_a_hat = n_A_terms*(n_A_terms+1)/2;
405  auto aq_aq_innerprods_list = rb_evaluation_reader.getAqAqInnerprods();
406  libmesh_error_msg_if(aq_aq_innerprods_list.size() != Q_a_hat*n_bfs*n_bfs,
407  "Size error while reading Aq-Aq representor norm data from buffer.");
408 
409  for (unsigned int i=0; i<Q_a_hat; ++i)
410  for (unsigned int j=0; j<n_bfs; ++j)
411  for (unsigned int l=0; l<n_bfs; ++l)
412  {
413  unsigned int offset = i*n_bfs*n_bfs + j*n_bfs + l;
414  rb_evaluation.Aq_Aq_representor_innerprods[i][j][l] =
415  load_scalar_value(aq_aq_innerprods_list[offset]);
416  }
417  }
418 
419  // Output dual inner-product data
420  {
421  unsigned int n_outputs = rb_theta_expansion.get_n_outputs();
422  auto output_innerprod_outer = rb_evaluation_reader.getOutputDualInnerprods();
423 
424  libmesh_error_msg_if(output_innerprod_outer.size() != n_outputs,
425  "Incorrect number of outputs detected in the buffer");
426 
427  for (unsigned int output_id=0; output_id<n_outputs; ++output_id)
428  {
429  unsigned int n_output_terms = rb_theta_expansion.get_n_output_terms(output_id);
430 
431  unsigned int Q_l_hat = n_output_terms*(n_output_terms+1)/2;
432  auto output_innerprod_inner = output_innerprod_outer[output_id];
433 
434  libmesh_error_msg_if(output_innerprod_inner.size() != Q_l_hat,
435  "Incorrect number of output terms detected in the buffer");
436 
437  for (unsigned int q=0; q<Q_l_hat; ++q)
438  {
439  rb_evaluation.output_dual_innerprods[output_id][q] =
440  load_scalar_value(output_innerprod_inner[q]);
441  }
442  }
443  }
444  }
445 
446  // Output vectors
447  {
448  unsigned int n_outputs = rb_theta_expansion.get_n_outputs();
449  auto output_vector_outer = rb_evaluation_reader.getOutputVectors();
450 
451  libmesh_error_msg_if(output_vector_outer.size() != n_outputs,
452  "Incorrect number of outputs detected in the buffer");
453 
454  for (unsigned int output_id=0; output_id<n_outputs; ++output_id)
455  {
456  unsigned int n_output_terms = rb_theta_expansion.get_n_output_terms(output_id);
457 
458  auto output_vector_middle = output_vector_outer[output_id];
459  libmesh_error_msg_if(output_vector_middle.size() != n_output_terms,
460  "Incorrect number of output terms detected in the buffer");
461 
462  for (unsigned int q_l=0; q_l<n_output_terms; ++q_l)
463  {
464  auto output_vectors_inner_list = output_vector_middle[q_l];
465 
466  libmesh_error_msg_if(output_vectors_inner_list.size() != n_bfs,
467  "Incorrect number of output terms detected in the buffer");
468 
469  for (unsigned int j=0; j<n_bfs; ++j)
470  {
471  rb_evaluation.RB_output_vectors[output_id][q_l](j) =
472  load_scalar_value(output_vectors_inner_list[j]);
473  }
474  }
475  }
476  }
477 
478  // Fq vectors and Aq matrices
479  {
480  auto rb_fq_vectors_outer_list = rb_evaluation_reader.getRbFqVectors();
481  libmesh_error_msg_if(rb_fq_vectors_outer_list.size() != n_F_terms,
482  "Incorrect number of Fq vectors detected in the buffer");
483 
484  for (unsigned int q_f=0; q_f<n_F_terms; ++q_f)
485  {
486  auto rb_fq_vectors_inner_list = rb_fq_vectors_outer_list[q_f];
487  libmesh_error_msg_if(rb_fq_vectors_inner_list.size() != n_bfs,
488  "Incorrect Fq vector size detected in the buffer");
489 
490  for (unsigned int i=0; i < n_bfs; ++i)
491  {
492  rb_evaluation.RB_Fq_vector[q_f](i) =
493  load_scalar_value(rb_fq_vectors_inner_list[i]);
494  }
495  }
496 
497  auto rb_Aq_matrices_outer_list = rb_evaluation_reader.getRbAqMatrices();
498  libmesh_error_msg_if(rb_Aq_matrices_outer_list.size() != n_A_terms,
499  "Incorrect number of Aq matrices detected in the buffer");
500 
501  for (unsigned int q_a=0; q_a<n_A_terms; ++q_a)
502  {
503  auto rb_Aq_matrices_inner_list = rb_Aq_matrices_outer_list[q_a];
504  libmesh_error_msg_if(rb_Aq_matrices_inner_list.size() != n_bfs*n_bfs,
505  "Incorrect Aq matrix size detected in the buffer");
506 
507  for (unsigned int i=0; i<n_bfs; ++i)
508  for (unsigned int j=0; j<n_bfs; ++j)
509  {
510  unsigned int offset = i*n_bfs+j;
511  rb_evaluation.RB_Aq_vector[q_a](i,j) =
512  load_scalar_value(rb_Aq_matrices_inner_list[offset]);
513  }
514  }
515  }
516 
517  // Inner-product matrix
518  if (rb_evaluation.compute_RB_inner_product)
519  {
520  auto rb_inner_product_matrix_list =
521  rb_evaluation_reader.getRbInnerProductMatrix();
522 
523  libmesh_error_msg_if(rb_inner_product_matrix_list.size() != n_bfs*n_bfs,
524  "Size error while reading the inner product matrix.");
525 
526  for (unsigned int i=0; i<n_bfs; ++i)
527  for (unsigned int j=0; j<n_bfs; ++j)
528  {
529  unsigned int offset = i*n_bfs + j;
530  rb_evaluation.RB_inner_product_matrix(i,j) =
531  load_scalar_value(rb_inner_product_matrix_list[offset]);
532  }
533  }
534 }
535 
536 template <typename RBEvaluationReaderNumber, typename TransRBEvaluationReaderNumber>
538  RBEvaluationReaderNumber & rb_eval_reader,
539  TransRBEvaluationReaderNumber & trans_rb_eval_reader,
540  bool read_error_bound_data)
541 {
542  load_rb_evaluation_data(trans_rb_eval,
543  rb_eval_reader,
544  read_error_bound_data);
545 
546  trans_rb_eval.set_delta_t( trans_rb_eval_reader.getDeltaT() );
547  trans_rb_eval.set_euler_theta( trans_rb_eval_reader.getEulerTheta() );
548  trans_rb_eval.set_n_time_steps( trans_rb_eval_reader.getNTimeSteps() );
549  trans_rb_eval.set_time_step( trans_rb_eval_reader.getTimeStep() );
550 
551  unsigned int n_bfs = rb_eval_reader.getNBfs();
552  unsigned int n_F_terms = trans_rb_eval.get_rb_theta_expansion().get_n_F_terms();
553  unsigned int n_A_terms = trans_rb_eval.get_rb_theta_expansion().get_n_A_terms();
554 
555  TransientRBThetaExpansion & trans_theta_expansion =
556  cast_ref<TransientRBThetaExpansion &>(trans_rb_eval.get_rb_theta_expansion());
557  unsigned int n_M_terms = trans_theta_expansion.get_n_M_terms();
558 
559  // L2 matrix
560  {
561  auto rb_L2_matrix_list =
562  trans_rb_eval_reader.getRbL2Matrix();
563 
564  libmesh_error_msg_if(rb_L2_matrix_list.size() != n_bfs*n_bfs,
565  "Size error while reading the L2 matrix.");
566 
567  for (unsigned int i=0; i<n_bfs; ++i)
568  for (unsigned int j=0; j<n_bfs; ++j)
569  {
570  unsigned int offset = i*n_bfs + j;
571  trans_rb_eval.RB_L2_matrix(i,j) =
572  load_scalar_value(rb_L2_matrix_list[offset]);
573  }
574  }
575 
576  // Mq matrices
577  {
578  auto rb_Mq_matrices_outer_list = trans_rb_eval_reader.getRbMqMatrices();
579 
580  libmesh_error_msg_if(rb_Mq_matrices_outer_list.size() != n_M_terms,
581  "Incorrect number of Mq matrices detected in the buffer");
582 
583  for (unsigned int q_m=0; q_m < n_M_terms; ++q_m)
584  {
585  auto rb_Mq_matrices_inner_list = rb_Mq_matrices_outer_list[q_m];
586  libmesh_error_msg_if(rb_Mq_matrices_inner_list.size() != n_bfs*n_bfs,
587  "Incorrect Mq matrix size detected in the buffer");
588 
589  for (unsigned int i=0; i<n_bfs; ++i)
590  for (unsigned int j=0; j<n_bfs; ++j)
591  {
592  unsigned int offset = i*n_bfs+j;
593  trans_rb_eval.RB_M_q_vector[q_m](i,j) =
594  load_scalar_value(rb_Mq_matrices_inner_list[offset]);
595  }
596  }
597  }
598 
599  // The initial condition and L2 error at t=0.
600  {
601  auto initial_l2_errors_reader =
602  trans_rb_eval_reader.getInitialL2Errors();
603  libmesh_error_msg_if(initial_l2_errors_reader.size() != n_bfs,
604  "Incorrect number of initial L2 error terms detected in the buffer");
605 
606  auto initial_conditions_outer_list =
607  trans_rb_eval_reader.getInitialConditions();
608  libmesh_error_msg_if(initial_conditions_outer_list.size() != n_bfs,
609  "Incorrect number of outer initial conditions detected in the buffer");
610 
611  for (unsigned int i=0; i<n_bfs; i++)
612  {
613  trans_rb_eval.initial_L2_error_all_N[i] =
614  initial_l2_errors_reader[i];
615 
616  auto initial_conditions_inner_list = initial_conditions_outer_list[i];
617  libmesh_error_msg_if(initial_conditions_inner_list.size() != (i+1),
618  "Incorrect number of inner initial conditions detected in the buffer");
619 
620  for (unsigned int j=0; j<=i; j++)
621  {
622  trans_rb_eval.RB_initial_condition_all_N[i](j) =
623  load_scalar_value(initial_conditions_inner_list[j]);
624  }
625  }
626  }
627 
628 
629  if (read_error_bound_data)
630  {
631  // Fq_Mq data
632  {
633  auto fq_mq_innerprods_list = trans_rb_eval_reader.getFqMqInnerprods();
634  libmesh_error_msg_if(fq_mq_innerprods_list.size() != n_F_terms*n_M_terms*n_bfs,
635  "Size error while reading Fq-Mq representor data from buffer.");
636 
637  for (unsigned int q_f=0; q_f<n_F_terms; ++q_f)
638  for (unsigned int q_m=0; q_m<n_M_terms; ++q_m)
639  for (unsigned int i=0; i<n_bfs; ++i)
640  {
641  unsigned int offset = q_f*n_M_terms*n_bfs + q_m*n_bfs + i;
642  trans_rb_eval.Fq_Mq_representor_innerprods[q_f][q_m][i] =
643  load_scalar_value(fq_mq_innerprods_list[offset]);
644  }
645  }
646 
647 
648  // Mq_Mq representor inner-product data
649  {
650  unsigned int Q_m_hat = n_M_terms*(n_M_terms+1)/2;
651  auto mq_mq_innerprods_list = trans_rb_eval_reader.getMqMqInnerprods();
652  libmesh_error_msg_if(mq_mq_innerprods_list.size() != Q_m_hat*n_bfs*n_bfs,
653  "Size error while reading Mq-Mq representor data from buffer.");
654 
655  for (unsigned int i=0; i<Q_m_hat; ++i)
656  for (unsigned int j=0; j<n_bfs; ++j)
657  for (unsigned int l=0; l<n_bfs; ++l)
658  {
659  unsigned int offset = i*n_bfs*n_bfs + j*n_bfs + l;
660  trans_rb_eval.Mq_Mq_representor_innerprods[i][j][l] =
661  load_scalar_value(mq_mq_innerprods_list[offset]);
662  }
663  }
664 
665  // Aq_Mq representor inner-product data
666  {
667  auto aq_mq_innerprods_list =
668  trans_rb_eval_reader.getAqMqInnerprods();
669  libmesh_error_msg_if(aq_mq_innerprods_list.size() != n_A_terms*n_M_terms*n_bfs*n_bfs,
670  "Size error while reading Aq-Mq representor data from buffer.");
671 
672  for (unsigned int q_a=0; q_a<n_A_terms; q_a++)
673  for (unsigned int q_m=0; q_m<n_M_terms; q_m++)
674  for (unsigned int i=0; i<n_bfs; i++)
675  for (unsigned int j=0; j<n_bfs; j++)
676  {
677  unsigned int offset =
678  q_a*(n_M_terms*n_bfs*n_bfs) + q_m*(n_bfs*n_bfs) + i*n_bfs + j;
679 
680  trans_rb_eval.Aq_Mq_representor_innerprods[q_a][q_m][i][j] =
681  load_scalar_value(aq_mq_innerprods_list[offset]);
682  }
683  }
684 
685  }
686 }
687 
688 template <typename RBEIMEvaluationReaderNumber>
690  RBEIMEvaluationReaderNumber & rb_eim_evaluation_reader)
691 {
692  // Set number of basis functions
693  unsigned int n_bfs = rb_eim_evaluation_reader.getNBfs();
694  rb_eim_evaluation.set_n_basis_functions(n_bfs);
695 
696  rb_eim_evaluation.resize_data_structures(n_bfs);
697 
698  // EIM interpolation matrix
699  {
700  auto interpolation_matrix_list = rb_eim_evaluation_reader.getInterpolationMatrix();
701 
702  libmesh_error_msg_if(interpolation_matrix_list.size() != n_bfs*(n_bfs+1)/2,
703  "Size error while reading the eim inner product matrix.");
704 
705  for (unsigned int i=0; i<n_bfs; ++i)
706  for (unsigned int j=0; j<=i; ++j)
707  {
708  unsigned int offset = i*(i+1)/2 + j;
709  rb_eim_evaluation.set_interpolation_matrix_entry(
710  i,j, load_scalar_value(interpolation_matrix_list[offset]));
711  }
712  }
713 
714  // Note that we do not check rb_eim_evaluation.use_eim_error_indicator()
715  // below because it can be false in some cases when we're reading in
716  // data (e.g. if we're using a base class RBEIMEvaluation to do the
717  // reading). The check below will still give the right behavior
718  // regardless of the value of use_eim_error_indicator().
719  if (rb_eim_evaluation_reader.getInterpolationXyz().size() > n_bfs)
720  {
721  auto error_indicator_data_list = rb_eim_evaluation_reader.getEimErrorIndicatorInterpData();
722 
723  libmesh_error_msg_if(error_indicator_data_list.size() != n_bfs,
724  "Size error while reading the eim error indicator data.");
725 
726  DenseVector<Number> eim_error_indicator_data(n_bfs);
727  for (unsigned int i=0; i<n_bfs; ++i)
728  eim_error_indicator_data(i) = load_scalar_value(error_indicator_data_list[i]);
729 
730  rb_eim_evaluation.set_error_indicator_interpolation_row(eim_error_indicator_data);
731  }
732 
733  // If we're using the EIM error indicator then we store one extra
734  // interpolation point and associated data, hence we increment n_bfs
735  // here so that we write out the extra data below.
736  //
737  // However the interpolation matrix and _error_indicator_interpolation_row
738  // does not include this extra point, which is why we read it in above
739  // before n_bfs is incremented.
740  if (rb_eim_evaluation_reader.getInterpolationXyz().size() > n_bfs)
741  n_bfs++;
742 
743  auto parameter_ranges =
744  rb_eim_evaluation_reader.getParameterRanges();
745  auto discrete_parameters_list =
746  rb_eim_evaluation_reader.getDiscreteParameters();
747 
748  load_parameter_ranges(rb_eim_evaluation,
749  parameter_ranges,
750  discrete_parameters_list);
751 
752  // Interpolation points
753  {
754  auto interpolation_points_list =
755  rb_eim_evaluation_reader.getInterpolationXyz();
756 
757  libmesh_error_msg_if(interpolation_points_list.size() != n_bfs,
758  "Size error while reading the eim interpolation points.");
759 
760  for (unsigned int i=0; i<n_bfs; ++i)
761  {
762  Point p;
763  load_point(interpolation_points_list[i], p);
764  rb_eim_evaluation.add_interpolation_points_xyz(p);
765  }
766  }
767 
768  // Interpolation points components
769  {
770  auto interpolation_points_comp_list =
771  rb_eim_evaluation_reader.getInterpolationComp();
772 
773  libmesh_error_msg_if(interpolation_points_comp_list.size() != n_bfs,
774  "Size error while reading the eim interpolation components.");
775 
776  for (unsigned int i=0; i<n_bfs; ++i)
777  {
778  rb_eim_evaluation.add_interpolation_points_comp(interpolation_points_comp_list[i]);
779  }
780  }
781 
782  // Interpolation points subdomain IDs
783  {
784  auto interpolation_points_subdomain_id_list =
785  rb_eim_evaluation_reader.getInterpolationSubdomainId();
786 
787  libmesh_error_msg_if(interpolation_points_subdomain_id_list.size() != n_bfs,
788  "Size error while reading the eim interpolation subdomain IDs.");
789 
790  for (unsigned int i=0; i<n_bfs; ++i)
791  {
792  rb_eim_evaluation.add_interpolation_points_subdomain_id(interpolation_points_subdomain_id_list[i]);
793  }
794  }
795 
796  // Interpolation points side indices, relevant if the parametrized function is defined
797  // on mesh sides or nodesets
798  if (rb_eim_evaluation.get_parametrized_function().on_mesh_sides() ||
799  rb_eim_evaluation.get_parametrized_function().on_mesh_nodes())
800  {
801  auto interpolation_points_boundary_id_list =
802  rb_eim_evaluation_reader.getInterpolationBoundaryId();
803 
804  libmesh_error_msg_if(interpolation_points_boundary_id_list.size() != n_bfs,
805  "Size error while reading the eim interpolation boundary IDs.");
806 
807  for (unsigned int i=0; i<n_bfs; ++i)
808  {
809  rb_eim_evaluation.add_interpolation_points_boundary_id(interpolation_points_boundary_id_list[i]);
810  }
811  }
812 
813  // Interpolation points element IDs
814  {
815  auto interpolation_points_elem_id_list =
816  rb_eim_evaluation_reader.getInterpolationElemId();
817 
818  libmesh_error_msg_if(interpolation_points_elem_id_list.size() != n_bfs,
819  "Size error while reading the eim interpolation element IDs.");
820 
821  for (unsigned int i=0; i<n_bfs; ++i)
822  {
823  rb_eim_evaluation.add_interpolation_points_elem_id(interpolation_points_elem_id_list[i]);
824  }
825  }
826 
827  // Interpolation points node IDs, relevant if the parametrized function is defined on mesh sides
828  if (rb_eim_evaluation.get_parametrized_function().on_mesh_nodes())
829  {
830  auto interpolation_points_node_id_list =
831  rb_eim_evaluation_reader.getInterpolationNodeId();
832 
833  libmesh_error_msg_if(interpolation_points_node_id_list.size() != n_bfs,
834  "Size error while reading the eim interpolation node IDs.");
835 
836  for (unsigned int i=0; i<n_bfs; ++i)
837  {
838  rb_eim_evaluation.add_interpolation_points_node_id(interpolation_points_node_id_list[i]);
839  }
840  }
841 
842  // Interpolation points side indices, relevant if the parametrized function is defined on mesh sides
843  if (rb_eim_evaluation.get_parametrized_function().on_mesh_sides())
844  {
845  auto interpolation_points_side_index_list =
846  rb_eim_evaluation_reader.getInterpolationSideIndex();
847 
848  libmesh_error_msg_if(interpolation_points_side_index_list.size() != n_bfs,
849  "Size error while reading the eim interpolation side indices.");
850 
851  for (unsigned int i=0; i<n_bfs; ++i)
852  {
853  rb_eim_evaluation.add_interpolation_points_side_index(interpolation_points_side_index_list[i]);
854  }
855  }
856 
857  // Interpolation points quad point indices
858  {
859  auto interpolation_points_qp_list =
860  rb_eim_evaluation_reader.getInterpolationQp();
861 
862  libmesh_error_msg_if(interpolation_points_qp_list.size() != n_bfs,
863  "Size error while reading the eim interpolation qps.");
864 
865  for (unsigned int i=0; i<n_bfs; ++i)
866  {
867  rb_eim_evaluation.add_interpolation_points_qp(interpolation_points_qp_list[i]);
868  }
869  }
870 
871  unsigned int n_elems = rb_eim_evaluation_reader.getNElems();
872  bool build_elem_id_to_local_index_map = false;
873  // Interpolation points JxW all qp values
874  {
875  auto interpolation_points_list_outer =
876  rb_eim_evaluation_reader.getInterpolationJxWAllQp();
877 
878  if (interpolation_points_list_outer.size() > 0)
879  {
880  if (n_elems != 0)
881  {
882  libmesh_error_msg_if(interpolation_points_list_outer.size() != n_elems,
883  "Size error while reading the eim JxW values.");
884 
885  for (unsigned int i=0; i<n_elems; ++i)
886  {
887  auto interpolation_points_list_inner = interpolation_points_list_outer[i];
888 
889  std::vector<Real> JxW(interpolation_points_list_inner.size());
890  for (unsigned int j=0; j<JxW.size(); j++)
891  {
892  JxW[j] = interpolation_points_list_inner[j];
893  }
894  rb_eim_evaluation.add_interpolation_points_JxW_all_qp(JxW);
895  }
896  }
897  // Backward compatibility for existing qp based training data
898  // As we read in data for all qp, we only select the first one for elems
899  // (when we encounter the elem for the first time).
900  else
901  {
902  // We use the JxW_all_qp to determine whether or not we need to build
903  // the elem_id_to_local_index_map in backward compatibility mode as the map
904  // will be empty when deserializing (old training data format) and it
905  // is not always needed (optional). If JxW is provided then elem_id_to_local_index_map
906  // is needed. This flag is only used in backward compatibility mode but not
907  // in the most recent training data format.
908  build_elem_id_to_local_index_map = true;
909 
910  auto interpolation_points_elem_id_list =
911  rb_eim_evaluation_reader.getInterpolationElemId();
912  std::set<dof_id_type> added_elem_id;
913 
914  libmesh_error_msg_if(interpolation_points_list_outer.size() != n_bfs,
915  "Size error while reading the eim JxW values.");
916 
917  for (unsigned int i=0; i<n_bfs; ++i)
918  {
919  dof_id_type elem_id = interpolation_points_elem_id_list[i];
920  if (const auto lookup = added_elem_id.find(elem_id); lookup == added_elem_id.end())
921  {
922  added_elem_id.emplace(elem_id);
923 
924  auto interpolation_points_list_inner = interpolation_points_list_outer[i];
925  std::vector<Real> JxW(interpolation_points_list_inner.size());
926  for (unsigned int j=0; j<JxW.size(); j++)
927  {
928  JxW[j] = interpolation_points_list_inner[j];
929  }
930  rb_eim_evaluation.add_interpolation_points_JxW_all_qp(JxW);
931  }
932  }
933  }
934  }
935  }
936 
937  // Interpolation points phi_i all qp values
938  {
939  auto interpolation_points_list_outer =
940  rb_eim_evaluation_reader.getInterpolationPhiValuesAllQp();
941 
942  if (interpolation_points_list_outer.size() > 0)
943  {
944  if (n_elems != 0)
945  {
946  libmesh_error_msg_if(interpolation_points_list_outer.size() != n_elems,
947  "Size error while reading the eim phi_i all qp values.");
948 
949  for (unsigned int i=0; i<n_elems; ++i)
950  {
951  auto interpolation_points_list_middle = interpolation_points_list_outer[i];
952 
953  std::vector<std::vector<Real>> phi_i_all_qp(interpolation_points_list_middle.size());
954  for (auto j : index_range(phi_i_all_qp))
955  {
956  auto interpolation_points_list_inner = interpolation_points_list_middle[j];
957 
958  phi_i_all_qp[j].resize(interpolation_points_list_inner.size());
959  for (auto k : index_range(phi_i_all_qp[j]))
960  phi_i_all_qp[j][k] = interpolation_points_list_inner[k];
961  }
962  rb_eim_evaluation.add_interpolation_points_phi_i_all_qp(phi_i_all_qp);
963  }
964  }
965  // Backward compatibility for existing qp based training data
966  // As we read in data for all qp, we only select the first one for elems
967  // (when we encounter the elem for the first time).
968  else
969  {
970  auto interpolation_points_elem_id_list =
971  rb_eim_evaluation_reader.getInterpolationElemId();
972  std::set<dof_id_type> added_elem_id;
973 
974  libmesh_error_msg_if(interpolation_points_list_outer.size() != n_bfs,
975  "Size error while reading the eim JxW values.");
976 
977  for (unsigned int i=0; i<n_bfs; ++i)
978  {
979  dof_id_type elem_id = interpolation_points_elem_id_list[i];
980  if (const auto lookup = added_elem_id.find(elem_id); lookup == added_elem_id.end())
981  {
982  added_elem_id.emplace(elem_id);
983 
984  auto interpolation_points_list_middle = interpolation_points_list_outer[i];
985  std::vector<std::vector<Real>> phi_i_all_qp(interpolation_points_list_middle.size());
986  for (auto j : index_range(phi_i_all_qp))
987  {
988  auto interpolation_points_list_inner = interpolation_points_list_middle[j];
989 
990  phi_i_all_qp[j].resize(interpolation_points_list_inner.size());
991  for (auto k : index_range(phi_i_all_qp[j]))
992  phi_i_all_qp[j][k] = interpolation_points_list_inner[k];
993  }
994  rb_eim_evaluation.add_interpolation_points_phi_i_all_qp(phi_i_all_qp);
995  }
996  }
997  }
998  }
999  }
1000 
1001  // Elem id to local index map
1002  {
1003  auto elem_id_to_local_index_list =
1004  rb_eim_evaluation_reader.getElemIdToLocalIndex();
1005 
1006  if (elem_id_to_local_index_list.size() > 0)
1007  {
1008  libmesh_error_msg_if(elem_id_to_local_index_list.size() != n_elems,
1009  "Size error while reading the eim elem id to local index map.");
1010 
1011  for (unsigned int i=0; i<n_elems; ++i)
1012  {
1013  rb_eim_evaluation.add_elem_id_local_index_map_entry(elem_id_to_local_index_list[i].getFirst(), elem_id_to_local_index_list[i].getSecond());
1014  }
1015  }
1016  // Create elem id to local index map if non-existent in training data set but
1017  // required for backward compatibility purposes.
1018  else if (build_elem_id_to_local_index_map)
1019  {
1020  auto interpolation_points_elem_id_list =
1021  rb_eim_evaluation_reader.getInterpolationElemId();
1022  std::set<dof_id_type> added_elem_id;
1023  unsigned int local_index = 0;
1024 
1025  libmesh_error_msg_if(interpolation_points_elem_id_list.size() != n_bfs,
1026  "Size error while creating the eim elem id to local index map.");
1027 
1028  for (unsigned int i=0; i<n_bfs; ++i)
1029  {
1030  dof_id_type elem_id = interpolation_points_elem_id_list[i];
1031  if (const auto lookup = added_elem_id.find(elem_id); lookup == added_elem_id.end())
1032  {
1033  added_elem_id.emplace(elem_id);
1034  rb_eim_evaluation.add_elem_id_local_index_map_entry(elem_id, local_index);
1035  ++local_index;
1036  }
1037  }
1038  }
1039  }
1040 
1041  // Dxyzdxi at the element center for the element that contains each interpolation point.
1042  {
1043  auto elem_center_dxyzdxi =
1044  rb_eim_evaluation_reader.getInterpolationDxyzDxiElem();
1045 
1046  if (elem_center_dxyzdxi.size() > 0)
1047  {
1048  if (n_elems != 0)
1049  {
1050  libmesh_error_msg_if(elem_center_dxyzdxi.size() != n_elems,
1051  "Size error while reading the eim elem center tangent derivative dxyzdxi.");
1052 
1053  Point dxyzdxi_buffer;
1054  for (const auto i : make_range(n_elems))
1055  {
1056  load_point(elem_center_dxyzdxi[i], dxyzdxi_buffer);
1057  rb_eim_evaluation.add_elem_center_dxyzdxi(dxyzdxi_buffer);
1058  }
1059  }
1060  // Backward compatibility for existing qp based training data
1061  // As we read in data for all qp, we only select the first one for elems
1062  // (when we encounter the elem for the first time).
1063  else
1064  {
1065  auto interpolation_points_elem_id_list =
1066  rb_eim_evaluation_reader.getInterpolationElemId();
1067  std::set<dof_id_type> added_elem_id;
1068 
1069  libmesh_error_msg_if(elem_center_dxyzdxi.size() != n_bfs,
1070  "Size error while reading the eim elem center tangent derivative dxyzdxi.");
1071 
1072  Point dxyzdxi_buffer;
1073  for (unsigned int i=0; i<n_bfs; ++i)
1074  {
1075  dof_id_type elem_id = interpolation_points_elem_id_list[i];
1076  if (const auto lookup = added_elem_id.find(elem_id); lookup == added_elem_id.end())
1077  {
1078  added_elem_id.emplace(elem_id);
1079 
1080  load_point(elem_center_dxyzdxi[i], dxyzdxi_buffer);
1081  rb_eim_evaluation.add_elem_center_dxyzdxi(dxyzdxi_buffer);
1082  }
1083  }
1084  }
1085  }
1086  }
1087 
1088  // Dxyzdeta at the element center for the element that contains each interpolation point.
1089  {
1090  auto elem_center_dxyzdeta =
1091  rb_eim_evaluation_reader.getInterpolationDxyzDetaElem();
1092 
1093  if (elem_center_dxyzdeta.size() > 0)
1094  {
1095  if (n_elems != 0)
1096  {
1097  libmesh_error_msg_if(elem_center_dxyzdeta.size() != n_elems,
1098  "Size error while reading the eim elem center tangent derivative dxyzdeta.");
1099 
1100  Point dxyzdeta_buffer;
1101  for (const auto i : make_range(n_elems))
1102  {
1103  load_point(elem_center_dxyzdeta[i], dxyzdeta_buffer);
1104  rb_eim_evaluation.add_elem_center_dxyzdeta(dxyzdeta_buffer);
1105  }
1106  }
1107  // Backward compatibility for existing qp based training data
1108  // As we read in data for all qp, we only select the first one for elems
1109  // (when we encounter the elem for the first time).
1110  else
1111  {
1112  auto interpolation_points_elem_id_list =
1113  rb_eim_evaluation_reader.getInterpolationElemId();
1114  std::set<dof_id_type> added_elem_id;
1115 
1116  libmesh_error_msg_if(elem_center_dxyzdeta.size() != n_bfs,
1117  "Size error while reading the eim elem center tangent derivative dxyzdeta.");
1118 
1119  Point dxyzdeta_buffer;
1120  for (unsigned int i=0; i<n_bfs; ++i)
1121  {
1122  dof_id_type elem_id = interpolation_points_elem_id_list[i];
1123  if (const auto lookup = added_elem_id.find(elem_id); lookup == added_elem_id.end())
1124  {
1125  added_elem_id.emplace(elem_id);
1126 
1127  load_point(elem_center_dxyzdeta[i], dxyzdeta_buffer);
1128  rb_eim_evaluation.add_elem_center_dxyzdeta(dxyzdeta_buffer);
1129  }
1130  }
1131  }
1132  }
1133  }
1134 
1135  // Quadrature rule order associated to the element that contains each interpolation point.
1136  {
1137  auto interpolation_points_qrule_order_list =
1138  rb_eim_evaluation_reader.getInterpolationQruleOrder();
1139 
1140  if (interpolation_points_qrule_order_list.size() > 0)
1141  {
1142  if (n_elems != 0)
1143  {
1144  libmesh_error_msg_if(interpolation_points_qrule_order_list.size() != n_elems,
1145  "Size error while reading the eim elem qrule order.");
1146 
1147  for (unsigned int i=0; i<n_elems; ++i)
1148  {
1149  rb_eim_evaluation.add_interpolation_points_qrule_order(static_cast<Order>(interpolation_points_qrule_order_list[i]));
1150  }
1151  }
1152  // Backward compatibility for existing qp based training data.
1153  // As we read in data for all qp, we only select the first one for elems
1154  // (when we encounter the elem for the first time).
1155  else
1156  {
1157  auto interpolation_points_elem_id_list =
1158  rb_eim_evaluation_reader.getInterpolationElemId();
1159  std::set<dof_id_type> added_elem_id;
1160 
1161  libmesh_error_msg_if(interpolation_points_qrule_order_list.size() != n_bfs,
1162  "Size error while reading the eim elem qrule order.");
1163 
1164  for (unsigned int i=0; i<n_bfs; ++i)
1165  {
1166  dof_id_type elem_id = interpolation_points_elem_id_list[i];
1167  if (const auto lookup = added_elem_id.find(elem_id); lookup == added_elem_id.end())
1168  {
1169  added_elem_id.emplace(elem_id);
1170 
1171  rb_eim_evaluation.add_interpolation_points_qrule_order(static_cast<Order>(interpolation_points_qrule_order_list[i]));
1172  }
1173  }
1174  }
1175  }
1176  }
1177 
1178  // Interpolation points element types
1179  {
1180  auto interpolation_points_elem_type_list =
1181  rb_eim_evaluation_reader.getInterpolationElemType();
1182 
1183  if (interpolation_points_elem_type_list.size() > 0)
1184  {
1185  libmesh_error_msg_if(interpolation_points_elem_type_list.size() != n_bfs,
1186  "Size error while reading the eim interpolation element types.");
1187 
1188  for (unsigned int i=0; i<n_bfs; ++i)
1189  {
1190  rb_eim_evaluation.add_interpolation_points_elem_type(static_cast<ElemType>(interpolation_points_elem_type_list[i]));
1191  }
1192  }
1193  }
1194 
1195  // Property map used to store generic properties by flaging entites like elements, nodes etc...
1196  {
1197  auto interpolation_points_property_list =
1198  rb_eim_evaluation_reader.getPropertyMap();
1199 
1200  if (interpolation_points_property_list.size() > 0)
1201  {
1202  unsigned int n_properties = interpolation_points_property_list.size();
1203  for (unsigned int i=0; i<n_properties; ++i)
1204  {
1205  std::string property_name = interpolation_points_property_list[i].getName();
1206  const auto entity_ids_list = interpolation_points_property_list[i].getEntityIds();
1207  std::set<dof_id_type> entity_ids_set;
1208  for (unsigned int j=0; j<entity_ids_list.size(); ++j)
1209  {
1210  entity_ids_set.insert(static_cast<dof_id_type>(entity_ids_list[j]));
1211  }
1212  rb_eim_evaluation.add_rb_property_map_entry(property_name, entity_ids_set);
1213  }
1214  }
1215  }
1216 
1217  // Interpolation points perturbations
1218  {
1219  auto interpolation_points_list_outer =
1220  rb_eim_evaluation_reader.getInterpolationXyzPerturb();
1221 
1222  libmesh_error_msg_if(interpolation_points_list_outer.size() != n_bfs,
1223  "Size error while reading the eim interpolation points.");
1224 
1225  for (unsigned int i=0; i<n_bfs; ++i)
1226  {
1227  auto interpolation_points_list_inner = interpolation_points_list_outer[i];
1228 
1229  std::vector<Point> perturbs(interpolation_points_list_inner.size());
1230  for (unsigned int j=0; j<perturbs.size(); j++)
1231  {
1232  load_point(interpolation_points_list_inner[j], perturbs[j]);
1233  }
1234  rb_eim_evaluation.add_interpolation_points_xyz_perturbations(perturbs);
1235  }
1236  }
1237 
1238  // Optionally load EIM solutions for the training set
1239  if (rb_eim_evaluation.get_parametrized_function().is_lookup_table)
1240  {
1241  auto eim_rhs_list_outer =
1242  rb_eim_evaluation_reader.getEimSolutionsForTrainingSet();
1243 
1244  std::vector<DenseVector<Number>> & eim_solutions = rb_eim_evaluation.get_eim_solutions_for_training_set();
1245  eim_solutions.clear();
1246  eim_solutions.resize(eim_rhs_list_outer.size());
1247 
1248  for (auto i : make_range(eim_rhs_list_outer.size()))
1249  {
1250  auto eim_rhs_list_inner = eim_rhs_list_outer[i];
1251 
1252  DenseVector<Number> values(eim_rhs_list_inner.size());
1253  for (auto j : index_range(values))
1254  {
1255  values(j) = load_scalar_value(eim_rhs_list_inner[j]);
1256  }
1257  eim_solutions[i] = values;
1258  }
1259  }
1260 
1261  // The shape function values at the interpolation points. This can be used to evaluate nodal data
1262  // at EIM interpolation points, which are at quadrature points.
1263  {
1264  auto interpolation_points_list_outer =
1265  rb_eim_evaluation_reader.getInterpolationPhiValues();
1266 
1267  libmesh_error_msg_if(interpolation_points_list_outer.size() != n_bfs,
1268  "Size error while reading the eim interpolation points.");
1269 
1270  for (unsigned int i=0; i<n_bfs; ++i)
1271  {
1272  auto interpolation_points_list_inner = interpolation_points_list_outer[i];
1273 
1274  std::vector<Real> phi_i_qp(interpolation_points_list_inner.size());
1275  for (unsigned int j=0; j<phi_i_qp.size(); j++)
1276  {
1277  phi_i_qp[j] = interpolation_points_list_inner[j];
1278  }
1279  rb_eim_evaluation.add_interpolation_points_phi_i_qp(phi_i_qp);
1280  }
1281  }
1282 
1283  // Read in the spatial indices at interpolation points. This data is optional
1284  // so this may be empty.
1285  {
1286  auto interpolation_points_list_outer =
1287  rb_eim_evaluation_reader.getInterpolationSpatialIndices();
1288 
1289  for (unsigned int i=0; i<interpolation_points_list_outer.size(); ++i)
1290  {
1291  auto interpolation_points_list_inner = interpolation_points_list_outer[i];
1292 
1293  std::vector<unsigned int> spatial_indices(interpolation_points_list_inner.size());
1294  for (unsigned int j=0; j<spatial_indices.size(); j++)
1295  {
1296  spatial_indices[j] = interpolation_points_list_inner[j];
1297  }
1298  rb_eim_evaluation.add_interpolation_points_spatial_indices(spatial_indices);
1299  }
1300 
1301  rb_eim_evaluation.initialize_param_fn_spatial_indices();
1302  }
1303 }
1304 
1305 #if defined(LIBMESH_HAVE_SLEPC) && (LIBMESH_HAVE_GLPK)
1307  RBData::RBSCMEvaluation::Reader & rb_scm_evaluation_reader)
1308 {
1309  auto parameter_ranges =
1310  rb_scm_evaluation_reader.getParameterRanges();
1311  auto discrete_parameters_list =
1312  rb_scm_evaluation_reader.getDiscreteParameters();
1313  load_parameter_ranges(rb_scm_eval,
1314  parameter_ranges,
1315  discrete_parameters_list);
1316 
1317  unsigned int n_A_terms = rb_scm_eval.get_rb_theta_expansion().get_n_A_terms();
1318 
1319  {
1320  auto b_min_list = rb_scm_evaluation_reader.getBMin();
1321 
1322  libmesh_error_msg_if(b_min_list.size() != n_A_terms,
1323  "Size error while reading B_min");
1324 
1325  rb_scm_eval.B_min.clear();
1326  for (unsigned int i=0; i<n_A_terms; i++)
1327  rb_scm_eval.B_min.push_back(b_min_list[i]);
1328  }
1329 
1330  {
1331  auto b_max_list = rb_scm_evaluation_reader.getBMax();
1332 
1333  libmesh_error_msg_if(b_max_list.size() != n_A_terms,
1334  "Size error while reading B_max");
1335 
1336  rb_scm_eval.B_max.clear();
1337  for (unsigned int i=0; i<n_A_terms; i++)
1338  rb_scm_eval.B_max.push_back(b_max_list[i]);
1339  }
1340 
1341  {
1342  auto cJ_stability_vector =
1343  rb_scm_evaluation_reader.getCJStabilityVector();
1344 
1345  rb_scm_eval.C_J_stability_vector.clear();
1346  for (const auto & val : cJ_stability_vector)
1347  rb_scm_eval.C_J_stability_vector.push_back(val);
1348  }
1349 
1350  {
1351  auto cJ_parameters_outer =
1352  rb_scm_evaluation_reader.getCJ();
1353 
1354  rb_scm_eval.C_J.resize(cJ_parameters_outer.size());
1355  for (auto i : make_range(cJ_parameters_outer.size()))
1356  {
1357  auto cJ_parameters_inner =
1358  cJ_parameters_outer[i];
1359 
1360  for (auto j : make_range(cJ_parameters_inner.size()))
1361  {
1362  std::string param_name = cJ_parameters_inner[j].getName();
1363  Real param_value = cJ_parameters_inner[j].getValue();
1364  rb_scm_eval.C_J[i].set_value(param_name, param_value);
1365  }
1366  }
1367  }
1368 
1369  {
1370  auto scm_ub_vectors =
1371  rb_scm_evaluation_reader.getScmUbVectors();
1372 
1373  // The number of UB vectors is the same as the number of C_J values
1374  unsigned int n_C_J_values = rb_scm_evaluation_reader.getCJ().size();
1375 
1376  libmesh_error_msg_if(scm_ub_vectors.size() != n_C_J_values*n_A_terms,
1377  "Size mismatch in SCB UB vectors");
1378 
1379  rb_scm_eval.SCM_UB_vectors.resize( n_C_J_values );
1380  for (unsigned int i=0; i<n_C_J_values; i++)
1381  {
1382  rb_scm_eval.SCM_UB_vectors[i].resize(n_A_terms);
1383  for (unsigned int j=0; j<n_A_terms; j++)
1384  {
1385  unsigned int offset = i*n_A_terms + j;
1386  rb_scm_eval.SCM_UB_vectors[i][j] = scm_ub_vectors[offset];
1387 
1388  }
1389  }
1390  }
1391 
1392 }
1393 #endif // LIBMESH_HAVE_SLEPC && LIBMESH_HAVE_GLPK
1394 
1395 
1396 
1397 void load_point(RBData::Point3D::Reader point_reader, Point & point)
1398 {
1399  point(0) = point_reader.getX();
1400 
1401  if (LIBMESH_DIM >= 2)
1402  point(1) = point_reader.getY();
1403 
1404  if (LIBMESH_DIM >= 3)
1405  point(2) = point_reader.getZ();
1406 }
1407 
1408 // ---- Helper functions for adding data to capnp Builders (END) ----
1409 
1410 } // namespace RBDataSerialization
1411 
1412 } // namespace libMesh
1413 
1414 #endif // #if defined(LIBMESH_HAVE_CAPNPROTO)
std::vector< Real > B_min
B_min, B_max define the bounding box.
std::vector< std::vector< std::vector< Number > > > Mq_Mq_representor_innerprods
void add_rb_property_map_entry(std::string &property_name, std::set< dof_id_type > &entity_ids)
void read_from_file(const std::string &path, bool read_error_bound_data, bool use_packing=false)
Read the Cap&#39;n&#39;Proto buffer from disk.
bool compute_RB_inner_product
Boolean flag to indicate whether we compute the RB_inner_product_matrix.
void add_interpolation_points_boundary_id(boundary_id_type b_id)
RBSCMEvaluation & _rb_scm_eval
The RBSCMEvaluation object we will read into.
std::vector< Number > Fq_representor_innerprods
Vectors storing the residual representor inner products to be used in computing the residuals online...
unsigned int get_n_F_terms() const
Get Q_f, the number of terms in the affine expansion for the right-hand side.
void set_interpolation_matrix_entry(unsigned int i, unsigned int j, Number value)
Set entry of the EIM interpolation matrix.
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.
void read_from_file(const std::string &path, bool use_packing=false)
Read the Cap&#39;n&#39;Proto buffer from disk.
std::vector< DenseMatrix< Number > > RB_M_q_vector
Dense matrices for the RB mass matrices.
void load_rb_evaluation_data(RBEvaluation &rb_evaluation, RBEvaluationReaderNumber &rb_evaluation_reader, bool read_error_bound_data)
Load an RB evaluation from a corresponding reader structure in the buffer.
DenseMatrix< Number > RB_inner_product_matrix
The inner product matrix.
void add_interpolation_points_elem_id(dof_id_type elem_id)
void load_rb_scm_evaluation_data(RBSCMEvaluation &rb_scm_eval, RBData::RBSCMEvaluation::Reader &rb_scm_eval_reader)
Load an SCM RB evaluation from a corresponding reader structure in the buffer.
unsigned int get_n_A_terms() const
Get Q_a, the number of terms in the affine expansion for the bilinear form.
This class is part of the rbOOmit framework.
void load_transient_rb_evaluation_data(TransientRBEvaluation &trans_rb_eval, RBEvaluationReaderNumber &rb_evaluation_reader, TransRBEvaluationReaderNumber &trans_rb_eval_reader, bool read_error_bound_data)
Load an RB evaluation from a corresponding reader structure in the buffer.
This class stores the set of RBTheta functor objects that define the "parameter-dependent expansion" ...
std::vector< std::vector< Number > > output_dual_innerprods
The vector storing the dual norm inner product terms for each output.
The libMesh namespace provides an interface to certain functionality in the library.
const std::vector< DenseVector< Number > > & get_eim_solutions_for_training_set() const
Return a const reference to the EIM solutions for the parameters in the training set.
void initialize_param_fn_spatial_indices()
The Online counterpart of initialize_interpolation_points_spatial_indices().
void add_interpolation_points_xyz_perturbations(const std::vector< Point > &perturbs)
RBThetaExpansion & get_rb_theta_expansion()
Get a reference to the rb_theta_expansion.
std::vector< Real > B_max
unsigned int get_n_outputs() const
Get n_outputs, the number output functionals.
This class stores the set of RBTheta functor objects that define the "parameter-dependent expansion" ...
std::vector< std::vector< Real > > SCM_UB_vectors
This matrix stores the infimizing vectors y_1( ),...,y_Q_a( ), for each in C_J, which are used in co...
std::vector< Real > C_J_stability_vector
Vector storing the (truth) stability values at the parameters in C_J.
RBSCMEvaluationDeserialization(RBSCMEvaluation &trans_rb_eval)
Initialize a new buffer using the structure from the Cap&#39;n&#39;Proto schema described in rb_data...
std::vector< DenseVector< Number > > RB_Fq_vector
Dense vector for the RHS.
bool is_lookup_table
Boolean to indicate if this parametrized function is defined based on a lookup table or not...
RBEvaluationDeserialization(RBEvaluation &rb_eval)
Initialize a new buffer using the structure from the Cap&#39;n&#39;Proto schema described in rb_data...
std::vector< Real > initial_L2_error_all_N
Vector storing initial L2 error for all 1 <= N <= RB_size.
void resize_data_structures(const unsigned int Nmax)
Resize the data structures for storing data associated with this object.
std::vector< RBParameters > C_J
Vector storing the greedily selected parameters during SCM training.
void set_n_basis_functions(unsigned int n_bfs)
Set the number of basis functions.
void load_parameter_ranges(RBParametrized &rb_evaluation, RBData::ParameterRanges::Reader &parameter_ranges, RBData::DiscreteParameterList::Reader &discrete_parameters_list)
Load parameter ranges and discrete parameter values into an RBEvaluation from the corresponding struc...
void add_elem_id_local_index_map_entry(dof_id_type elem_id, unsigned int local_index)
virtual unsigned int get_n_M_terms() const
Get Q_m, the number of terms in the affine expansion for the mass operator.
void read_from_file(const std::string &path, bool read_error_bound_data, bool use_packing=false)
Read the Cap&#39;n&#39;Proto buffer from disk.
void load_rb_eim_evaluation_data(RBEIMEvaluation &rb_eim_eval, RBEIMEvaluationReaderNumber &rb_eim_eval_reader)
Load an EIM RB evaluation from a corresponding reader structure in the buffer.
void add_interpolation_points_side_index(unsigned int side_index)
std::vector< std::vector< std::vector< Number > > > Fq_Mq_representor_innerprods
Vectors storing the residual representor inner products to be used in computing the residuals online...
RBEIMEvaluation & _rb_eim_eval
The RBEIMEvaluation object we will read into.
void add_interpolation_points_phi_i_all_qp(const std::vector< std::vector< Real >> &phi_i_all_qp)
void add_interpolation_points_phi_i_qp(const std::vector< Real > &phi_i_qp)
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
void add_elem_center_dxyzdeta(const Point &dxyzdxi)
RBEIMEvaluationDeserialization(RBEIMEvaluation &trans_rb_eval)
Initialize a new buffer using the structure from the Cap&#39;n&#39;Proto schema described in rb_data...
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::vector< DenseVector< Number > > RB_initial_condition_all_N
The RB initial conditions (i.e.
This class is part of the rbOOmit framework.
Definition: rb_evaluation.h:50
void add_interpolation_points_subdomain_id(subdomain_id_type sbd_id)
std::vector< DenseMatrix< Number > > RB_Aq_vector
Dense matrices for the RB computations.
void add_interpolation_points_node_id(dof_id_type node_id)
void add_interpolation_points_xyz(Point p)
Set the data associated with EIM interpolation points.
void add_interpolation_points_qrule_order(Order qrule_order)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void load_point(RBData::Point3D::Reader point_reader, Point &point)
Helper function that loads point data.
void add_interpolation_points_JxW_all_qp(const std::vector< Real > &JxW_all_qp)
unsigned int get_n_output_terms(unsigned int output_index) const
Get the number of affine terms associated with the specified output.
void set_value(const std::string &param_name, Real value)
Set the value of the specified parameter.
void read_from_file(const std::string &path, bool use_packing=false)
Read the Cap&#39;n&#39;Proto buffer from disk.
This class is part of the rbOOmit framework.
void set_error_indicator_interpolation_row(const DenseVector< Number > &error_indicator_row)
static const bool value
Definition: xdr_io.C:54
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
void set_euler_theta(const Real euler_theta_in)
TransientRBEvaluation & _trans_rb_eval
The TransientRBEvaluation object that we will read into.
void add_interpolation_points_comp(unsigned int comp)
RBEvaluation & _rb_eval
The RBEvaluation object that we will read into.
std::vector< std::vector< std::vector< std::vector< Number > > > > Aq_Mq_representor_innerprods
void set_n_time_steps(const unsigned int K)
void add_interpolation_points_qp(unsigned int qp)
TransientRBEvaluationDeserialization(TransientRBEvaluation &trans_rb_eval)
Initialize a new buffer using the structure from the Cap&#39;n&#39;Proto schema described in rb_data...
RBParametrizedFunction & get_parametrized_function()
Get a reference to the parametrized function.
void initialize_parameters(const RBParameters &mu_min_in, const RBParameters &mu_max_in, const std::map< std::string, std::vector< Real >> &discrete_parameter_values)
Initialize the parameter ranges and set current_parameters.
void add_interpolation_points_spatial_indices(const std::vector< unsigned int > &spatial_indices)
This class enables evaluation of an Empirical Interpolation Method (EIM) approximation.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
void add_elem_center_dxyzdxi(const Point &dxyzdxi)
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117
RBThetaExpansion & get_rb_theta_expansion()
Get a reference to the rb_theta_expansion.
Definition: rb_evaluation.C:85
DenseMatrix< Number > RB_L2_matrix
Dense RB L2 matrix.
void add_interpolation_points_elem_type(ElemType elem_type)
This class is part of the rbOOmit framework.
std::vector< std::vector< std::vector< Number > > > Aq_Aq_representor_innerprods
uint8_t dof_id_type
Definition: id_types.h:67
std::vector< std::vector< DenseVector< Number > > > RB_output_vectors
The vectors storing the RB output vectors.