20 #include "libmesh/libmesh_config.h"
21 #if defined(LIBMESH_HAVE_CAPNPROTO)
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"
35 #include "capnp/serialize.h"
56 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
65 namespace RBDataDeserialization
79 bool read_error_bound_data)
81 LOG_SCOPE(
"read_from_file()",
"RBEvaluationDeserialization");
83 int fd = open(path.c_str(), O_RDONLY);
85 libmesh_error_msg(
"Couldn't open the buffer file: " + path);
88 capnp::ReaderOptions reader_options;
89 reader_options.traversalLimitInWords = std::numeric_limits<uint64_t>::max();
91 std::unique_ptr<capnp::StreamFdMessageReader> message;
94 message = libmesh_make_unique<capnp::StreamFdMessageReader>(fd, reader_options);
98 libmesh_error_msg(
"Failed to open capnp buffer");
101 #ifndef LIBMESH_USE_COMPLEX_NUMBERS
102 RBData::RBEvaluationReal::Reader rb_eval_reader =
103 message->getRoot<RBData::RBEvaluationReal>();
105 RBData::RBEvaluationComplex::Reader rb_eval_reader =
106 message->getRoot<RBData::RBEvaluationComplex>();
111 int error = close(fd);
113 libmesh_error_msg(
"Error closing a read-only file descriptor: " + path);
123 _trans_rb_eval(trans_rb_eval)
130 bool read_error_bound_data)
132 LOG_SCOPE(
"read_from_file()",
"TransientRBEvaluationDeserialization");
134 int fd = open(path.c_str(), O_RDONLY);
136 libmesh_error_msg(
"Couldn't open the buffer file: " + path);
139 capnp::ReaderOptions reader_options;
140 reader_options.traversalLimitInWords = std::numeric_limits<uint64_t>::max();
142 std::unique_ptr<capnp::StreamFdMessageReader> message;
145 message = libmesh_make_unique<capnp::StreamFdMessageReader>(fd, reader_options);
149 libmesh_error_msg(
"Failed to open capnp buffer");
152 #ifndef LIBMESH_USE_COMPLEX_NUMBERS
153 RBData::TransientRBEvaluationReal::Reader trans_rb_eval_reader =
154 message->getRoot<RBData::TransientRBEvaluationReal>();
155 RBData::RBEvaluationReal::Reader rb_eval_reader =
156 trans_rb_eval_reader.getRbEvaluation();
158 RBData::TransientRBEvaluationComplex::Reader trans_rb_eval_reader =
159 message->getRoot<RBData::TransientRBEvaluationComplex>();
160 RBData::RBEvaluationComplex::Reader rb_eval_reader =
161 trans_rb_eval_reader.getRbEvaluation();
166 trans_rb_eval_reader,
167 read_error_bound_data);
169 int error = close(fd);
171 libmesh_error_msg(
"Error closing a read-only file descriptor: " + path);
181 _rb_eim_eval(rb_eim_eval)
189 LOG_SCOPE(
"read_from_file()",
"RBEIMEvaluationDeserialization");
191 int fd = open(path.c_str(), O_RDONLY);
193 libmesh_error_msg(
"Couldn't open the buffer file: " + path);
196 capnp::ReaderOptions reader_options;
197 reader_options.traversalLimitInWords = std::numeric_limits<uint64_t>::max();
199 std::unique_ptr<capnp::StreamFdMessageReader> message;
202 message = libmesh_make_unique<capnp::StreamFdMessageReader>(fd, reader_options);
206 libmesh_error_msg(
"Failed to open capnp buffer");
209 #ifndef LIBMESH_USE_COMPLEX_NUMBERS
210 RBData::RBEIMEvaluationReal::Reader rb_eim_eval_reader =
211 message->getRoot<RBData::RBEIMEvaluationReal>();
212 RBData::RBEvaluationReal::Reader rb_eval_reader =
213 rb_eim_eval_reader.getRbEvaluation();
215 RBData::RBEIMEvaluationComplex::Reader rb_eim_eval_reader =
216 message->getRoot<RBData::RBEIMEvaluationComplex>();
217 RBData::RBEvaluationComplex::Reader rb_eval_reader =
218 rb_eim_eval_reader.getRbEvaluation();
225 int error = close(fd);
227 libmesh_error_msg(
"Error closing a read-only file descriptor: " + path);
237 #if defined(LIBMESH_HAVE_SLEPC) && (LIBMESH_HAVE_GLPK)
241 _rb_scm_eval(rb_scm_eval)
249 LOG_SCOPE(
"read_from_file()",
"RBSCMEvaluationDeserialization");
251 int fd = open(path.c_str(), O_RDONLY);
253 libmesh_error_msg(
"Couldn't open the buffer file: " + path);
256 capnp::ReaderOptions reader_options;
257 reader_options.traversalLimitInWords = std::numeric_limits<uint64_t>::max();
259 std::unique_ptr<capnp::StreamFdMessageReader> message;
262 message = libmesh_make_unique<capnp::StreamFdMessageReader>(fd, reader_options);
266 libmesh_error_msg(
"Failed to open capnp buffer");
269 RBData::RBSCMEvaluation::Reader rb_scm_eval_reader =
270 message->getRoot<RBData::RBSCMEvaluation>();
275 int error = close(fd);
277 libmesh_error_msg(
"Error closing a read-only file descriptor: " + path);
280 #endif // LIBMESH_HAVE_SLEPC && LIBMESH_HAVE_GLPK
288 RBData::ParameterRanges::Reader & parameter_ranges,
289 RBData::DiscreteParameterList::Reader & discrete_parameters_list)
295 unsigned int n_parameter_ranges = parameter_ranges.getNames().size();
297 for (
unsigned int i=0; i<n_parameter_ranges; ++i)
299 std::string parameter_name = parameter_ranges.getNames()[i];
300 Real min_value = parameter_ranges.getMinValues()[i];
301 Real max_value = parameter_ranges.getMaxValues()[i];
303 parameters_min.
set_value(parameter_name, min_value);
304 parameters_max.
set_value(parameter_name, max_value);
309 std::map<std::string, std::vector<Real>> discrete_parameter_values;
311 unsigned int n_discrete_parameters = discrete_parameters_list.getNames().size();
313 for (
unsigned int i=0; i<n_discrete_parameters; ++i)
315 std::string parameter_name = discrete_parameters_list.getNames()[i];
317 auto value_list = discrete_parameters_list.getValues()[i];
318 unsigned int n_values = value_list.size();
319 std::vector<Real> values(n_values);
320 for (
unsigned int j=0; j<n_values; ++j)
321 values[j] = value_list[j];
323 discrete_parameter_values[parameter_name] = values;
329 discrete_parameter_values);
332 template <
typename RBEvaluationReaderNumber>
334 RBEvaluationReaderNumber & rb_evaluation_reader,
335 bool read_error_bound_data)
338 unsigned int n_bfs = rb_evaluation_reader.getNBfs();
343 auto parameter_ranges =
344 rb_evaluation_reader.getParameterRanges();
345 auto discrete_parameters_list =
346 rb_evaluation_reader.getDiscreteParameters();
350 discrete_parameters_list);
357 if (read_error_bound_data)
362 unsigned int Q_f_hat = n_F_terms*(n_F_terms+1)/2;
364 auto fq_innerprods_list = rb_evaluation_reader.getFqInnerprods();
365 if (fq_innerprods_list.size() != Q_f_hat)
366 libmesh_error_msg(
"Size error while reading Fq representor norm data from buffer.");
368 for (
unsigned int i=0; i < Q_f_hat; ++i)
374 auto fq_aq_innerprods_list = rb_evaluation_reader.getFqAqInnerprods();
375 if (fq_aq_innerprods_list.size() != n_F_terms*n_A_terms*n_bfs)
376 libmesh_error_msg(
"Size error while reading Fq-Aq representor norm data from buffer.");
378 for (
unsigned int q_f=0; q_f<n_F_terms; ++q_f)
379 for (
unsigned int q_a=0; q_a<n_A_terms; ++q_a)
380 for (
unsigned int i=0; i<n_bfs; ++i)
382 unsigned int offset = q_f*n_A_terms*n_bfs + q_a*n_bfs + i;
384 load_scalar_value(fq_aq_innerprods_list[offset]);
390 unsigned int Q_a_hat = n_A_terms*(n_A_terms+1)/2;
391 auto aq_aq_innerprods_list = rb_evaluation_reader.getAqAqInnerprods();
392 if (aq_aq_innerprods_list.size() != Q_a_hat*n_bfs*n_bfs)
393 libmesh_error_msg(
"Size error while reading Aq-Aq representor norm data from buffer.");
395 for (
unsigned int i=0; i<Q_a_hat; ++i)
396 for (
unsigned int j=0; j<n_bfs; ++j)
397 for (
unsigned int l=0; l<n_bfs; ++l)
399 unsigned int offset = i*n_bfs*n_bfs + j*n_bfs + l;
401 load_scalar_value(aq_aq_innerprods_list[offset]);
408 auto output_innerprod_outer = rb_evaluation_reader.getOutputDualInnerprods();
410 if (output_innerprod_outer.size() != n_outputs)
411 libmesh_error_msg(
"Incorrect number of outputs detected in the buffer");
413 for (
unsigned int output_id=0; output_id<n_outputs; ++output_id)
417 unsigned int Q_l_hat = n_output_terms*(n_output_terms+1)/2;
418 auto output_innerprod_inner = output_innerprod_outer[output_id];
420 if (output_innerprod_inner.size() != Q_l_hat)
421 libmesh_error_msg(
"Incorrect number of output terms detected in the buffer");
423 for (
unsigned int q=0; q<Q_l_hat; ++q)
426 load_scalar_value(output_innerprod_inner[q]);
435 auto output_vector_outer = rb_evaluation_reader.getOutputVectors();
437 if (output_vector_outer.size() != n_outputs)
438 libmesh_error_msg(
"Incorrect number of outputs detected in the buffer");
440 for (
unsigned int output_id=0; output_id<n_outputs; ++output_id)
444 auto output_vector_middle = output_vector_outer[output_id];
445 if (output_vector_middle.size() != n_output_terms)
446 libmesh_error_msg(
"Incorrect number of output terms detected in the buffer");
448 for (
unsigned int q_l=0; q_l<n_output_terms; ++q_l)
450 auto output_vectors_inner_list = output_vector_middle[q_l];
452 if (output_vectors_inner_list.size() != n_bfs)
453 libmesh_error_msg(
"Incorrect number of output terms detected in the buffer");
455 for (
unsigned int j=0; j<n_bfs; ++j)
458 load_scalar_value(output_vectors_inner_list[j]);
466 auto rb_fq_vectors_outer_list = rb_evaluation_reader.getRbFqVectors();
467 if (rb_fq_vectors_outer_list.size() != n_F_terms)
468 libmesh_error_msg(
"Incorrect number of Fq vectors detected in the buffer");
470 for (
unsigned int q_f=0; q_f<n_F_terms; ++q_f)
472 auto rb_fq_vectors_inner_list = rb_fq_vectors_outer_list[q_f];
473 if (rb_fq_vectors_inner_list.size() != n_bfs)
474 libmesh_error_msg(
"Incorrect Fq vector size detected in the buffer");
476 for (
unsigned int i=0; i < n_bfs; ++i)
479 load_scalar_value(rb_fq_vectors_inner_list[i]);
483 auto rb_Aq_matrices_outer_list = rb_evaluation_reader.getRbAqMatrices();
484 if (rb_Aq_matrices_outer_list.size() != n_A_terms)
485 libmesh_error_msg(
"Incorrect number of Aq matrices detected in the buffer");
487 for (
unsigned int q_a=0; q_a<n_A_terms; ++q_a)
489 auto rb_Aq_matrices_inner_list = rb_Aq_matrices_outer_list[q_a];
490 if (rb_Aq_matrices_inner_list.size() != n_bfs*n_bfs)
491 libmesh_error_msg(
"Incorrect Aq matrix size detected in the buffer");
493 for (
unsigned int i=0; i<n_bfs; ++i)
494 for (
unsigned int j=0; j<n_bfs; ++j)
496 unsigned int offset = i*n_bfs+j;
498 load_scalar_value(rb_Aq_matrices_inner_list[offset]);
506 auto rb_inner_product_matrix_list =
507 rb_evaluation_reader.getRbInnerProductMatrix();
509 if (rb_inner_product_matrix_list.size() != n_bfs*n_bfs)
510 libmesh_error_msg(
"Size error while reading the inner product matrix.");
512 for (
unsigned int i=0; i<n_bfs; ++i)
513 for (
unsigned int j=0; j<n_bfs; ++j)
515 unsigned int offset = i*n_bfs + j;
517 load_scalar_value(rb_inner_product_matrix_list[offset]);
522 template <
typename RBEvaluationReaderNumber,
typename TransRBEvaluationReaderNumber>
524 RBEvaluationReaderNumber & rb_eval_reader,
525 TransRBEvaluationReaderNumber & trans_rb_eval_reader,
526 bool read_error_bound_data)
530 read_error_bound_data);
532 trans_rb_eval.
set_delta_t( trans_rb_eval_reader.getDeltaT() );
535 trans_rb_eval.
set_time_step( trans_rb_eval_reader.getTimeStep() );
537 unsigned int n_bfs = rb_eval_reader.getNBfs();
543 unsigned int n_M_terms = trans_theta_expansion.
get_n_M_terms();
547 auto rb_L2_matrix_list =
548 trans_rb_eval_reader.getRbL2Matrix();
550 if (rb_L2_matrix_list.size() != n_bfs*n_bfs)
551 libmesh_error_msg(
"Size error while reading the L2 matrix.");
553 for (
unsigned int i=0; i<n_bfs; ++i)
554 for (
unsigned int j=0; j<n_bfs; ++j)
556 unsigned int offset = i*n_bfs + j;
558 load_scalar_value(rb_L2_matrix_list[offset]);
564 auto rb_Mq_matrices_outer_list = trans_rb_eval_reader.getRbMqMatrices();
566 if (rb_Mq_matrices_outer_list.size() != n_M_terms)
567 libmesh_error_msg(
"Incorrect number of Mq matrices detected in the buffer");
569 for (
unsigned int q_m=0; q_m < n_M_terms; ++q_m)
571 auto rb_Mq_matrices_inner_list = rb_Mq_matrices_outer_list[q_m];
572 if (rb_Mq_matrices_inner_list.size() != n_bfs*n_bfs)
573 libmesh_error_msg(
"Incorrect Mq matrix size detected in the buffer");
575 for (
unsigned int i=0; i<n_bfs; ++i)
576 for (
unsigned int j=0; j<n_bfs; ++j)
578 unsigned int offset = i*n_bfs+j;
580 load_scalar_value(rb_Mq_matrices_inner_list[offset]);
587 auto initial_l2_errors_reader =
588 trans_rb_eval_reader.getInitialL2Errors();
589 if (initial_l2_errors_reader.size() != n_bfs)
590 libmesh_error_msg(
"Incorrect number of initial L2 error terms detected in the buffer");
592 auto initial_conditions_outer_list =
593 trans_rb_eval_reader.getInitialConditions();
594 if (initial_conditions_outer_list.size() != n_bfs)
595 libmesh_error_msg(
"Incorrect number of outer initial conditions detected in the buffer");
597 for (
unsigned int i=0; i<n_bfs; i++)
600 initial_l2_errors_reader[i];
602 auto initial_conditions_inner_list = initial_conditions_outer_list[i];
603 if (initial_conditions_inner_list.size() != (i+1))
604 libmesh_error_msg(
"Incorrect number of inner initial conditions detected in the buffer");
606 for (
unsigned int j=0; j<=i; j++)
609 load_scalar_value(initial_conditions_inner_list[j]);
615 if (read_error_bound_data)
619 auto fq_mq_innerprods_list = trans_rb_eval_reader.getFqMqInnerprods();
620 if (fq_mq_innerprods_list.size() != n_F_terms*n_M_terms*n_bfs)
621 libmesh_error_msg(
"Size error while reading Fq-Mq representor data from buffer.");
623 for (
unsigned int q_f=0; q_f<n_F_terms; ++q_f)
624 for (
unsigned int q_m=0; q_m<n_M_terms; ++q_m)
625 for (
unsigned int i=0; i<n_bfs; ++i)
627 unsigned int offset = q_f*n_M_terms*n_bfs + q_m*n_bfs + i;
629 load_scalar_value(fq_mq_innerprods_list[offset]);
636 unsigned int Q_m_hat = n_M_terms*(n_M_terms+1)/2;
637 auto mq_mq_innerprods_list = trans_rb_eval_reader.getMqMqInnerprods();
638 if (mq_mq_innerprods_list.size() != Q_m_hat*n_bfs*n_bfs)
639 libmesh_error_msg(
"Size error while reading Mq-Mq representor data from buffer.");
641 for (
unsigned int i=0; i<Q_m_hat; ++i)
642 for (
unsigned int j=0; j<n_bfs; ++j)
643 for (
unsigned int l=0; l<n_bfs; ++l)
645 unsigned int offset = i*n_bfs*n_bfs + j*n_bfs + l;
647 load_scalar_value(mq_mq_innerprods_list[offset]);
653 auto aq_mq_innerprods_list =
654 trans_rb_eval_reader.getAqMqInnerprods();
655 if (aq_mq_innerprods_list.size() != n_A_terms*n_M_terms*n_bfs*n_bfs)
656 libmesh_error_msg(
"Size error while reading Aq-Mq representor data from buffer.");
658 for (
unsigned int q_a=0; q_a<n_A_terms; q_a++)
659 for (
unsigned int q_m=0; q_m<n_M_terms; q_m++)
660 for (
unsigned int i=0; i<n_bfs; i++)
661 for (
unsigned int j=0; j<n_bfs; j++)
663 unsigned int offset =
664 q_a*(n_M_terms*n_bfs*n_bfs) + q_m*(n_bfs*n_bfs) + i*n_bfs + j;
667 load_scalar_value(aq_mq_innerprods_list[offset]);
674 template <
typename RBEvaluationReaderNumber,
typename RBEIMEvaluationReaderNumber>
676 RBEvaluationReaderNumber & rb_evaluation_reader,
677 RBEIMEvaluationReaderNumber & rb_eim_evaluation_reader)
682 rb_evaluation_reader,
689 auto interpolation_matrix_list = rb_eim_evaluation_reader.getInterpolationMatrix();
691 if (interpolation_matrix_list.size() != n_bfs*(n_bfs+1)/2)
692 libmesh_error_msg(
"Size error while reading the eim inner product matrix.");
694 for (
unsigned int i=0; i<n_bfs; ++i)
695 for (
unsigned int j=0; j<=i; ++j)
697 unsigned int offset = i*(i+1)/2 + j;
699 load_scalar_value(interpolation_matrix_list[offset]);
705 auto interpolation_points_list =
706 rb_eim_evaluation_reader.getInterpolationPoints();
708 if (interpolation_points_list.size() != n_bfs)
709 libmesh_error_msg(
"Size error while reading the eim interpolation points.");
712 for (
unsigned int i=0; i<n_bfs; ++i)
721 auto interpolation_points_var_list =
722 rb_eim_evaluation_reader.getInterpolationPointsVar();
725 if (interpolation_points_var_list.size() != n_bfs)
726 libmesh_error_msg(
"Size error while reading the eim interpolation variables.");
728 for (
unsigned int i=0; i<n_bfs; ++i)
731 interpolation_points_var_list[i];
740 interpolation_points_mesh.
clear();
742 auto interpolation_points_elem_list =
743 rb_eim_evaluation_reader.getInterpolationPointsElems();
744 unsigned int n_interpolation_elems = interpolation_points_elem_list.size();
746 if (n_interpolation_elems != n_bfs)
747 libmesh_error_msg(
"The number of elements should match the number of basis functions");
751 for (
unsigned int i=0; i<n_interpolation_elems; ++i)
753 auto mesh_elem_reader = interpolation_points_elem_list[i];
754 std::string elem_type_name = mesh_elem_reader.getType().cStr();
756 libMesh::Utility::string_to_enum<libMesh::ElemType>(elem_type_name);
767 #if defined(LIBMESH_HAVE_SLEPC) && (LIBMESH_HAVE_GLPK)
769 RBData::RBSCMEvaluation::Reader & rb_scm_evaluation_reader)
771 auto parameter_ranges =
772 rb_scm_evaluation_reader.getParameterRanges();
773 auto discrete_parameters_list =
774 rb_scm_evaluation_reader.getDiscreteParameters();
777 discrete_parameters_list);
782 auto b_min_list = rb_scm_evaluation_reader.getBMin();
784 if (b_min_list.size() != n_A_terms)
785 libmesh_error_msg(
"Size error while reading B_min");
787 rb_scm_eval.
B_min.clear();
788 for (
unsigned int i=0; i<n_A_terms; i++)
789 rb_scm_eval.
B_min.push_back(b_min_list[i]);
793 auto b_max_list = rb_scm_evaluation_reader.getBMax();
795 if (b_max_list.size() != n_A_terms)
796 libmesh_error_msg(
"Size error while reading B_max");
798 rb_scm_eval.
B_max.clear();
799 for (
unsigned int i=0; i<n_A_terms; i++)
800 rb_scm_eval.
B_max.push_back(b_max_list[i]);
804 auto cJ_stability_vector =
805 rb_scm_evaluation_reader.getCJStabilityVector();
808 for (
const auto & val : cJ_stability_vector)
813 auto cJ_parameters_outer =
814 rb_scm_evaluation_reader.getCJ();
816 rb_scm_eval.
C_J.resize(cJ_parameters_outer.size());
819 auto cJ_parameters_inner =
820 cJ_parameters_outer[i];
824 std::string param_name = cJ_parameters_inner[j].getName();
825 Real param_value = cJ_parameters_inner[j].getValue();
826 rb_scm_eval.
C_J[i].set_value(param_name, param_value);
832 auto scm_ub_vectors =
833 rb_scm_evaluation_reader.getScmUbVectors();
836 unsigned int n_C_J_values = rb_scm_evaluation_reader.getCJ().size();
838 if (scm_ub_vectors.size() != n_C_J_values*n_A_terms)
839 libmesh_error_msg(
"Size mismatch in SCB UB vectors");
842 for (
unsigned int i=0; i<n_C_J_values; i++)
845 for (
unsigned int j=0; j<n_A_terms; j++)
847 unsigned int offset = i*n_A_terms + j;
855 #endif // LIBMESH_HAVE_SLEPC && LIBMESH_HAVE_GLPK
861 point(0) = point_reader.getX();
863 if (LIBMESH_DIM >= 2)
864 point(1) = point_reader.getY();
866 if (LIBMESH_DIM >= 3)
867 point(2) = point_reader.getZ();
875 auto mesh_elem_point_list = mesh_elem_reader.getPoints();
876 unsigned int n_points = mesh_elem_point_list.size();
878 if (n_points != elem->
n_nodes())
879 libmesh_error_msg(
"Wrong number of nodes for element type");
881 for (
unsigned int i=0; i < n_points; ++i)
884 mesh_elem_point_list[i].getY(),
885 mesh_elem_point_list[i].getZ());
892 elem->
subdomain_id() = mesh_elem_reader.getSubdomainId();
903 #endif // #if defined(LIBMESH_HAVE_CAPNPROTO)