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" 52 limit_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 =
2552 const auto & binfo =
mesh.get_boundary_info();
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))
2564 binfo.boundary_ids(elem, side, side_boundary_ids);
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)
void add_rb_property_map_entry(std::string &property_name, std::set< dof_id_type > &entity_ids)
void set_rb_eim_solutions(const std::vector< DenseVector< Number >> &rb_eim_solutions)
Set _rb_eim_solutions.
virtual void clear() override
Clear this object.
VectorizedEvalInput _vec_eval_input
We store the EIM interpolation point data in this object.
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 ...
ElemType
Defines an enum for geometric element types.
void add_interpolation_points_boundary_id(boundary_id_type b_id)
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().
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.
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...
Order
defines an enum for polynomial orders.
A Node is like a Point, but with more information.
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.
boost::multiprecision::float128 real(const boost::multiprecision::float128 in)
const SideQpDataMap & get_side_basis_function(unsigned int i) const
Get a reference to the i^th side basis function.
void set_eim_error_indicator_active(bool is_active)
Activate/decative the error indicator in EIM solves.
const DenseMatrix< Number > & get_interpolation_matrix() const
Get the EIM interpolation matrix.
void add_basis_function(const QpDataMap &bf)
Add bf to our EIM basis.
void scatter(const std::vector< T, A > &data, T &recv, const unsigned int root_id=0) const
void set_interpolation_matrix_entry(unsigned int i, unsigned int j, Number value)
Set entry of the EIM interpolation matrix.
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...
std::map< dof_id_type, std::vector< Number > > NodeDataMap
Type of the data structure used to map from (node id) -> [n_vars] data.
subdomain_id_type get_interpolation_points_subdomain_id(unsigned int index) const
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...
void distribute_bfs(const System &sys)
Helper function that distributes the entries of _local_eim_basis_functions to their respective proces...
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.
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 ...
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
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 ...
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...
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.
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.
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.
A simple functor class that provides a RBParameter-dependent function.
void gather(const unsigned int root_id, const T &send_data, std::vector< T, A > &recv) const
unsigned int get_n_basis_functions() const
Return the current number of EIM basis functions.
void add_node_basis_function(const NodeDataMap &node_bf)
Add node_bf to our EIM basis.
RBEIMEvaluation(const Parallel::Communicator &comm)
Constructor.
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...
void add_interpolation_points_elem_id(dof_id_type elem_id)
std::vector< Number > get_rb_eim_solutions_entries(unsigned int index) const
Return entry index for each solution in _rb_eim_solutions.
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.
const std::vector< std::vector< Real > > & get_interpolation_points_phi_i_all_qp(unsigned int index) const
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.
const std::vector< DenseVector< Number > > & get_rb_eim_solutions() const
Return the EIM solution coefficients from the most recent call to rb_eim_solves().
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.
processor_id_type rank() const
std::unique_ptr< RBParametrizedFunction > _parametrized_function
Store the parametrized function that will be approximated by this EIM system.
const Parallel::Communicator & comm() const
int mkdir(const char *pathname)
Create a directory.
const std::vector< Point > & get_interpolation_points_xyz_perturbations(unsigned int index) const
unsigned int get_interpolation_points_side_index(unsigned int index) const
bool get_preserve_rb_eim_solutions() const
Get _preserve_rb_eim_solutions.
unsigned int get_n_interpolation_points() const
Return the number of interpolation points.
void decrement_vector(QpDataMap &v, const DenseVector< Number > &coeffs)
Subtract coeffs[i]*basis_function[i] from v.
const NodeDataMap & get_node_basis_function(unsigned int i) const
Get a reference to the i^th node basis function.
The libMesh namespace provides an interface to certain functionality in the library.
unsigned int get_interpolation_points_comp(unsigned int index) const
const std::vector< DenseVector< Number > > & get_eim_solutions_for_training_set() const
Return a const reference to the EIM solutions for the parameters in the training set.
void initialize_param_fn_spatial_indices()
The Online counterpart of initialize_interpolation_points_spatial_indices().
void set_parametrized_function(std::unique_ptr< RBParametrizedFunction > pf)
Set the parametrized function that we will approximate using the Empirical Interpolation Method...
void add_interpolation_points_xyz_perturbations(const std::vector< Point > &perturbs)
const MeshBase & get_mesh() const
bool _is_eim_error_indicator_active
Indicate if the EIM error indicator is active in RB EIM solves.
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.
void get_principal_subvector(unsigned int sub_n, DenseVector< T > &dest) const
Puts the principal subvector of size sub_n (i.e.
void set_preserve_rb_eim_solutions(bool preserve_rb_eim_solutions)
Set _preserve_rb_eim_solutions.
std::vector< SideQpDataMap > _local_side_eim_basis_functions
The EIM basis functions on element sides.
void initialize_eim_theta_objects()
Build a vector of RBTheta objects that accesses the components of the RB_solution member variable of ...
void add_side_basis_function(const SideQpDataMap &side_bf)
Add side_bf to our EIM basis.
uint8_t processor_id_type
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.
This is the MeshBase class.
void side_decrement_vector(SideQpDataMap &v, const DenseVector< Number > &coeffs)
Same as decrement_vector() except for Side data.
void side_distribute_bfs(const System &sys)
Same as distribute_bfs() except for side data.
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.
std::vector< std::unique_ptr< RBTheta > > & get_eim_theta_objects()
const std::vector< Real > & get_interpolation_points_JxW_all_qp(unsigned int index) const
std::vector< std::unique_ptr< RBTheta > > _rb_eim_theta_objects
The vector of RBTheta objects that are created to point to this RBEIMEvaluation.
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 data(T &a, std::string_view comment="")
Inputs or outputs a single value.
const Point & get_elem_center_dxyzdeta(unsigned int index) const
processor_id_type size() const
void side_gather_bfs()
Same as gather_bfs() except for side data.
std::vector< NodeDataMap > _local_node_eim_basis_functions
The EIM basis functions on element nodes (e.g.
processor_id_type n_processors() const
void libmesh_ignore(const Args &...)
const QpDataMap & get_basis_function(unsigned int i) const
Get a reference to the i^th basis function.
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.
boundary_id_type get_interpolation_points_boundary_id(unsigned int index) const
void print_local_eim_basis_functions() const
Print the contents of _local_eim_basis_functions to libMesh::out.
unsigned int get_n_properties() const
Return the number of properties stored in the rb_property_map.
void resize_data_structures(const unsigned int Nmax)
Resize the data structures for storing data associated with this object.
const boundary_id_type node_boundary_id
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_n_basis_functions(unsigned int n_bfs)
Set the number of basis functions.
Manages consistently variables, degrees of freedom, and coefficient vectors.
const std::unordered_map< std::string, std::set< dof_id_type > > & get_rb_property_map() const
void node_distribute_bfs(const System &sys)
Same as distribute_bfs() except for node data.
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 write_out_interior_basis_functions(const std::string &directory_name, bool write_binary_basis_functions)
Method that writes out element interior EIM basis functions.
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.
void add_elem_id_local_index_map_entry(dof_id_type elem_id, unsigned int local_index)
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.
const std::vector< unsigned int > & get_interpolation_points_spatial_indices(unsigned int index) const
const DenseVector< Number > & get_error_indicator_interpolation_row() const
Get/set _extra_points_interpolation_matrix.
ElemType get_interpolation_points_elem_type(unsigned int index) const
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.
void add_interpolation_points_side_index(unsigned int side_index)
void node_gather_bfs()
Same as gather_bfs() except for node data.
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 add_interpolation_points_phi_i_all_qp(const std::vector< std::vector< Real >> &phi_i_all_qp)
void node_decrement_vector(NodeDataMap &v, const DenseVector< Number > &coeffs)
Same as decrement_vector() except for node data.
void add_interpolation_points_phi_i_qp(const std::vector< Real > &phi_i_qp)
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.
virtual ~RBEIMEvaluation()
bool _preserve_rb_eim_solutions
Boolean to indicate if we skip updating _rb_eim_solutions in rb_eim_solves().
std::vector< DenseVector< Number > > _eim_solutions_for_training_set
Storage for EIM solutions from the training set.
void add_elem_center_dxyzdeta(const Point &dxyzdxi)
An object whose state is distributed along a set of processors.
bool limit_eim_error_indicator_to_one
If this boolean is true then we clamp EIM error indicator values to be at most 1. ...
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.
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
std::vector< std::vector< std::vector< Number > > > get_interior_basis_functions_as_vecs()
Get all interior basis functions in the form of std::vectors.
This class implements a C++ interface to the XDR (eXternal Data Representation) format.
EimErrorIndicatorNormalization eim_error_indicator_normalization
virtual std::unique_ptr< RBTheta > build_eim_theta(unsigned int index)
Build a theta object corresponding to EIM index index.
Point get_interpolation_points_xyz(unsigned int index) const
Get the data associated with EIM interpolation points.
dof_id_type get_interpolation_points_node_id(unsigned int index) const
virtual bool use_eim_error_indicator() const
Virtual function to indicate if we use the EIM error indicator in this case.
void add_interpolation_points_subdomain_id(subdomain_id_type sbd_id)
CompareTypes< T, T2 >::supertype dot(const DenseVector< T2 > &vec) const
DenseVector< Number > rb_eim_solve(DenseVector< Number > &EIM_rhs)
Calculate the EIM approximation for the given right-hand side vector EIM_rhs.
void lu_solve(const DenseVector< T > &b, DenseVector< T > &x)
Solve the system Ax=b given the input vector b.
void add_interpolation_points_node_id(dof_id_type node_id)
void add_interpolation_points_xyz(Point p)
Set the data associated with EIM interpolation points.
unsigned int _rb_eim_solves_N
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...
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 add_interpolation_points_qrule_order(Order qrule_order)
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.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void initialize_rb_property_map()
Initialize the rb_property_map of RBEIMEvaluation (this) from the rb_property_map stored in RBParamet...
const VectorizedEvalInput & get_vec_eval_input() const
Get the VectorizedEvalInput data.
const std::map< dof_id_type, unsigned int > & get_elem_id_to_local_index_map() const
void add_interpolation_points_JxW_all_qp(const std::vector< Real > &JxW_all_qp)
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 max(const T &r, T &o, Request &req) const
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.
std::vector< DenseVector< Number > > _rb_eim_solutions
The EIM solution coefficients from the most recent call to rb_eim_solves().
void set_error_indicator_interpolation_row(const DenseVector< Number > &error_indicator_row)
std::vector< unsigned int > _interpolation_points_comp
In the case of a "vector-valued" EIM, this vector determines which component of the parameterized fun...
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
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...
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...
dof_id_type get_interpolation_points_elem_id(unsigned int index) const
void add_interpolation_points_comp(unsigned int comp)
virtual unsigned int size() const override final
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.
unsigned int get_n_elems() const
Return the number of unique elements containing interpolation points.
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...
void add_interpolation_points_qp(unsigned int qp)
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...
std::vector< QpDataMap > _local_eim_basis_functions
The EIM basis functions.
RBParametrizedFunction & get_parametrized_function()
Get a reference to the parametrized function.
processor_id_type processor_id() const
void add_interpolation_points_spatial_indices(const std::vector< unsigned int > &spatial_indices)
const std::vector< Real > & get_interpolation_points_phi_i_qp(unsigned int index) const
This struct encapsulates data that specifies how we will perform plotting for EIM variable groups...
This class enables evaluation of an Empirical Interpolation Method (EIM) approximation.
processor_id_type processor_id() const
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.
const Point & get_elem_center_dxyzdxi(unsigned int index) const
unsigned int get_n_params() const
Get the number of parameters.
void initialize_interpolation_points_spatial_indices()
Initialize _interpolation_points_spatial_indices.
A Point defines a location in LIBMESH_DIM dimensional Real space.
void add_elem_center_dxyzdxi(const Point &dxyzdxi)
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
unsigned int get_interpolation_points_qp(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.
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...
void add_interpolation_points_elem_type(ElemType elem_type)
const std::vector< EIMVarGroupPlottingInfo > & get_eim_vars_to_project_and_write() const
Get _eim_vars_to_project_and_write.
void gather_bfs()
Helper function that gathers the contents of _local_eim_basis_functions to processor 0 in preparation...
virtual void vectorized_evaluate(const std::vector< RBParameters > &mus, const VectorizedEvalInput &v, std::vector< std::vector< std::vector< Number >>> &output)
Vectorized version of evaluate.
DenseMatrix< Number > _interpolation_matrix
Dense matrix that stores the lower triangular interpolation matrix that can be used.
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.
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().