libMesh
Loading...
Searching...
No Matches
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
48namespace libMesh
49{
50
51namespace
52{
53
58template <typename T>
59Number 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
70namespace RBDataDeserialization
71{
72
73// ---- RBEvaluationDeserialization (BEGIN) ----
74
79
81
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
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
346template <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
536template <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
688template <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
1397void 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)
Defines a dense vector for use in Finite Element-type computations.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
void read_from_file(const std::string &path, bool use_packing=false)
Read the Cap'n'Proto buffer from disk.
RBEIMEvaluation & _rb_eim_eval
The RBEIMEvaluation object we will read into.
RBEIMEvaluationDeserialization(RBEIMEvaluation &trans_rb_eval)
Initialize a new buffer using the structure from the Cap'n'Proto schema described in rb_data....
RBEvaluation & _rb_eval
The RBEvaluation object that we will read into.
void read_from_file(const std::string &path, bool read_error_bound_data, bool use_packing=false)
Read the Cap'n'Proto buffer from disk.
RBEvaluationDeserialization(RBEvaluation &rb_eval)
Initialize a new buffer using the structure from the Cap'n'Proto schema described in rb_data....
RBSCMEvaluation & _rb_scm_eval
The RBSCMEvaluation object we will read into.
RBSCMEvaluationDeserialization(RBSCMEvaluation &trans_rb_eval)
Initialize a new buffer using the structure from the Cap'n'Proto schema described in rb_data....
void read_from_file(const std::string &path, bool use_packing=false)
Read the Cap'n'Proto buffer from disk.
TransientRBEvaluation & _trans_rb_eval
The TransientRBEvaluation object that we will read into.
void read_from_file(const std::string &path, bool read_error_bound_data, bool use_packing=false)
Read the Cap'n'Proto buffer from disk.
TransientRBEvaluationDeserialization(TransientRBEvaluation &trans_rb_eval)
Initialize a new buffer using the structure from the Cap'n'Proto schema described in rb_data....
This class enables evaluation of an Empirical Interpolation Method (EIM) approximation.
void add_interpolation_points_subdomain_id(subdomain_id_type sbd_id)
void add_interpolation_points_comp(unsigned int comp)
void add_interpolation_points_phi_i_all_qp(const std::vector< std::vector< Real > > &phi_i_all_qp)
void add_rb_property_map_entry(std::string &property_name, std::set< dof_id_type > &entity_ids)
void add_interpolation_points_xyz_perturbations(const std::vector< Point > &perturbs)
void add_interpolation_points_side_index(unsigned int side_index)
void add_interpolation_points_elem_type(ElemType elem_type)
void add_interpolation_points_boundary_id(boundary_id_type b_id)
void add_interpolation_points_qp(unsigned int qp)
void add_interpolation_points_elem_id(dof_id_type elem_id)
void set_error_indicator_interpolation_row(const DenseVector< Number > &error_indicator_row)
void set_n_basis_functions(unsigned int n_bfs)
Set the number of basis functions.
void add_interpolation_points_xyz(Point p)
Set the data associated with EIM interpolation points.
void add_interpolation_points_phi_i_qp(const std::vector< Real > &phi_i_qp)
void resize_data_structures(const unsigned int Nmax)
Resize the data structures for storing data associated with this object.
void add_interpolation_points_spatial_indices(const std::vector< unsigned int > &spatial_indices)
void add_elem_id_local_index_map_entry(dof_id_type elem_id, unsigned int local_index)
void set_interpolation_matrix_entry(unsigned int i, unsigned int j, Number value)
Set entry of the EIM interpolation matrix.
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 add_interpolation_points_qrule_order(Order qrule_order)
void add_elem_center_dxyzdxi(const Point &dxyzdxi)
void add_elem_center_dxyzdeta(const Point &dxyzdxi)
void add_interpolation_points_node_id(dof_id_type node_id)
void initialize_param_fn_spatial_indices()
The Online counterpart of initialize_interpolation_points_spatial_indices().
RBParametrizedFunction & get_parametrized_function()
Get a reference to the parametrized function.
void add_interpolation_points_JxW_all_qp(const std::vector< Real > &JxW_all_qp)
This class is part of the rbOOmit framework.
DenseMatrix< Number > RB_inner_product_matrix
The inner product matrix.
std::vector< Number > Fq_representor_innerprods
Vectors storing the residual representor inner products to be used in computing the residuals online.
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.
bool compute_RB_inner_product
Boolean flag to indicate whether we compute the RB_inner_product_matrix.
virtual void set_n_basis_functions(unsigned int n_bfs)
Set the number of basis functions.
std::vector< std::vector< std::vector< Number > > > Aq_Aq_representor_innerprods
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< std::vector< DenseVector< Number > > > RB_output_vectors
The vectors storing the RB output vectors.
RBThetaExpansion & get_rb_theta_expansion()
Get a reference to the rb_theta_expansion.
std::vector< std::vector< Number > > output_dual_innerprods
The vector storing the dual norm inner product terms for each output.
std::vector< DenseVector< Number > > RB_Fq_vector
Dense vector for the RHS.
std::vector< DenseMatrix< Number > > RB_Aq_vector
Dense matrices for the RB computations.
This class is part of the rbOOmit framework.
void set_value(const std::string &param_name, Real value)
Set the value of the specified parameter.
bool is_lookup_table
Boolean to indicate if this parametrized function is defined based on a lookup table or not.
This class is part of the rbOOmit framework.
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.
This class is part of the rbOOmit framework.
std::vector< Real > B_max
RBThetaExpansion & get_rb_theta_expansion()
Get a reference to the rb_theta_expansion.
std::vector< Real > C_J_stability_vector
Vector storing the (truth) stability values at the parameters in C_J.
std::vector< Real > B_min
B_min, B_max define the bounding box.
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< RBParameters > C_J
Vector storing the greedily selected parameters during SCM training.
void set_euler_theta(const Real euler_theta_in)
This class stores the set of RBTheta functor objects that define the "parameter-dependent expansion" ...
unsigned int get_n_F_terms() const
Get Q_f, the number of terms in the affine expansion for the right-hand side.
unsigned int get_n_A_terms() const
Get Q_a, the number of terms in the affine expansion for the bilinear form.
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_n_outputs() const
Get n_outputs, the number output functionals.
This class is part of the rbOOmit framework.
std::vector< std::vector< std::vector< std::vector< Number > > > > Aq_Mq_representor_innerprods
std::vector< std::vector< std::vector< Number > > > Mq_Mq_representor_innerprods
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.
DenseMatrix< Number > RB_L2_matrix
Dense RB L2 matrix.
std::vector< Real > initial_L2_error_all_N
Vector storing initial L2 error for all 1 <= N <= RB_size.
std::vector< DenseMatrix< Number > > RB_M_q_vector
Dense matrices for the RB mass matrices.
std::vector< DenseVector< Number > > RB_initial_condition_all_N
The RB initial conditions (i.e.
This class stores the set of RBTheta functor objects that define the "parameter-dependent expansion" ...
virtual unsigned int get_n_M_terms() const
Get Q_m, the number of terms in the affine expansion for the mass operator.
void load_point(RBData::Point3D::Reader point_reader, Point &point)
Helper function that loads point data.
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.
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.
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.
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 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...
The libMesh namespace provides an interface to certain functionality in the library.
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:153
ElemType
Defines an enum for geometric element types.
uint8_t dof_id_type
Definition id_types.h:67
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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:176
static const bool value
Definition xdr_io.C:55