21#include "libmesh/rb_eim_evaluation.h"
22#include "libmesh/rb_eim_theta.h"
23#include "libmesh/rb_parametrized_function.h"
24#include "libmesh/rb_evaluation.h"
25#include "libmesh/utility.h"
28#include "libmesh/xdr_cxx.h"
29#include "libmesh/libmesh_logging.h"
30#include "libmesh/replicated_mesh.h"
31#include "libmesh/elem.h"
32#include "libmesh/system.h"
33#include "libmesh/equation_systems.h"
34#include "libmesh/numeric_vector.h"
35#include "libmesh/quadrature.h"
36#include "libmesh/boundary_info.h"
52limit_eim_error_indicator_to_one(true),
54_preserve_rb_eim_solutions(false),
55_is_eim_error_indicator_active(false)
108 LOG_SCOPE(
"rb_eim_solve()",
"RBEIMEvaluation");
111 "Error: N cannot be larger than the number of basis functions in rb_solve");
113 libmesh_error_msg_if(EIM_rhs.
size()==0,
"Error: N must be greater than 0 in rb_solve");
115 const unsigned int N = EIM_rhs.
size();
120 interpolation_matrix_N.
lu_solve(EIM_rhs, rb_eim_solution);
122 return rb_eim_solution;
139 "Error: N cannot be larger than the number of basis functions in rb_eim_solves");
140 libmesh_error_msg_if(N==0,
"Error: N must be greater than 0 in rb_eim_solves");
146 LOG_SCOPE(
"rb_eim_solves()",
"RBEIMEvaluation");
156 Real lookup_table_param =
161 unsigned int lookup_table_index =
162 cast_int<unsigned int>(std::round(lookup_table_param));
174 std::vector<std::vector<std::vector<Number>>> output_all_comps;
186 auto n_samples_0 = mus[0].n_samples();
187 for (
const auto & mu : mus)
188 libmesh_error_msg_if(mu.n_samples() != n_samples_0,
"All RBParameters objects must have same n_samples()");
193 unsigned int num_rb_eim_solves = mus.size() * n_samples_0;
200 if (num_rb_eim_solves == 0 && mus[0].n_parameters() == 0)
202 libmesh_error_msg_if(mus.size() != 1,
"Must pass in only a single RBParameters object when solving with no parameters.");
203 num_rb_eim_solves = 1;
206 std::vector<std::vector<Number>> evaluated_values_at_interp_points(num_rb_eim_solves);
208 std::vector<Number> evaluated_values_at_err_indicator_point;
210 evaluated_values_at_err_indicator_point.resize(num_rb_eim_solves);
216 unsigned int counter = 0;
218 for (
auto sample_index :
make_range(mus[mu_index].n_samples()))
223 evaluated_values_at_interp_points[counter].resize(N);
225 for (
unsigned int interp_pt_index=0; interp_pt_index<N; interp_pt_index++)
231 evaluated_values_at_interp_points[counter][interp_pt_index] =
232 output_all_comps[counter][interp_pt_index][comp];
239 evaluated_values_at_err_indicator_point[counter] =
240 output_all_comps[counter][N][comp];
248 libmesh_error_msg_if(counter != num_rb_eim_solves,
249 "We should have done " << num_rb_eim_solves <<
250 " solves, instead we did " << counter);
264 unsigned int counter = 0;
266 for (
auto sample_index :
make_range(mus[mu_index].n_samples()))
280 Number error_indicator_rhs = evaluated_values_at_err_indicator_point[counter];
343 LOG_SCOPE(
"decrement_vector()",
"RBEIMEvaluation");
346 "Error: Number of coefficients should match number of basis functions");
348 for (
auto & [elem_id, v_comp_and_qp] : v)
350 for (
const auto & comp :
index_range(v_comp_and_qp))
351 for (
unsigned int qp :
index_range(v_comp_and_qp[comp]))
358 libmesh_error_msg_if(comp >= basis_comp_and_qp.size(),
"Error: Invalid comp");
359 libmesh_error_msg_if(qp >= basis_comp_and_qp[comp].size(),
"Error: Invalid qp");
361 v_comp_and_qp[comp][qp] -= coeffs(i) * basis_comp_and_qp[comp][qp];
369 LOG_SCOPE(
"side_decrement_vector()",
"RBEIMEvaluation");
372 "Error: Number of coefficients should match number of basis functions");
374 for (
auto & [elem_and_side, v_comp_and_qp] : v)
376 for (
const auto & comp :
index_range(v_comp_and_qp))
377 for (
unsigned int qp :
index_range(v_comp_and_qp[comp]))
384 libmesh_error_msg_if(comp >= basis_comp_and_qp.size(),
"Error: Invalid comp");
385 libmesh_error_msg_if(qp >= basis_comp_and_qp[comp].size(),
"Error: Invalid qp");
387 v_comp_and_qp[comp][qp] -= coeffs(i) * basis_comp_and_qp[comp][qp];
395 LOG_SCOPE(
"node_decrement_vector()",
"RBEIMEvaluation");
398 "Error: Number of coefficients should match number of basis functions");
400 for (
auto & [node_id, v_comps] : v)
409 libmesh_error_msg_if(comp >= basis_comp.size(),
"Error: Invalid comp");
411 v_comps[comp] -= coeffs(i) * basis_comp[comp];
431 return std::make_unique<RBEIMTheta>(*
this, index);
438 std::vector<Number> & values)
440 LOG_SCOPE(
"get_parametrized_function_values_at_qps()",
"RBEIMConstruction");
444 if (
const auto it = pf.find(elem_id);
447 const auto & comps_and_qps_on_elem = it->second;
448 libmesh_error_msg_if(comp >= comps_and_qps_on_elem.size(),
449 "Invalid comp index: " << comp);
451 values = comps_and_qps_on_elem[comp];
458 unsigned int side_index,
460 std::vector<Number> & values)
462 LOG_SCOPE(
"get_parametrized_function_side_values_at_qps()",
"RBEIMConstruction");
466 if (
const auto it = pf.find(std::make_pair(elem_id, side_index));
469 const auto & comps_and_qps_on_elem = it->second;
470 libmesh_error_msg_if(comp >= comps_and_qps_on_elem.size(),
471 "Invalid comp index: " << comp);
473 values = comps_and_qps_on_elem[comp];
482 LOG_SCOPE(
"get_parametrized_function_node_local_value()",
"RBEIMConstruction");
484 if (
const auto it = pf.find(node_id);
487 const std::vector<Number> & vec = it->second;
488 libmesh_error_msg_if (comp >= vec.size(),
"Error: Invalid comp index");
502 std::vector<Number> values;
509 libmesh_error_msg_if(qp >= values.size(),
"Error: Invalid qp index");
522 unsigned int side_index,
526 std::vector<Number> values;
533 libmesh_error_msg_if(qp >= values.size(),
"Error: Invalid qp index");
548 LOG_SCOPE(
"get_parametrized_function_node_value()",
"RBEIMConstruction");
559 std::vector<Number> & values)
const
562 "Invalid basis function index: " << basis_function_index);
573 unsigned int side_index,
575 std::vector<Number> & values)
const
578 "Invalid basis function index: " << basis_function_index);
590 unsigned int comp)
const
593 "Invalid basis function index: " << basis_function_index);
603 unsigned int comp)
const
606 "Invalid basis function index: " << basis_function_index);
618 unsigned int qp)
const
621 "Invalid basis function index: " << basis_function_index);
633 unsigned int side_index,
635 unsigned int qp)
const
638 "Invalid side basis function index: " << basis_function_index);
679 LOG_SCOPE(
"get_rb_eim_solutions_entries()",
"RBEIMEvaluation");
685 "Error: Requested solution index " << index <<
690 return rb_eim_solutions_entries;
797 libmesh_error_msg_if(!insert_succeed,
"Entry already added, duplicate detected.");
803 libmesh_error_msg_if(!insert_succeed,
"Entry already added, duplicate detected.");
943 "Error: Invalid matrix indices");
975 const std::vector<Point> & perturbs,
976 const std::vector<Real> & phi_i_qp,
978 const std::vector<Real> & JxW_all_qp,
979 const std::vector<std::vector<Real>> & phi_i_all_qp,
981 const Point & dxyzdxi_elem_center,
982 const Point & dxyzdeta_elem_center)
1028 unsigned int side_index,
1032 const std::vector<Point> & perturbs,
1033 const std::vector<Real> & phi_i_qp)
1090 bool write_binary_basis_functions)
1092 LOG_SCOPE(
"write_out_basis_functions()",
"RBEIMEvaluation");
1104 bool write_binary_basis_functions)
1106 LOG_SCOPE(
"write_out_interior_basis_functions()",
"RBEIMEvaluation");
1124 std::vector<unsigned int> n_qp_per_elem;
1125 auto interior_basis_function_sizes =
1132 std::ostringstream file_name;
1133 const std::string basis_function_suffix = (write_binary_basis_functions ?
".xdr" :
".dat");
1134 file_name << directory_name <<
"/" <<
"bf_data" << basis_function_suffix;
1137 Xdr xdr(file_name.str(), write_binary_basis_functions ?
ENCODE :
WRITE);
1142 auto n_bf = libmesh_map_find(interior_basis_function_sizes,
"n_bf");
1143 xdr.data(n_bf,
"# Number of basis functions");
1148 auto n_elem = libmesh_map_find(interior_basis_function_sizes,
"n_elem");
1149 xdr.data(n_elem,
"# Number of elements");
1154 auto n_vars = libmesh_map_find(interior_basis_function_sizes,
"n_vars");
1155 xdr.data(
n_vars,
"# Number of variables");
1160 xdr.data(n_qp_per_elem,
"# Number of QPs per Elem");
1164 auto n_qp_data = libmesh_map_find(interior_basis_function_sizes,
"n_qp_data");
1176 xdr.data_stream(qp_data[var].data(), qp_data[var].size(), qp_data[var].size());
1184 std::map<std::string,std::size_t> interior_basis_function_sizes;
1190 interior_basis_function_sizes[
"n_bf"] = n_bf;
1196 interior_basis_function_sizes[
"n_elem"] = n_elem;
1202 interior_basis_function_sizes[
"n_vars"] =
n_vars;
1207 n_qp_per_elem.clear();
1208 n_qp_per_elem.reserve(n_elem);
1216 libmesh_error_msg_if(actual_elem_id != expected_elem_id++,
1217 "RBEIMEvaluation currently assumes a contiguous Elem numbering starting from 0.");
1221 n_qp_per_elem.push_back(array[0].size());
1227 std::accumulate(n_qp_per_elem.begin(),
1228 n_qp_per_elem.end(),
1230 interior_basis_function_sizes[
"n_qp_data"] = n_qp_data;
1232 return interior_basis_function_sizes;
1238 unsigned int n_qp_data,
1239 unsigned int bf_index)
1241 LOG_SCOPE(
"get_interior_basis_function_as_vec_helper()",
"RBEIMEvaluation");
1243 std::vector<std::vector<Number>> qp_data(
n_vars);
1248 qp_data[var].reserve(n_qp_data);
1259 const auto & array = pr.second;
1263 qp_data[var].insert(qp_data[var].end(),
1275 LOG_SCOPE(
"get_interior_basis_function_as_vec()",
"RBEIMEvaluation");
1277 std::vector<std::vector<std::vector<Number>>> interior_basis_functions;
1285 return interior_basis_functions;
1294 std::vector<unsigned int> n_qp_per_elem;
1295 std::map<std::string,std::size_t> interior_basis_function_sizes =
1299 interior_basis_functions.emplace_back(
1301 libmesh_map_find(interior_basis_function_sizes,
"n_vars"),
1302 libmesh_map_find(interior_basis_function_sizes,
"n_qp_data"),
1306 return interior_basis_functions;
1311 bool write_binary_basis_functions)
1313 LOG_SCOPE(
"write_out_side_basis_functions()",
"RBEIMEvaluation");
1335 std::ostringstream file_name;
1336 const std::string basis_function_suffix = (write_binary_basis_functions ?
".xdr" :
".dat");
1337 file_name << directory_name <<
"/" <<
"bf_data" << basis_function_suffix;
1340 Xdr xdr(file_name.str(), write_binary_basis_functions ?
ENCODE :
WRITE);
1346 xdr.
data(n_bf,
"# Number of basis functions");
1352 xdr.data(n_elem,
"# Number of (elem,side) pairs");
1358 xdr.data(
n_vars,
"# Number of variables");
1364 std::vector<unsigned int> n_qp_per_elem_side;
1365 std::vector<unsigned int> elem_ids;
1366 std::vector<unsigned int> side_indices;
1367 elem_ids.reserve(n_elem);
1368 side_indices.reserve(n_elem);
1369 n_qp_per_elem_side.reserve(n_elem);
1372 elem_ids.push_back(elem_side_pair.first);
1373 side_indices.push_back(elem_side_pair.second);
1377 n_qp_per_elem_side.push_back(array[0].size());
1379 xdr.data(elem_ids,
"# Elem IDs");
1380 xdr.data(side_indices,
"# Side indices");
1381 xdr.data(n_qp_per_elem_side,
"# Number of QPs per Elem");
1386 std::accumulate(n_qp_per_elem_side.begin(),
1387 n_qp_per_elem_side.end(),
1391 std::vector<std::vector<Number>> qp_data(
n_vars);
1393 qp_data[var].reserve(n_qp_data);
1403 qp_data[var].
clear();
1408 const auto & array = pr.second;
1412 qp_data[var].insert(qp_data[var].end(),
1420 xdr.data_stream(qp_data[var].data(), qp_data[var].size(), qp_data[var].size());
1427 bool write_binary_basis_functions)
1429 LOG_SCOPE(
"write_out_node_basis_functions()",
"RBEIMEvaluation");
1451 std::ostringstream file_name;
1452 const std::string basis_function_suffix = (write_binary_basis_functions ?
".xdr" :
".dat");
1453 file_name << directory_name <<
"/" <<
"bf_data" << basis_function_suffix;
1456 Xdr xdr(file_name.str(), write_binary_basis_functions ?
ENCODE :
WRITE);
1462 xdr.
data(n_bf,
"# Number of basis functions");
1468 xdr.data(n_node,
"# Number of nodes");
1474 xdr.data(
n_vars,
"# Number of variables");
1478 std::vector<unsigned int> node_ids;
1479 node_ids.reserve(n_node);
1482 node_ids.push_back(pr.first);
1484 xdr.data(node_ids,
"# Node IDs");
1491 std::vector<std::vector<Number>> var_data(
n_vars);
1492 for (
unsigned int var=0; var<
n_vars; var++)
1493 var_data[var].resize(n_node);
1497 unsigned int node_counter = 0;
1501 const auto & array = pr.second;
1507 var_data[var][node_counter] = array[var];
1515 xdr.data_stream(var_data[var].data(), var_data[var].size(), var_data[var].size());
1522 const std::string & directory_name,
1523 bool read_binary_basis_functions)
1525 LOG_SCOPE(
"read_in_basis_functions()",
"RBEIMEvaluation");
1541 const std::string & directory_name,
1542 bool read_binary_basis_functions)
1544 LOG_SCOPE(
"read_in_interior_basis_functions()",
"RBEIMEvaluation");
1550 std::ostringstream file_name;
1551 const std::string basis_function_suffix = (read_binary_basis_functions ?
".xdr" :
".dat");
1552 file_name << directory_name <<
"/" <<
"bf_data" << basis_function_suffix;
1555 Xdr xdr(file_name.str(), read_binary_basis_functions ?
DECODE :
READ);
1573 std::vector<unsigned int> n_qp_per_elem(n_elem);
1574 xdr.data(n_qp_per_elem);
1579 std::accumulate(n_qp_per_elem.begin(),
1580 n_qp_per_elem.end(),
1592 for (std::size_t elem_id=0; elem_id<n_elem; ++elem_id)
1599 std::vector<Number> qp_data;
1607 for (std::size_t var=0; var<
n_vars; ++var)
1610 qp_data.resize(n_qp_data);
1615 xdr.data_stream(qp_data.data(), qp_data.size());
1619 auto cursor = qp_data.begin();
1620 for (std::size_t elem_id=0; elem_id<n_elem; ++elem_id)
1626 auto & array = bf_map[elem_id];
1627 array[var].assign(cursor, cursor + n_qp_per_elem[elem_id]);
1628 std::advance(cursor, n_qp_per_elem[elem_id]);
1640 const std::string & directory_name,
1641 bool read_binary_basis_functions)
1643 LOG_SCOPE(
"read_in_basis_functions()",
"RBEIMEvaluation");
1649 std::ostringstream file_name;
1650 const std::string basis_function_suffix = (read_binary_basis_functions ?
".xdr" :
".dat");
1651 file_name << directory_name <<
"/" <<
"bf_data" << basis_function_suffix;
1654 Xdr xdr(file_name.str(), read_binary_basis_functions ?
DECODE :
READ);
1662 std::size_t n_elem_side;
1663 xdr.data(n_elem_side);
1669 std::vector<unsigned int> elem_ids(n_elem_side);
1671 std::vector<unsigned int> side_indices(n_elem_side);
1672 xdr.data(side_indices);
1677 std::vector<unsigned int> n_qp_per_elem_side(n_elem_side);
1678 xdr.data(n_qp_per_elem_side);
1683 std::accumulate(n_qp_per_elem_side.begin(),
1684 n_qp_per_elem_side.end(),
1692 for (std::size_t elem_side_idx=0; elem_side_idx<n_elem_side; ++elem_side_idx)
1694 unsigned int elem_id = elem_ids[elem_side_idx];
1695 unsigned int side_index = side_indices[elem_side_idx];
1696 auto elem_side_pair = std::make_pair(elem_id, side_index);
1703 std::vector<Number> qp_data;
1711 for (std::size_t var=0; var<
n_vars; ++var)
1714 qp_data.resize(n_qp_data);
1719 xdr.data_stream(qp_data.data(), qp_data.size());
1723 auto cursor = qp_data.begin();
1724 for (std::size_t elem_side_idx=0; elem_side_idx<n_elem_side; ++elem_side_idx)
1726 unsigned int elem_id = elem_ids[elem_side_idx];
1727 unsigned int side_index = side_indices[elem_side_idx];
1728 auto elem_side_pair = std::make_pair(elem_id, side_index);
1734 auto & array = bf_map[elem_side_pair];
1735 array[var].assign(cursor, cursor + n_qp_per_elem_side[elem_side_idx]);
1736 std::advance(cursor, n_qp_per_elem_side[elem_side_idx]);
1748 const std::string & directory_name,
1749 bool read_binary_basis_functions)
1751 LOG_SCOPE(
"read_in_node_basis_functions()",
"RBEIMEvaluation");
1757 std::ostringstream file_name;
1758 const std::string basis_function_suffix = (read_binary_basis_functions ?
".xdr" :
".dat");
1759 file_name << directory_name <<
"/" <<
"bf_data" << basis_function_suffix;
1762 Xdr xdr(file_name.str(), read_binary_basis_functions ?
DECODE :
READ);
1777 std::vector<unsigned int> node_ids(n_node);
1789 for (
auto node_id : node_ids)
1796 std::vector<Number> node_value;
1804 for (std::size_t var=0; var<
n_vars; ++var)
1807 node_value.resize(n_node);
1812 xdr.data_stream(node_value.data(), node_value.size());
1814 for (
unsigned int node_counter=0; node_counter<n_node; node_counter++)
1816 auto & array = bf_map[node_ids[node_counter]];
1817 array[var] = node_value[node_counter];
1831 libMesh::out <<
"Interior basis function " << bf << std::endl;
1847 libMesh::out <<
"Side basis function " << bf << std::endl;
1850 const auto & elem_id = pr.first;
1851 const auto & side_index = pr.second;
1852 libMesh::out <<
"Elem " << elem_id <<
", Side " << side_index << std::endl;
1865 libMesh::out <<
"Node basis function " << bf << std::endl;
1871 libMesh::out <<
"Variable " << var <<
": " << array[var] << std::endl;
1906 libmesh_error_msg_if(!n_bf,
"RBEIMEvaluation::gather_bfs() should not be called with 0 basis functions.");
1921 std::vector<dof_id_type> elem_ids;
1924 elem_ids.push_back(pr.first);
1930 std::vector<unsigned int> n_qp_per_elem;
1936 const auto & array = pr.second;
1937 n_qp_per_elem.push_back(array[0].size());
1943 auto n_local_qp_data =
1944 std::accumulate(n_qp_per_elem.begin(),
1945 n_qp_per_elem.end(),
1953 libmesh_error_msg_if(elem_ids.size() != n_qp_per_elem.size(),
1954 "Must gather same number of Elem ids as qps per Elem.");
1957 std::vector<std::vector<Number>> gathered_qp_data(
n_vars);
1959 gathered_qp_data[var].reserve(n_local_qp_data);
1969 gathered_qp_data[var].
clear();
1974 const auto & array = pr.second;
1978 gathered_qp_data[var].insert(gathered_qp_data[var].end(),
1992 this->
comm().
gather(0, gathered_qp_data[var]);
2001 auto cursor = gathered_qp_data[var].begin();
2004 auto elem_id = elem_ids[i];
2005 auto n_qp_this_elem = n_qp_per_elem[i];
2011 auto & array = bf_map[elem_id];
2018 array[var].assign(cursor, cursor + n_qp_this_elem);
2019 std::advance(cursor, n_qp_this_elem);
2054 libmesh_error_msg_if(!n_bf,
"SideRBEIMEvaluation::gather_bfs() should not be called with 0 basis functions.");
2069 std::vector<std::pair<dof_id_type,unsigned int>> elem_side_pairs;
2072 elem_side_pairs.push_back(pr.first);
2078 std::vector<unsigned int> n_qp_per_elem_side;
2084 const auto & array = pr.second;
2085 n_qp_per_elem_side.push_back(array[0].size());
2091 auto n_local_qp_data =
2092 std::accumulate(n_qp_per_elem_side.begin(),
2093 n_qp_per_elem_side.end(),
2101 libmesh_error_msg_if(elem_side_pairs.size() != n_qp_per_elem_side.size(),
2102 "Must gather same number of Elem ids as qps per Elem.");
2105 std::vector<std::vector<Number>> gathered_qp_data(
n_vars);
2107 gathered_qp_data[var].reserve(n_local_qp_data);
2117 gathered_qp_data[var].
clear();
2122 const auto & array = pr.second;
2126 gathered_qp_data[var].insert(gathered_qp_data[var].end(),
2140 this->
comm().
gather(0, gathered_qp_data[var]);
2149 auto cursor = gathered_qp_data[var].begin();
2152 auto elem_side_pair = elem_side_pairs[i];
2153 auto n_qp_this_elem_side = n_qp_per_elem_side[i];
2159 auto & array = bf_map[elem_side_pair];
2166 array[var].assign(cursor, cursor + n_qp_this_elem_side);
2167 std::advance(cursor, n_qp_this_elem_side);
2202 libmesh_error_msg_if(!n_bf,
"RBEIMEvaluation::gather_bfs() should not be called with 0 basis functions.");
2218 std::vector<dof_id_type> node_ids;
2219 node_ids.reserve(n_local_nodes);
2221 node_ids.push_back(pr.first);
2228 std::vector<std::vector<Number>> gathered_node_data(
n_vars);
2234 gathered_node_data[var].clear();
2235 gathered_node_data[var].resize(n_local_nodes);
2238 unsigned int local_node_idx = 0;
2242 const auto & array = pr.second;
2245 gathered_node_data[var][local_node_idx] = array[var];
2259 this->
comm().
gather(0, gathered_node_data[var]);
2268 auto cursor = gathered_node_data[var].begin();
2271 auto node_id = node_ids[i];
2277 auto & array = bf_map[node_id];
2287 array[var] = *cursor;
2288 std::advance(cursor, 1);
2325 std::vector<dof_id_type> gathered_local_elem_ids;
2326 gathered_local_elem_ids.reserve(
mesh.n_elem());
2327 for (
const auto & elem :
mesh.active_local_element_ptr_range())
2328 gathered_local_elem_ids.push_back(elem->id());
2334 std::sort(gathered_local_elem_ids.begin(), gathered_local_elem_ids.end());
2337 auto n_local_elems = gathered_local_elem_ids.size();
2338 std::vector<std::size_t> gathered_n_local_elems = {n_local_elems};
2339 sys.
comm().
gather(0, gathered_n_local_elems);
2342 sys.
comm().
gather(0, gathered_local_elem_ids);
2347 std::vector<std::size_t> start_elem_ids_index, end_elem_ids_index;
2351 start_elem_ids_index.resize(n_procs);
2352 start_elem_ids_index[0] = 0;
2354 start_elem_ids_index[p] = start_elem_ids_index[p-1] + gathered_n_local_elems[p-1];
2356 end_elem_ids_index.resize(n_procs);
2357 end_elem_ids_index[n_procs - 1] = gathered_local_elem_ids.size();
2359 end_elem_ids_index[p] = start_elem_ids_index[p+1];
2367 std::vector<unsigned int> n_qp_per_elem_data;
2371 std::vector<int> counts;
2375 n_qp_per_elem_data.reserve(gathered_local_elem_ids.size());
2376 counts.resize(n_procs);
2382 for (
auto e :
make_range(start_elem_ids_index[p], end_elem_ids_index[p]))
2384 auto elem_id = gathered_local_elem_ids[e];
2388 const auto & array = libmesh_map_find(bf_map, elem_id);
2390 auto n_qps = array[0].size();
2393 n_qp_per_elem_data.push_back(n_qps);
2404 std::vector<unsigned int> recv;
2405 std::vector<int> tmp(gathered_n_local_elems.begin(), gathered_n_local_elems.end());
2406 sys.
comm().
scatter(n_qp_per_elem_data, tmp, recv, 0);
2411 n_qp_per_elem_data.swap(recv);
2419 std::vector<std::vector<Number>> qp_data(
n_vars);
2425 std::accumulate(counts.begin(), counts.end(), 0u);
2430 qp_data[var].reserve(n_qp_data);
2435 std::vector<Number> recv_qp_data;
2449 qp_data[var].
clear();
2453 for (
auto e :
make_range(start_elem_ids_index[p], end_elem_ids_index[p]))
2455 auto elem_id = gathered_local_elem_ids[e];
2459 const auto & array = libmesh_map_find(bf_map, elem_id);
2464 qp_data[var].insert(qp_data[var].end(),
2476 sys.
comm().
scatter(qp_data[var], counts, recv_qp_data, 0);
2482 auto cursor = recv_qp_data.begin();
2484 for (
auto i :
index_range(gathered_local_elem_ids))
2486 auto elem_id = gathered_local_elem_ids[i];
2487 auto n_qp_this_elem = n_qp_per_elem_data[i];
2488 auto & array = bf_map[elem_id];
2494 array[var].assign(cursor, cursor + n_qp_this_elem);
2495 std::advance(cursor, n_qp_this_elem);
2508 for (
auto e :
make_range(start_elem_ids_index[p], end_elem_ids_index[p]))
2510 auto elem_id = gathered_local_elem_ids[e];
2514 bf_map.erase(elem_id);
2545 const std::set<boundary_id_type> & parametrized_function_boundary_ids =
2553 std::vector<boundary_id_type> side_boundary_ids;
2555 std::vector<dof_id_type> gathered_local_elem_ids;
2556 std::vector<dof_id_type> gathered_local_side_indices;
2557 for (
const auto & elem :
mesh.active_local_element_ptr_range())
2559 for (
unsigned int side = 0; side != elem->n_sides(); ++side)
2562 if (!elem->neighbor_ptr(side))
2566 bool has_side_boundary_id =
false;
2568 if (parametrized_function_boundary_ids.count(side_boundary_id))
2570 has_side_boundary_id =
true;
2574 if (has_side_boundary_id)
2576 gathered_local_elem_ids.push_back(elem->id());
2577 gathered_local_side_indices.push_back(side);
2583 if (elem->dim() == 2)
2584 for (
unsigned int shellface_index=0; shellface_index<2; shellface_index++)
2586 binfo.shellface_boundary_ids(elem, shellface_index, side_boundary_ids);
2588 bool has_side_boundary_id =
false;
2590 if (parametrized_function_boundary_ids.count(side_boundary_id))
2592 has_side_boundary_id =
true;
2596 if (has_side_boundary_id)
2600 gathered_local_elem_ids.push_back(elem->id());
2601 gathered_local_side_indices.push_back(shellface_index);
2607 auto n_local_elems = gathered_local_elem_ids.size();
2608 std::vector<std::size_t> gathered_n_local_elems = {n_local_elems};
2609 sys.
comm().
gather(0, gathered_n_local_elems);
2612 sys.
comm().
gather(0, gathered_local_elem_ids);
2613 sys.
comm().
gather(0, gathered_local_side_indices);
2618 std::vector<std::size_t> start_elem_ids_index, end_elem_ids_index;
2622 start_elem_ids_index.resize(n_procs);
2623 start_elem_ids_index[0] = 0;
2625 start_elem_ids_index[p] = start_elem_ids_index[p-1] + gathered_n_local_elems[p-1];
2627 end_elem_ids_index.resize(n_procs);
2628 end_elem_ids_index[n_procs - 1] = gathered_local_elem_ids.size();
2630 end_elem_ids_index[p] = start_elem_ids_index[p+1];
2638 std::vector<unsigned int> n_qp_per_elem_data;
2642 std::vector<int> counts;
2646 n_qp_per_elem_data.reserve(gathered_local_elem_ids.size());
2647 counts.resize(n_procs);
2653 for (
auto e :
make_range(start_elem_ids_index[p], end_elem_ids_index[p]))
2655 auto elem_id = gathered_local_elem_ids[e];
2656 auto side_index = gathered_local_side_indices[e];
2660 const auto & array = libmesh_map_find(bf_map, std::make_pair(elem_id, side_index));
2662 auto n_qps = array[0].size();
2665 n_qp_per_elem_data.push_back(n_qps);
2676 std::vector<unsigned int> recv;
2677 std::vector<int> tmp(gathered_n_local_elems.begin(), gathered_n_local_elems.end());
2678 sys.
comm().
scatter(n_qp_per_elem_data, tmp, recv, 0);
2683 n_qp_per_elem_data.swap(recv);
2691 std::vector<std::vector<Number>> qp_data(
n_vars);
2697 std::accumulate(counts.begin(), counts.end(), 0u);
2702 qp_data[var].reserve(n_qp_data);
2707 std::vector<Number> recv_qp_data;
2721 qp_data[var].
clear();
2725 for (
auto e :
make_range(start_elem_ids_index[p], end_elem_ids_index[p]))
2727 auto elem_id = gathered_local_elem_ids[e];
2728 auto side_index = gathered_local_side_indices[e];
2732 const auto & array = libmesh_map_find(bf_map, std::make_pair(elem_id, side_index));
2737 qp_data[var].insert(qp_data[var].end(),
2749 sys.
comm().
scatter(qp_data[var], counts, recv_qp_data, 0);
2755 auto cursor = recv_qp_data.begin();
2757 for (
auto i :
index_range(gathered_local_elem_ids))
2759 auto elem_id = gathered_local_elem_ids[i];
2760 auto side_index = gathered_local_side_indices[i];
2761 auto n_qp_this_elem = n_qp_per_elem_data[i];
2762 auto & array = bf_map[std::make_pair(elem_id, side_index)];
2768 array[var].assign(cursor, cursor + n_qp_this_elem);
2769 std::advance(cursor, n_qp_this_elem);
2782 for (
auto e :
make_range(start_elem_ids_index[p], end_elem_ids_index[p]))
2784 auto elem_id = gathered_local_elem_ids[e];
2785 auto side_index = gathered_local_side_indices[e];
2789 bf_map.erase(std::make_pair(elem_id, side_index));
2823 std::vector<dof_id_type> gathered_local_node_ids;
2825 const std::set<boundary_id_type> & parametrized_function_boundary_ids =
2828 const auto & binfo =
mesh.get_boundary_info();
2834 std::set<dof_id_type> nodes_with_nodesets;
2835 for (
const auto & t : binfo.build_node_list())
2836 nodes_with_nodesets.insert(std::get<0>(t));
2839 std::vector<boundary_id_type> node_boundary_ids;
2843 const Node * node =
mesh.node_ptr(node_id);
2848 binfo.boundary_ids(node, node_boundary_ids);
2850 bool has_node_boundary_id =
false;
2854 has_node_boundary_id =
true;
2858 if(has_node_boundary_id)
2860 gathered_local_node_ids.push_back(node_id);
2869 std::sort(gathered_local_node_ids.begin(), gathered_local_node_ids.end());
2872 auto n_local_nodes = gathered_local_node_ids.size();
2873 std::vector<std::size_t> gathered_n_local_nodes = {n_local_nodes};
2874 sys.
comm().
gather(0, gathered_n_local_nodes);
2877 sys.
comm().
gather(0, gathered_local_node_ids);
2882 std::vector<std::size_t> start_node_ids_index, end_node_ids_index;
2886 start_node_ids_index.resize(n_procs);
2887 start_node_ids_index[0] = 0;
2889 start_node_ids_index[p] = start_node_ids_index[p-1] + gathered_n_local_nodes[p-1];
2891 end_node_ids_index.resize(n_procs);
2892 end_node_ids_index[n_procs - 1] = gathered_local_node_ids.size();
2894 end_node_ids_index[p] = start_node_ids_index[p+1];
2905 std::vector<int> counts;
2909 counts.resize(n_procs);
2913 auto node_ids_range = (end_node_ids_index[p] - start_node_ids_index[p]);
2916 counts[p] += node_ids_range;
2922 std::vector<Number> recv_node_data;
2929 std::vector<std::vector<Number>> node_data(
n_vars);
2932 int count_sum = std::accumulate(counts.begin(), counts.end(), 0);
2934 node_data[var].reserve(count_sum);
2949 node_data[var].
clear();
2953 for (
auto n :
make_range(start_node_ids_index[p], end_node_ids_index[p]))
2955 auto node_id = gathered_local_node_ids[n];
2959 const auto & array = libmesh_map_find(bf_map, node_id);
2962 node_data[var].push_back(array[var]);
2971 sys.
comm().
scatter(node_data[var], counts, recv_node_data, 0);
2977 auto cursor = recv_node_data.begin();
2979 for (
auto i :
index_range(gathered_local_node_ids))
2981 auto node_id = gathered_local_node_ids[i];
2982 auto & array = bf_map[node_id];
2991 array[var] = *cursor;
2992 std::advance(cursor, 1);
3005 for (
auto n :
make_range(start_node_ids_index[p], end_node_ids_index[p]))
3007 auto node_id = gathered_local_node_ids[n];
3011 bf_map.erase(node_id);
3018 const std::vector<Number> & ,
3020 const std::map<std::string,std::string> & )
3054 Number error_indicator_rhs,
3061 Number EIM_val_at_error_indicator_pt = coeffs.
dot(eim_solution);
3062 Real error_indicator_val =
3063 std::real(error_indicator_rhs - EIM_val_at_error_indicator_pt);
3065 Real normalization = 0.;
3073 std::abs(error_indicator_rhs) + std::abs(EIM_val_at_error_indicator_pt);
3078 normalization = std::abs(error_indicator_rhs);
3089 normalization = std::max(eim_rhs.
linfty_norm(), std::abs(error_indicator_rhs));
3093 libmesh_error_msg(
"unsupported eim_error_indicator_normalization");
3100 Real orig_normalization = normalization;
3101 if (normalization == 0.)
3110 Real rel_error_indicator = std::abs(error_indicator_val) / normalization;
3112 rel_error_indicator = 1.0;
3114 return std::make_pair(rel_error_indicator, orig_normalization);
3127 for (
const auto & [key, val] : rb_property_map)
3133 return _error_indicator_interpolation_row;
3138 _error_indicator_interpolation_row = extra_point_row;
void max(const T &r, T &o, Request &req) const
processor_id_type size() const
processor_id_type rank() const
void scatter(const std::vector< T, A > &data, T &recv, const unsigned int root_id=0) const
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
void gather(const unsigned int root_id, const T &send_data, std::vector< T, A > &recv) const
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
Defines a dense matrix for use in Finite Element-type computations.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
void lu_solve(const DenseVector< T > &b, DenseVector< T > &x)
Solve the system Ax=b given the input vector b.
void get_principal_submatrix(unsigned int sub_m, unsigned int sub_n, DenseMatrix< T > &dest) const
Put the sub_m x sub_n principal submatrix into dest.
Defines a dense vector for use in Finite Element-type computations.
void get_principal_subvector(unsigned int sub_n, DenseVector< T > &dest) const
Puts the principal subvector of size sub_n (i.e.
CompareTypes< T, T2 >::supertype dot(const DenseVector< T2 > &vec) const
virtual unsigned int size() const override final
processor_id_type processor_id() const
This is the MeshBase class.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
A Node is like a Point, but with more information.
An object whose state is distributed along a set of processors.
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
This class enables evaluation of an Empirical Interpolation Method (EIM) approximation.
const SideQpDataMap & get_side_basis_function(unsigned int i) const
Get a reference to the i^th side basis function.
void distribute_bfs(const System &sys)
Helper function that distributes the entries of _local_eim_basis_functions to their respective proces...
Point get_interpolation_points_xyz(unsigned int index) const
Get the data associated with EIM interpolation points.
virtual void project_qp_data_vector_onto_system(System &sys, const std::vector< Number > &bf_data, const EIMVarGroupPlottingInfo &eim_vargroup, const std::map< std::string, std::string > &extra_options)
Project the EIM basis function data stored in bf_data onto sys.solution.
void add_interpolation_data(Point p, unsigned int comp, dof_id_type elem_id, subdomain_id_type subdomain_id, unsigned int qp, const std::vector< Point > &perturbs, const std::vector< Real > &phi_i_qp, ElemType elem_type, const std::vector< Real > &JxW_all_qp, const std::vector< std::vector< Real > > &phi_i_all_qp, Order qrule_order, const Point &dxyz_dxi_elem_center, const Point &dxyz_deta_elem_center)
Add interpolation data associated with a new basis function.
void add_interpolation_points_subdomain_id(subdomain_id_type sbd_id)
void add_interpolation_points_comp(unsigned int comp)
void add_basis_function(const QpDataMap &bf)
Add bf to our EIM basis.
virtual bool use_eim_error_indicator() const
Virtual function to indicate if we use the EIM error indicator in this case.
bool _preserve_rb_eim_solutions
Boolean to indicate if we skip updating _rb_eim_solutions in rb_eim_solves().
void add_interpolation_points_phi_i_all_qp(const std::vector< std::vector< Real > > &phi_i_all_qp)
void add_node_interpolation_data(Point p, unsigned int comp, dof_id_type node_id, boundary_id_type boundary_id)
Add interpolation data associated with a new basis function.
void read_in_interior_basis_functions(const System &sys, const std::string &directory_name, bool read_binary_basis_functions)
Method that reads in element interior EIM basis functions.
void read_in_node_basis_functions(const System &sys, const std::string &directory_name, bool read_binary_basis_functions)
Method that reads in element node EIM basis functions.
void add_rb_property_map_entry(std::string &property_name, std::set< dof_id_type > &entity_ids)
DenseMatrix< Number > _interpolation_matrix
Dense matrix that stores the lower triangular interpolation matrix that can be used.
std::vector< std::vector< std::vector< Number > > > get_interior_basis_functions_as_vecs()
Get all interior basis functions in the form of std::vectors.
std::vector< DenseVector< Number > > _eim_solutions_for_training_set
Storage for EIM solutions from the training set.
void add_interpolation_points_xyz_perturbations(const std::vector< Point > &perturbs)
const std::unordered_map< std::string, std::set< dof_id_type > > & get_rb_property_map() const
void decrement_vector(QpDataMap &v, const DenseVector< Number > &coeffs)
Subtract coeffs[i]*basis_function[i] from v.
void print_local_eim_basis_functions() const
Print the contents of _local_eim_basis_functions to libMesh::out.
unsigned int get_interpolation_points_side_index(unsigned int index) const
const std::map< dof_id_type, unsigned int > & get_elem_id_to_local_index_map() const
std::vector< QpDataMap > _local_eim_basis_functions
The EIM basis functions.
unsigned int get_n_elems() const
Return the number of unique elements containing interpolation points.
std::vector< unsigned int > _interpolation_points_comp
In the case of a "vector-valued" EIM, this vector determines which component of the parameterized fun...
EimErrorIndicatorNormalization eim_error_indicator_normalization
std::vector< std::pair< Real, Real > > _rb_eim_error_indicators
If we're using the EIM error indicator, then we store the error indicator values corresponding to _rb...
const DenseMatrix< Number > & get_interpolation_matrix() const
Get the EIM interpolation matrix.
void add_interpolation_points_side_index(unsigned int side_index)
void side_gather_bfs()
Same as gather_bfs() except for side data.
const std::set< unsigned int > & scale_components_in_enrichment() const
Get _scale_components_in_enrichment.
Order get_interpolation_points_qrule_order(unsigned int index) const
virtual std::unique_ptr< RBTheta > build_eim_theta(unsigned int index)
Build a theta object corresponding to EIM index index.
virtual ~RBEIMEvaluation()
void add_interpolation_points_elem_type(ElemType elem_type)
Number get_eim_basis_function_node_local_value(unsigned int basis_function_index, dof_id_type node_id, unsigned int var) const
Same as get_eim_basis_function_values_at_qps() except for node data.
void add_interpolation_points_boundary_id(boundary_id_type b_id)
Number get_eim_basis_function_node_value(unsigned int basis_function_index, dof_id_type node_id, unsigned int var) const
Same as get_eim_basis_function_value() except for node data.
void set_preserve_rb_eim_solutions(bool preserve_rb_eim_solutions)
Set _preserve_rb_eim_solutions.
std::pair< Real, Real > get_eim_error_indicator(Number error_indicator_rhs, const DenseVector< Number > &eim_solution, const DenseVector< Number > &eim_rhs)
Evaluates the EIM error indicator based on error_indicator_rhs, eim_solution, and _error_indicator_in...
std::vector< std::vector< unsigned int > > _interpolation_points_spatial_indices
Here we store the spatial indices that were initialized by initialize_spatial_indices_at_interp_pts()...
void set_rb_eim_solutions(const std::vector< DenseVector< Number > > &rb_eim_solutions)
Set _rb_eim_solutions.
unsigned int get_n_basis_functions() const
Return the current number of EIM basis functions.
void add_interpolation_points_qp(unsigned int qp)
void write_out_interior_basis_functions(const std::string &directory_name, bool write_binary_basis_functions)
Method that writes out element interior EIM basis functions.
void add_interpolation_points_elem_id(dof_id_type elem_id)
subdomain_id_type get_interpolation_points_subdomain_id(unsigned int index) const
unsigned int get_n_interpolation_points() const
Return the number of interpolation points.
std::vector< NodeDataMap > _local_node_eim_basis_functions
The EIM basis functions on element nodes (e.g.
Number get_eim_basis_function_value(unsigned int basis_function_index, dof_id_type elem_id, unsigned int comp, unsigned int qp) const
Same as above, except that we just return the value at the qp^th quadrature point.
unsigned int get_interpolation_points_comp(unsigned int index) const
unsigned int get_n_properties() const
Return the number of properties stored in the rb_property_map.
void write_out_node_basis_functions(const std::string &directory_name, bool write_binary_basis_functions)
Method that writes out element node EIM basis functions.
void side_distribute_bfs(const System &sys)
Same as distribute_bfs() except for side data.
void initialize_eim_theta_objects()
Build a vector of RBTheta objects that accesses the components of the RB_solution member variable of ...
const std::vector< Real > & get_interpolation_points_JxW_all_qp(unsigned int index) const
void set_n_basis_functions(unsigned int n_bfs)
Set the number of basis functions.
std::vector< std::unique_ptr< RBTheta > > _rb_eim_theta_objects
The vector of RBTheta objects that are created to point to this RBEIMEvaluation.
const std::vector< std::vector< Real > > & get_interpolation_points_phi_i_all_qp(unsigned int index) const
std::vector< SideQpDataMap > _local_side_eim_basis_functions
The EIM basis functions on element sides.
const QpDataMap & get_basis_function(unsigned int i) const
Get a reference to the i^th basis function.
void node_distribute_bfs(const System &sys)
Same as distribute_bfs() except for node data.
void add_interpolation_points_xyz(Point p)
Set the data associated with EIM interpolation points.
bool _is_eim_error_indicator_active
Indicate if the EIM error indicator is active in RB EIM solves.
void read_in_basis_functions(const System &sys, const std::string &directory_name="offline_data", bool read_binary_basis_functions=true)
Read in all the basis functions from file.
void add_interpolation_points_phi_i_qp(const std::vector< Real > &phi_i_qp)
void rb_eim_solves(const std::vector< RBParameters > &mus, unsigned int N)
Perform rb_eim_solves at each mu in mus and store the results in _rb_eim_solutions.
static void get_parametrized_function_side_values_at_qps(const SideQpDataMap &pf, dof_id_type elem_id, unsigned int side_index, unsigned int comp, std::vector< Number > &values)
Same as get_parametrized_function_values_at_qps() except for side data.
virtual void clear() override
Clear this object.
void add_node_basis_function(const NodeDataMap &node_bf)
Add node_bf to our EIM basis.
std::set< unsigned int > _scale_components_in_enrichment
This set that specifies which EIM variables will be scaled during EIM enrichment so that their maximu...
std::vector< Number > get_rb_eim_solutions_entries(unsigned int index) const
Return entry index for each solution in _rb_eim_solutions.
void resize_data_structures(const unsigned int Nmax)
Resize the data structures for storing data associated with this object.
void set_parametrized_function(std::unique_ptr< RBParametrizedFunction > pf)
Set the parametrized function that we will approximate using the Empirical Interpolation Method.
dof_id_type get_interpolation_points_elem_id(unsigned int index) const
void add_interpolation_points_spatial_indices(const std::vector< unsigned int > &spatial_indices)
void side_decrement_vector(SideQpDataMap &v, const DenseVector< Number > &coeffs)
Same as decrement_vector() except for Side data.
const NodeDataMap & get_node_basis_function(unsigned int i) const
Get a reference to the i^th node basis function.
void read_in_side_basis_functions(const System &sys, const std::string &directory_name, bool read_binary_basis_functions)
Method that reads in element side EIM basis functions.
void set_eim_error_indicator_active(bool is_active)
Activate/decative the error indicator in EIM solves.
void initialize_rb_property_map()
Initialize the rb_property_map of RBEIMEvaluation (this) from the rb_property_map stored in RBParamet...
const std::vector< Real > & get_interpolation_points_phi_i_qp(unsigned int index) const
void add_side_basis_function(const SideQpDataMap &side_bf)
Add side_bf to our EIM basis.
std::map< std::pair< dof_id_type, unsigned int >, std::vector< std::vector< Number > > > SideQpDataMap
Type of the data structure used to map from (elem id, side index) -> [n_vars][n_qp] data.
const std::vector< EIMVarGroupPlottingInfo > & get_eim_vars_to_project_and_write() const
Get _eim_vars_to_project_and_write.
void initialize_interpolation_points_spatial_indices()
Initialize _interpolation_points_spatial_indices.
dof_id_type get_interpolation_points_node_id(unsigned int index) const
const std::vector< unsigned int > & get_interpolation_points_spatial_indices(unsigned int index) const
unsigned int get_n_interpolation_points_spatial_indices() const
_interpolation_points_spatial_indices is optional data, so we need to be able to check how many _inte...
Number get_eim_basis_function_side_value(unsigned int basis_function_index, dof_id_type elem_id, unsigned int side_index, unsigned int comp, unsigned int qp) const
Same as get_eim_basis_function_value() except for side data.
void write_out_basis_functions(const std::string &directory_name="offline_data", bool write_binary_basis_functions=true)
Write out all the basis functions to file.
std::vector< std::vector< Number > > get_interior_basis_function_as_vec_helper(unsigned int n_vars, unsigned int n_qp_data, unsigned int bf_index)
Helper function called by write_out_interior_basis_functions() to get basis function bf_index stored ...
static Number get_parametrized_function_node_local_value(const NodeDataMap &pf, dof_id_type node_id, unsigned int comp)
Same as get_parametrized_function_values_at_qps() except for node data.
const std::vector< DenseVector< Number > > & get_rb_eim_solutions() const
Return the EIM solution coefficients from the most recent call to rb_eim_solves().
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.
std::map< std::string, std::size_t > get_interior_basis_function_sizes(std::vector< unsigned int > &n_qp_per_elem)
Get data that defines the sizes of interior EIM basis functions.
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.
DenseVector< Number > _error_indicator_interpolation_row
Here we store an extra row of the interpolation matrix which is used to compute the EIM error indicat...
std::vector< RBParameters > _rb_eim_solves_mus
The parameters and the number of basis functions that were used in the most recent call to rb_eim_sol...
VectorizedEvalInput _vec_eval_input
We store the EIM interpolation point data in this object.
static Number get_parametrized_function_side_value(const Parallel::Communicator &comm, const SideQpDataMap &pf, dof_id_type elem_id, unsigned int side_index, unsigned int comp, unsigned int qp)
Same as get_parametrized_function_value() except for side data.
void node_decrement_vector(NodeDataMap &v, const DenseVector< Number > &coeffs)
Same as decrement_vector() except for node data.
void add_interpolation_points_qrule_order(Order qrule_order)
static void get_parametrized_function_values_at_qps(const QpDataMap &pf, dof_id_type elem_id, unsigned int comp, std::vector< Number > &values)
Fill up values by evaluating the parametrized function pf for all quadrature points on element elem_i...
void add_elem_center_dxyzdxi(const Point &dxyzdxi)
void node_gather_bfs()
Same as gather_bfs() except for node data.
bool limit_eim_error_indicator_to_one
If this boolean is true then we clamp EIM error indicator values to be at most 1.
void add_elem_center_dxyzdeta(const Point &dxyzdxi)
unsigned int _rb_eim_solves_N
void add_interpolation_points_node_id(dof_id_type node_id)
static Number get_parametrized_function_node_value(const Parallel::Communicator &comm, const NodeDataMap &pf, dof_id_type node_id, unsigned int comp)
Same as get_parametrized_function_value() except for node data.
void add_side_interpolation_data(Point p, unsigned int comp, dof_id_type elem_id, unsigned int side_index, subdomain_id_type subdomain_id, boundary_id_type boundary_id, unsigned int qp, const std::vector< Point > &perturbs, const std::vector< Real > &phi_i_qp)
Add interpolation data associated with a new basis function.
DenseVector< Number > rb_eim_solve(DenseVector< Number > &EIM_rhs)
Calculate the EIM approximation for the given right-hand side vector EIM_rhs.
void get_eim_basis_function_side_values_at_qps(unsigned int basis_function_index, dof_id_type elem_id, unsigned int side_index, unsigned int var, std::vector< Number > &values) const
Same as get_eim_basis_function_values_at_qps() except for side data.
void initialize_param_fn_spatial_indices()
The Online counterpart of initialize_interpolation_points_spatial_indices().
std::vector< EIMVarGroupPlottingInfo > _eim_vars_to_project_and_write
This vector specifies which EIM variables we want to write to disk and/or project to nodes for plotti...
std::unique_ptr< RBParametrizedFunction > _parametrized_function
Store the parametrized function that will be approximated by this EIM system.
const std::vector< std::pair< Real, Real > > & get_rb_eim_error_indicators() const
Return the EIM error indicator values from the most recent call to rb_eim_solves().
RBParametrizedFunction & get_parametrized_function()
Get a reference to the parametrized function.
boundary_id_type get_interpolation_points_boundary_id(unsigned int index) const
ElemType get_interpolation_points_elem_type(unsigned int index) const
std::map< dof_id_type, std::vector< std::vector< Number > > > QpDataMap
Type of the data structure used to map from (elem id) -> [n_vars][n_qp] data.
bool get_preserve_rb_eim_solutions() const
Get _preserve_rb_eim_solutions.
std::vector< std::unique_ptr< RBTheta > > & get_eim_theta_objects()
const Point & get_elem_center_dxyzdeta(unsigned int index) const
std::vector< DenseVector< Number > > _rb_eim_solutions
The EIM solution coefficients from the most recent call to rb_eim_solves().
const Point & get_elem_center_dxyzdxi(unsigned int index) const
static Number get_parametrized_function_value(const Parallel::Communicator &comm, const QpDataMap &pf, dof_id_type elem_id, unsigned int comp, unsigned int qp)
Same as above, except that we just return the value at the qp^th quadrature point.
RBEIMEvaluation(const Parallel::Communicator &comm)
Constructor.
void get_eim_basis_function_values_at_qps(unsigned int basis_function_index, dof_id_type elem_id, unsigned int var, std::vector< Number > &values) const
Fill up values with the basis function values for basis function basis_function_index and variable va...
unsigned int get_interpolation_points_qp(unsigned int index) const
const VectorizedEvalInput & get_vec_eval_input() const
Get the VectorizedEvalInput data.
void add_interpolation_points_JxW_all_qp(const std::vector< Real > &JxW_all_qp)
void gather_bfs()
Helper function that gathers the contents of _local_eim_basis_functions to processor 0 in preparation...
const std::vector< Point > & get_interpolation_points_xyz_perturbations(unsigned int index) const
void write_out_side_basis_functions(const std::string &directory_name, bool write_binary_basis_functions)
Method that writes out element side EIM basis functions.
std::map< dof_id_type, std::vector< Number > > NodeDataMap
Type of the data structure used to map from (node id) -> [n_vars] data.
A simple functor class that provides a RBParameter-dependent function.
std::string lookup_table_param_name
If this is a lookup table, then lookup_table_param_name specifies the parameter that is used to index...
const std::unordered_map< std::string, std::set< dof_id_type > > & get_rb_property_map() const
Function that returns a reference to the rb_property_map stored in the RBParametrizedFunction.
virtual void get_spatial_indices(std::vector< std::vector< unsigned int > > &spatial_indices, const VectorizedEvalInput &v)
In some cases a parametrized function is defined based on array data that we index into based on the ...
virtual void add_interpolation_data_to_rb_property_map(const Parallel::Communicator &comm, std::unordered_map< std::string, std::set< dof_id_type > > &rb_property_map, dof_id_type elem_id)
Virtual function that can be overridden in RBParametrizedFunction subclasses to store properties in t...
const std::set< boundary_id_type > & get_parametrized_function_boundary_ids() const
For RBParametrizedFunctions defined on element sides or nodes, we get/set the boundary IDs that this ...
virtual void initialize_spatial_indices(const std::vector< std::vector< unsigned int > > &spatial_indices, const VectorizedEvalInput &v)
The Online stage counterpart of get_spatial_indices().
virtual void node_vectorized_evaluate(const std::vector< RBParameters > &mus, const VectorizedEvalInput &v, std::vector< std::vector< std::vector< Number > > > &output)
Same as vectorized_evaluate() but on element nodes.
virtual void side_vectorized_evaluate(const std::vector< RBParameters > &mus, const VectorizedEvalInput &v, std::vector< std::vector< std::vector< Number > > > &output)
Same as vectorized_evaluate() but on element sides.
virtual void vectorized_evaluate(const std::vector< RBParameters > &mus, const VectorizedEvalInput &v, std::vector< std::vector< std::vector< Number > > > &output)
Vectorized version of evaluate.
unsigned int get_n_params() const
Get the number of parameters.
Manages consistently variables, degrees of freedom, and coefficient vectors.
const MeshBase & get_mesh() const
This class implements a C++ interface to the XDR (eXternal Data Representation) format.
void data(T &a, std::string_view comment="")
Inputs or outputs a single value.
const boundary_id_type node_boundary_id
int mkdir(const char *pathname)
Create a directory.
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...
ElemType
Defines an enum for geometric element types.
void libmesh_ignore(const Args &...)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
uint8_t processor_id_type
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...
boost::multiprecision::float128 real(const boost::multiprecision::float128 in)
This struct encapsulates data that specifies how we will perform plotting for EIM variable groups.