21#include "libmesh/xdr_io.h"
22#include "libmesh/boundary_info.h"
23#include "libmesh/elem.h"
24#include "libmesh/enum_xdr_mode.h"
25#include "libmesh/int_range.h"
26#include "libmesh/libmesh_logging.h"
27#include "libmesh/mesh_base.h"
28#include "libmesh/mesh_tools.h"
29#include "libmesh/node.h"
30#include "libmesh/partitioner.h"
31#include "libmesh/utility.h"
32#include "libmesh/xdr_cxx.h"
53template <
class T,
class U>
54struct libmesh_type_is_same {
55 static const bool value =
false;
59struct libmesh_type_is_same<T, T> {
60 static const bool value =
true;
81 _write_serial (false),
82 _write_parallel (false),
83#ifdef LIBMESH_ENABLE_UNIQUE_ID
84 _write_unique_id (true),
86 _write_unique_id (false),
89 _version (
"libMesh-1.8.0"),
90 _bc_file_name (
"n/a"),
91 _partition_map_file (
"n/a"),
92 _subdomain_map_file (
"n/a"),
105 _write_serial (false),
106 _write_parallel (false),
107#ifdef LIBMESH_ENABLE_UNIQUE_ID
108 _write_unique_id (true),
110 _write_unique_id (false),
113 _version (
"libMesh-1.8.0"),
114 _bc_file_name (
"n/a"),
115 _partition_map_file (
"n/a"),
116 _subdomain_map_file (
"n/a"),
117 _p_level_file (
"n/a")
129 libmesh_error_msg_if(this->
legacy(),
"We don't support writing parallel files in the legacy format.");
133 LOG_SCOPE(
"write()",
"XdrIO");
158 if ((n_side_bcs || n_edge_bcs || n_shellface_bcs || n_nodesets) &&
165 (this->subdomain_map_file_name() ==
"n/a"))
172 if ((n_p_levels > 1) &&
179 std::string full_ver = this->
version() + (write_parallel_files ?
" parallel" :
"");
182 io.
data (n_elem,
"# number of elements");
183 io.
data (max_node_id,
"# number of nodes");
199 io.
data (write_size,
"# type size");
201 io.
data (write_partitioning ? write_size : zero_size,
"# pid size");
202 io.
data (write_subdomain_id ? write_size : zero_size,
"# sid size");
203 io.
data (write_p_level ? write_size : zero_size,
"# p-level size");
205 io.
data (write_bcs ? write_size : zero_size,
"# eid size");
206 io.
data (write_bcs ? write_size : zero_size,
"# side size");
207 io.
data (write_bcs ? write_size : zero_size,
"# bid size");
211 io.
data((n_elem_integers || n_node_integers) ? write_size : zero_size,
"# extra integer size");
214 std::vector<std::string> node_integer_names;
215 for (
unsigned int i=0; i != n_node_integers; ++i)
217 io.
data(node_integer_names,
"# node integer names");
220 std::vector<std::string> elem_integer_names;
221 for (
unsigned int i=0; i != n_elem_integers; ++i)
223 io.
data(elem_integer_names,
"# elem integer names");
228 io.
data(elemset_codes,
"# elemset codes");
232 for (
const auto & elemset_code : elemset_codes)
237 std::vector<dof_id_type> elemset_id_vec(id_set_to_fill.begin(), id_set_to_fill.end());
240 std::string comment_string =
"# elemset ids for elemset code " + std::to_string(elemset_code);
241 io.
data(elemset_id_vec, comment_string);
245 if (write_parallel_files)
249 libMesh::out <<
"Warning! Parallel xda/xdr is not yet implemented.\n";
250 libMesh::out <<
"Writing a serialized file instead." << std::endl;
315 std::vector<new_header_id_type> subdomain_ids;
316 subdomain_ids.reserve(subdomain_map.size());
318 std::vector<std::string> subdomain_names;
319 subdomain_names.reserve(subdomain_map.size());
325 for (
const auto & [sbd_id, name] : subdomain_map)
329 subdomain_ids.push_back(sbd_id);
330 subdomain_names.push_back(name);
333 io.
data(n_subdomain_names,
"# subdomain id to name map");
335 if (n_subdomain_names)
337 io.
data(subdomain_ids);
338 io.
data(subdomain_names);
359 libmesh_assert_equal_to (n_elem,
mesh.
n_elem());
363 std::vector<xdr_id_type> n_global_elem_at_level(n_active_levels);
369 for (
unsigned int level=0; level<n_active_levels; level++)
371 n_global_elem_at_level[level] =
373 mesh.local_level_elements_end(level));
375 this->
comm().
sum(n_global_elem_at_level[level]);
377 tot_n_elem += n_global_elem_at_level[level];
379 libmesh_assert_less_equal (n_global_elem_at_level[level], n_elem);
380 libmesh_assert_less_equal (tot_n_elem, n_elem);
383 std::vector<xdr_id_type>
384 xfer_conn, recv_conn;
385 std::vector<dof_id_type>
387 std::vector<xdr_id_type> output_buffer;
388 std::vector<std::size_t>
391#ifdef LIBMESH_ENABLE_AMR
392 typedef std::map<dof_id_type, std::pair<processor_id_type, dof_id_type>> id_map_type;
393 id_map_type parent_id_map, child_id_map;
400 for (
const auto & elem :
as_range(
mesh.local_level_elements_begin(0),
401 mesh.local_level_elements_end(0)))
407#ifdef LIBMESH_ENABLE_AMR
408 parent_id_map[elem->id()] = std::make_pair(this->
processor_id(),
413 xfer_conn.push_back(my_next_elem);
415 std::size_t my_size = xfer_conn.size();
416 this->
comm().
gather (0, my_next_elem, n_elem_on_proc);
417 this->
comm().
gather (0, my_size, xfer_buf_sizes);
419 processor_offsets[0] = 0;
421 processor_offsets[pid] = processor_offsets[pid-1] + n_elem_on_proc[pid-1];
429 std::string comment =
"# n_elem at level 0", legend =
", [ type ";
432 if (write_partitioning)
434 if (write_subdomain_id)
437 legend +=
"p_level ";
438 legend +=
"(n0 ... nN-1) ]";
440 io.
data (n_global_elem_at_level[0], comment);
445 recv_conn.resize(xfer_buf_sizes[pid]);
447 recv_conn = xfer_conn;
455 for (
auto [elem, recv_conn_iter, n_elem_received] =
456 std::tuple{
xdr_id_type(0), recv_conn.begin(), recv_conn.back()};
457 elem<n_elem_received; elem++, next_global_elem++)
459 output_buffer.clear();
465 output_buffer.push_back(*recv_conn_iter++);
470 output_buffer.push_back(tmp);
473 tmp = *recv_conn_iter++;
474 if (write_partitioning)
475 output_buffer.push_back(tmp);
478 tmp = *recv_conn_iter++;
479 if (write_subdomain_id)
480 output_buffer.push_back(tmp);
482#ifdef LIBMESH_ENABLE_AMR
484 tmp = *recv_conn_iter++;
486 output_buffer.push_back(tmp);
490 output_buffer.push_back(*recv_conn_iter++);
494 output_buffer.push_back(*recv_conn_iter++);
497 (output_buffer.data(),
498 cast_int<unsigned int>(output_buffer.size()),
499 cast_int<unsigned int>(output_buffer.size()));
506#ifdef LIBMESH_ENABLE_AMR
511 for (
unsigned int level=1; level<n_active_levels; level++)
516 for (
const auto & parent :
as_range(
mesh.local_level_elements_begin(level-1),
517 mesh.local_level_elements_end(level-1)))
518 if (!parent->active())
520 id_map_type::iterator pos = parent_id_map.find(parent->id());
524 parent_id_map.erase(pos);
526 for (
auto & child : parent->child_ref_range())
528 pack_element (xfer_conn, &child, parent_id, parent_pid, n_elem_integers);
533 child_id_map[child.id()] = std::make_pair (child.processor_id(),
534 my_n_elem_written_at_level++);
538 xfer_conn.push_back(my_n_elem_written_at_level);
539 my_size = xfer_conn.size();
540 this->
comm().
gather (0, my_size, xfer_buf_sizes);
547 std::ostringstream buf;
548 buf <<
"# n_elem at level " << level <<
", [ type ";
553 if (write_partitioning)
555 if (write_subdomain_id)
559 buf <<
"(n0 ... nN-1) ]";
561 io.
data (n_global_elem_at_level[level], buf.str());
566 recv_conn.resize(xfer_buf_sizes[pid]);
568 recv_conn = xfer_conn;
576 for (
auto [elem, recv_conn_iter, n_elem_received] =
577 std::tuple{
xdr_id_type(0), recv_conn.begin(), recv_conn.back()};
578 elem<n_elem_received;
579 elem++, next_global_elem++)
581 output_buffer.clear();
587 output_buffer.push_back(*recv_conn_iter++);
592 output_buffer.push_back(tmp);
595 const xdr_id_type parent_local_id = *recv_conn_iter++;
600 output_buffer.push_back (parent_local_id+processor_offsets[parent_pid]);
603 tmp = *recv_conn_iter++;
604 if (write_partitioning)
605 output_buffer.push_back(tmp);
608 tmp = *recv_conn_iter++;
609 if (write_subdomain_id)
610 output_buffer.push_back(tmp);
613 tmp = *recv_conn_iter++;
615 output_buffer.push_back(tmp);
619 output_buffer.push_back(*recv_conn_iter++);
623 output_buffer.push_back(*recv_conn_iter++);
626 (output_buffer.data(),
627 cast_int<unsigned int>(output_buffer.size()),
628 cast_int<unsigned int>(output_buffer.size()));
636 processor_offsets[0] = processor_offsets.back() + n_elem_on_proc.back();
637 this->
comm().
gather (0, my_n_elem_written_at_level, n_elem_on_proc);
639 processor_offsets[pid] = processor_offsets[pid-1] + n_elem_on_proc[pid-1];
645 std::map<processor_id_type, std::vector<dof_id_type>> requested_ids;
647 for (
const auto & elem :
as_range(
mesh.local_level_elements_begin(level),
648 mesh.local_level_elements_end(level)))
649 if (!child_id_map.count(elem->id()))
651 libmesh_assert_not_equal_to (elem->parent()->processor_id(), this->processor_id());
654 requested_ids[pid].push_back(elem->id());
657 auto gather_functor =
660 const std::vector<dof_id_type> & ids,
661 std::vector<dof_id_type> & data)
663 const std::size_t ids_size = ids.size();
664 data.resize(ids_size);
667 for (std::size_t i=0; i != ids_size; i++)
670 libmesh_assert_equal_to (child_id_map[ids[i]].first, pid);
672 data[i] = child_id_map[ids[i]].second;
676 auto action_functor =
679 const std::vector<dof_id_type> & ids,
680 const std::vector<dof_id_type> & data)
682 std::size_t data_size = data.size();
684 for (std::size_t i=0; i != data_size; i++)
685 child_id_map[ids[i]] =
686 std::make_pair (pid, data[i]);
692 (this->
comm(), requested_ids, gather_functor, action_functor, ex);
696 parent_id_map.swap(child_id_map);
697 child_id_map.clear();
702 libmesh_assert_equal_to (next_global_elem, n_elem);
715 std::vector<dof_id_type> xfer_ids;
716 std::vector<Real> xfer_coords;
717 std::vector<Real> & coords=xfer_coords;
719 std::vector<std::vector<dof_id_type>> recv_ids (this->
n_processors());
720 std::vector<std::vector<Real>> recv_coords(this->
n_processors());
723 std::size_t n_written=0;
732 for (std::size_t blk=0, last_node=0; last_node<max_node_id; blk++)
734 const std::size_t first_node = blk*
io_blksize;
735 last_node = std::min((blk+1)*
io_blksize, std::size_t(max_node_id));
737 const std::size_t tot_id_size = last_node - first_node;
743 for (; node_iter != nodes_end; ++node_iter)
745 const Node & node = **node_iter;
746 libmesh_assert_greater_equal(node.
id(), first_node);
747 if (node.
id() >= last_node)
750 xfer_ids.push_back(node.
id());
751 xfer_coords.push_back(node(0));
753 xfer_coords.push_back(node(1));
756 xfer_coords.push_back(node(2));
762 std::vector<std::size_t> ids_size;
764 const std::size_t my_ids_size = xfer_ids.size();
767 this->
comm().
gather (0, my_ids_size, ids_size);
771 std::vector<Parallel::Request>
784 recv_ids[pid].resize(ids_size[pid]);
785 recv_coords[pid].resize(ids_size[pid]*LIBMESH_DIM);
789 recv_ids[0] = xfer_ids;
790 recv_coords[0] = xfer_coords;
795 id_request_handles[pid-1],
798 coord_request_handles[pid-1],
806 this->
comm().
send(0, xfer_ids, id_tag);
807 this->
comm().
send(0, xfer_coords, coord_tag);
822 libmesh_assert_equal_to(recv_coords[pid].size(),
823 recv_ids[pid].size()*LIBMESH_DIM);
839 coords.resize (3*tot_id_size, std::numeric_limits<Real>::quiet_NaN());
844 libmesh_assert_less_equal(first_node, recv_ids[pid][idx]);
845 const std::size_t local_idx = recv_ids[pid][idx] - first_node;
846 libmesh_assert_less(local_idx, tot_id_size);
848 libmesh_assert_less ((3*local_idx+2), coords.size());
849 libmesh_assert_less ((LIBMESH_DIM*idx+LIBMESH_DIM-1), recv_coords[pid].size());
851 coords[3*local_idx+0] = recv_coords[pid][LIBMESH_DIM*idx+0];
853 coords[3*local_idx+1] = recv_coords[pid][LIBMESH_DIM*idx+1];
855 coords[3*local_idx+1] = 0.;
858 coords[3*local_idx+2] = recv_coords[pid][LIBMESH_DIM*idx+2];
860 coords[3*local_idx+2] = 0.;
868 io.
data_stream (coords.empty() ?
nullptr : coords.data(),
869 cast_int<unsigned int>(coords.size()), 3);
874 libmesh_assert_less_equal (n_written, max_node_id);
876#ifdef LIBMESH_ENABLE_UNIQUE_ID
878 unsigned short write_unique_ids = 1;
880 unsigned short write_unique_ids = 0;
884 io.
data (write_unique_ids,
"# presence of unique ids");
886#ifdef LIBMESH_ENABLE_UNIQUE_ID
888 std::vector<xdr_id_type> xfer_unique_ids;
889 std::vector<xdr_id_type> & unique_ids=xfer_unique_ids;
890 std::vector<std::vector<xdr_id_type>> recv_unique_ids (this->
n_processors());
898 node_iter =
mesh.local_nodes_begin();
900 for (std::size_t blk=0, last_node=0; last_node<max_node_id; blk++)
902 const std::size_t first_node = blk*
io_blksize;
903 last_node = std::min((blk+1)*
io_blksize, std::size_t(max_node_id));
905 const std::size_t tot_id_size = last_node - first_node;
909 xfer_ids.reserve(tot_id_size);
910 xfer_unique_ids.clear();
911 xfer_unique_ids.reserve(tot_id_size);
913 for (; node_iter != nodes_end; ++node_iter)
915 const Node & node = **node_iter;
916 libmesh_assert_greater_equal(node.
id(), first_node);
917 if (node.
id() >= last_node)
920 xfer_ids.push_back(node.
id());
921 xfer_unique_ids.push_back(node.
unique_id());
926 std::vector<std::size_t> ids_size;
928 const std::size_t my_ids_size = xfer_ids.size();
931 this->
comm().
gather (0, my_ids_size, ids_size);
935 std::vector<Parallel::Request>
948 recv_ids[pid].resize(ids_size[pid]);
949 recv_unique_ids[pid].resize(ids_size[pid]);
953 recv_ids[0] = xfer_ids;
954 recv_unique_ids[0] = xfer_unique_ids;
959 id_request_handles[pid-1],
962 unique_id_request_handles[pid-1],
970 this->
comm().
send(0, xfer_ids, id_tag);
971 this->
comm().
send(0, xfer_unique_ids, unique_id_tag);
986 libmesh_assert_equal_to
987 (recv_ids[pid].size(), recv_unique_ids[pid].size());
990 libmesh_assert_less_equal
991 (tot_id_size, std::min(
io_blksize, std::size_t(max_node_id)));
1000 libmesh_assert_less_equal(first_node, recv_ids[pid][idx]);
1001 const std::size_t local_idx = recv_ids[pid][idx] - first_node;
1002 libmesh_assert_less (local_idx, unique_ids.size());
1004 unique_ids[local_idx] = recv_unique_ids[pid][idx];
1011 io.
data_stream (unique_ids.empty() ?
nullptr : unique_ids.data(),
1012 cast_int<unsigned int>(unique_ids.size()), 1);
1017 libmesh_assert_less_equal (n_written, max_node_id);
1022 if (n_node_integers)
1030 node_iter =
mesh.local_nodes_begin();
1033 std::vector<dof_id_type> xfer_node_integers;
1034 std::vector<dof_id_type> & node_integers = xfer_node_integers;
1035 std::vector<std::vector<dof_id_type>> recv_node_integers(this->
n_processors());
1037 for (std::size_t blk=0, last_node=0; last_node<max_node_id; blk++)
1039 const std::size_t first_node = blk*
io_blksize;
1040 last_node = std::min((blk+1)*
io_blksize, std::size_t(max_node_id));
1042 const std::size_t tot_id_size = last_node - first_node;
1046 xfer_ids.reserve(tot_id_size);
1047 xfer_node_integers.clear();
1048 xfer_node_integers.reserve(tot_id_size * n_node_integers);
1050 for (; node_iter != nodes_end; ++node_iter)
1052 const Node & node = **node_iter;
1053 libmesh_assert_greater_equal(node.
id(), first_node);
1054 if (node.
id() >= last_node)
1057 xfer_ids.push_back(node.
id());
1060 for (
unsigned int i=0; i != n_node_integers; ++i)
1066 std::vector<std::size_t> ids_size;
1068 const std::size_t my_ids_size = xfer_ids.size();
1071 this->
comm().
gather (0, my_ids_size, ids_size);
1075 std::vector<Parallel::Request>
1088 recv_ids[pid].resize(ids_size[pid]);
1089 recv_node_integers[pid].resize(n_node_integers * ids_size[pid]);
1093 recv_ids[0] = xfer_ids;
1094 recv_node_integers[0] = xfer_node_integers;
1099 id_request_handles[pid-1],
1101 this->
comm().
receive (pid, recv_node_integers[pid],
1102 node_integers_request_handles[pid-1],
1110 this->
comm().
send(0, xfer_ids, id_tag);
1111 this->
comm().
send(0, xfer_node_integers, node_integers_tag);
1126 libmesh_assert_equal_to
1127 (recv_ids[pid].size(), recv_node_integers[pid].size() / n_node_integers);
1130 libmesh_assert_less_equal
1131 (tot_id_size, std::min(
io_blksize, std::size_t(max_node_id)));
1146 node_integers.clear();
1147 node_integers.resize (n_node_integers*tot_id_size,
static_cast<dof_id_type>(-1));
1152 libmesh_assert_less_equal(first_node, recv_ids[pid][idx]);
1153 const std::size_t local_idx = recv_ids[pid][idx] - first_node;
1156 libmesh_assert_less (local_idx, tot_id_size);
1158 for (
unsigned int i=0; i != n_node_integers; ++i)
1159 node_integers[n_node_integers*local_idx + i] = recv_node_integers[pid][n_node_integers*idx + i];
1166 io.
data_stream (node_integers.empty() ?
nullptr : node_integers.data(),
1167 cast_int<unsigned int>(node_integers.size()), n_node_integers);
1172 libmesh_assert_less_equal (n_written, max_node_id);
1195 std::stringstream comment_string;
1196 comment_string <<
"# number of " << bc_type <<
" boundary conditions";
1197 io.
data (n_bcs_out, comment_string.str());
1203 std::vector<xdr_id_type> xfer_bcs, recv_bcs;
1204 std::vector<std::size_t> bc_sizes(this->
n_processors());
1207 std::vector<boundary_id_type> bc_ids;
1211 for (
const auto & elem :
as_range(
mesh.local_level_elements_begin(0),
1212 mesh.local_level_elements_end(0)))
1214 if (bc_type ==
"side")
1216 for (
auto s : elem->side_index_range())
1219 for (
const auto & bc_id : bc_ids)
1222 xfer_bcs.push_back (n_local_level_0_elem);
1223 xfer_bcs.push_back (s) ;
1224 xfer_bcs.push_back (bc_id);
1228 else if (bc_type ==
"edge")
1230 for (
auto e : elem->edge_index_range())
1233 for (
const auto & bc_id : bc_ids)
1236 xfer_bcs.push_back (n_local_level_0_elem);
1237 xfer_bcs.push_back (e) ;
1238 xfer_bcs.push_back (bc_id);
1242 else if (bc_type ==
"shellface")
1244 for (
unsigned short sf=0; sf<2; sf++)
1247 for (
const auto & bc_id : bc_ids)
1250 xfer_bcs.push_back (n_local_level_0_elem);
1251 xfer_bcs.push_back (sf) ;
1252 xfer_bcs.push_back (bc_id);
1258 libmesh_error_msg(
"bc_type not recognized: " + bc_type);
1262 n_local_level_0_elem++;
1265 xfer_bcs.push_back(n_local_level_0_elem);
1266 std::size_t my_size = xfer_bcs.size();
1276 recv_bcs.resize(bc_sizes[pid]);
1278 recv_bcs = xfer_bcs;
1283 = cast_int<dof_id_type>(recv_bcs.back());
1284 recv_bcs.pop_back();
1286 for (std::size_t idx=0, rbs=recv_bcs.size(); idx<rbs; idx += 3, n_bcs_out++)
1287 recv_bcs[idx+0] += elem_offset;
1289 io.
data_stream (recv_bcs.empty() ? nullptr : recv_bcs.data(),
1290 cast_int<unsigned int>(recv_bcs.size()), 3);
1291 elem_offset += my_n_local_level_0_elem;
1293 libmesh_assert_equal_to (n_bcs, n_bcs_out);
1337 io.
data (n_nodesets_out,
"# number of nodesets");
1340 if (!n_nodesets)
return;
1342 std::vector<xdr_id_type> xfer_bcs, recv_bcs;
1343 std::vector<std::size_t> bc_sizes(this->
n_processors());
1346 std::vector<boundary_id_type> nodeset_ids;
1349 for (
const auto & node :
mesh.local_node_ptr_range())
1352 for (
const auto & bc_id : nodeset_ids)
1355 xfer_bcs.push_back (node->id());
1356 xfer_bcs.push_back (bc_id);
1360 xfer_bcs.push_back(n_node);
1361 std::size_t my_size = xfer_bcs.size();
1371 recv_bcs.resize(bc_sizes[pid]);
1373 recv_bcs = xfer_bcs;
1378 cast_int<dof_id_type>(recv_bcs.back());
1379 recv_bcs.pop_back();
1381 for (std::size_t idx=0, rbs=recv_bcs.size(); idx<rbs; idx += 2, n_nodesets_out++)
1382 recv_bcs[idx+0] += node_offset;
1384 io.
data_stream (recv_bcs.empty() ? nullptr : recv_bcs.data(),
1385 cast_int<unsigned int>(recv_bcs.size()), 2);
1386 node_offset += my_n_node;
1388 libmesh_assert_equal_to (n_nodesets, n_nodesets_out);
1400 const std::map<boundary_id_type, std::string> & boundary_map = is_sideset ?
1401 info.get_sideset_name_map() : info.get_nodeset_name_map();
1403 std::vector<new_header_id_type> boundary_ids;
1404 boundary_ids.reserve(boundary_map.size());
1406 std::vector<std::string> boundary_names;
1407 boundary_names.reserve(boundary_map.size());
1413 for (
const auto & [bndry_id, name] : boundary_map)
1417 boundary_ids.push_back(bndry_id);
1418 boundary_names.push_back(name);
1422 io.
data(n_boundary_names,
"# sideset id to name map");
1424 io.
data(n_boundary_names,
"# nodeset id to name map");
1426 if (n_boundary_names)
1428 io.
data(boundary_ids);
1429 io.
data(boundary_names);
1438 LOG_SCOPE(
"read()",
"XdrIO");
1458 libmesh_error_msg_if(this->
legacy(),
"We no longer support reading files in the legacy format.");
1462 const unsigned int n_header_metadata_values = 13;
1463 std::vector<new_header_id_type> meta_data(n_header_metadata_values,
sizeof(
xdr_id_type));
1472 std::vector<old_header_id_type> old_data(n_header_metadata_values,
sizeof(
xdr_id_type));
1476 meta_data.assign(old_data.begin(), old_data.end());
1502 libmesh_type_is_same<uint64_t, unsigned long>::value))
1504 uint32_t type_size = 0;
1533 uint64_t type_size = 0;
1567template <
typename T>
1570 LOG_SCOPE(
"read_header()",
"XdrIO");
1577 std::vector<std::string> node_integer_names;
1578 std::vector<std::string> elem_integer_names;
1579 std::vector<dof_id_type> elemset_codes;
1580 std::vector<std::vector<dof_id_type>> elemset_id_vecs;
1584 io.
data (meta_data[0]);
1585 io.
data (meta_data[1]);
1594 libmesh_assert_greater_equal(meta_data.size(), 10);
1596 io.
data (meta_data[2],
"# type size");
1597 io.
data (meta_data[3],
"# uid size");
1598 io.
data (meta_data[4],
"# pid size");
1599 io.
data (meta_data[5],
"# sid size");
1600 io.
data (meta_data[6],
"# p-level size");
1602 io.
data (meta_data[7],
"# eid size");
1603 io.
data (meta_data[8],
"# side size");
1604 io.
data (meta_data[9],
"# bid size");
1610 libmesh_assert_greater_equal(meta_data.size(), 13);
1612 io.
data (meta_data[10],
"# extra integer size");
1615 io.
data(node_integer_names,
"# node integer names");
1616 meta_data[11] = node_integer_names.size();
1619 io.
data(elem_integer_names,
"# elem integer names");
1620 meta_data[12] = elem_integer_names.size();
1623 io.
data(elemset_codes,
"# elemset codes");
1626 elemset_id_vecs.resize(elemset_codes.size());
1628 io.
data(elemset_id_vecs[i]);
1646 const T & n_elem = meta_data[0];
1647 const T &
n_nodes = meta_data[1];
1675 elemset_id_vecs[i].end()));
1684 if (read_entity_info)
1689 std::vector<new_header_id_type> subdomain_ids;
1690 std::vector<std::string> subdomain_names;
1695 if (use_new_header_type)
1696 io.
data(n_subdomain_names);
1701 n_subdomain_names = temp;
1704 subdomain_ids.resize(n_subdomain_names);
1705 subdomain_names.resize(n_subdomain_names);
1707 if (n_subdomain_names)
1709 if (use_new_header_type)
1710 io.
data(subdomain_ids);
1713 std::vector<old_header_id_type> temp;
1715 subdomain_ids.assign(temp.begin(), temp.end());
1718 io.
data(subdomain_names);
1724 if (n_subdomain_names == 0)
1727 subdomain_ids.resize(n_subdomain_names);
1728 subdomain_names.resize(n_subdomain_names);
1735 for (
unsigned int i=0; i<n_subdomain_names; ++i)
1736 subdomain_map.emplace(subdomain_ids[i], subdomain_names[i]);
1741template <
typename T>
1745 const std::vector<new_header_id_type> & meta_data,
1750 if (!n_elem)
return;
1764 std::vector<T> conn, input_buffer(100 );
1769 const size_t unique_id_size_index = 3;
1771 const bool read_unique_id =
1773 meta_data[unique_id_size_index];
1776 const std::size_t n_elem_integers_index = 12;
1780 libmesh_assert_greater_equal(meta_data.size(), 13);
1781 n_elem_integers = meta_data[n_elem_integers_index];
1784 T n_elem_at_level=0, n_processed_at_level=0;
1785 for (
dof_id_type blk=0, first_elem=0, last_elem=0;
1786 last_elem<n_elem; blk++)
1788 first_elem = cast_int<dof_id_type>(blk*
io_blksize);
1789 last_elem = cast_int<dof_id_type>(std::min(cast_int<std::size_t>((blk+1)*
io_blksize),
1790 cast_int<std::size_t>(n_elem)));
1795 for (
dof_id_type e=first_elem; e<last_elem; e++, n_processed_at_level++)
1797 if (n_processed_at_level == n_elem_at_level)
1800 io.
data (n_elem_at_level);
1801 n_processed_at_level = 0;
1806 unsigned int pos = 0;
1821 input_buffer[pos++] =
static_cast<T
>(-1);
1824 if (read_partitioning)
1827 input_buffer[pos++] = 0;
1830 if (read_subdomain_id)
1833 input_buffer[pos++] = 0;
1839 input_buffer[pos++] = 0;
1843 libmesh_not_implemented();
1846 libmesh_assert_less (pos+n_nodes0, input_buffer.size());
1853 libmesh_assert_less (pos + n_elem_integers, input_buffer.size());
1854 io.
data_stream (&input_buffer[pos], n_elem_integers);
1857 pos += n_elem_integers;
1860 conn.insert (conn.end(), input_buffer.begin(), input_buffer.begin() + pos);
1863 std::size_t conn_size = conn.size();
1865 conn.resize (conn_size);
1869 for (
auto [e, it] = std::tuple{first_elem, conn.begin()}; e<last_elem; e++)
1876#ifdef LIBMESH_ENABLE_UNIQUE_ID
1887#ifdef LIBMESH_ENABLE_UNIQUE_ID
1888 unique_id = cast_int<unique_id_type>(tmp);
1897 cast_int<processor_id_type>(*it++);
1900 restrict_int<subdomain_id_type>(*it++);
1903#ifdef LIBMESH_ENABLE_AMR
1904 const unsigned int p_level = cast_int<unsigned int>(tmp);
1913#ifdef LIBMESH_ENABLE_UNIQUE_ID
1914 elem->set_unique_id(unique_id);
1916 elem->processor_id() = proc_id;
1917 elem->subdomain_id() = subdomain_id;
1918#ifdef LIBMESH_ENABLE_AMR
1919 elem->hack_p_level(p_level);
1930 for (
unsigned int n=0, n_n = elem->n_nodes(); n != n_n;
1934 cast_int<dof_id_type>(*it);
1939 elem->set_node(n, node);
1943#ifdef LIBMESH_ENABLE_UNIQUE_ID
1945 new_node->set_unique_id(n_elem + global_node_number);
1962 for (
unsigned int ei=0; ei<n_elem_integers; ++ei)
1964 auto extra_int = cast_int<dof_id_type>(*it++);
1971 for (
unsigned char i=0; i!=4; ++i)
1977 "Cannot open dimension "
1979 <<
" mesh file when configured without "
1990 const std::vector<new_header_id_type> & meta_data)
2011 std::vector<dof_id_type> needed_nodes;
2014 for (
auto & node :
mesh.node_ptr_range())
2015 needed_nodes.push_back(node->id());
2017 std::sort (needed_nodes.begin(), needed_nodes.end());
2020 libmesh_assert (std::unique(needed_nodes.begin(), needed_nodes.end()) == needed_nodes.end());
2024 const std::size_t n_node_integers_index = 11;
2028 libmesh_assert_greater_equal(meta_data.size(), 13);
2029 n_node_integers = meta_data[n_node_integers_index];
2033 std::vector<Real> coords;
2034 std::pair<std::vector<dof_id_type>::iterator,
2035 std::vector<dof_id_type>::iterator> pos;
2036 pos.first = needed_nodes.begin();
2039 for (std::size_t blk=0, first_node=0, last_node=0; last_node<
n_nodes; blk++)
2044 coords.resize(3*(last_node - first_node));
2047 io.
data_stream (coords.empty() ?
nullptr : coords.data(),
2048 cast_int<unsigned int>(coords.size()));
2055 for (std::size_t n=first_node, idx=0; n<last_node; n++, idx+=3)
2060 pos = std::equal_range (pos.first, needed_nodes.end(), n);
2062 if (pos.first != pos.second)
2064 libmesh_assert_equal_to (*pos.first, n);
2069 Point (coords[idx+0],
2078 unsigned short read_unique_ids =
false;
2083 io.
data (read_unique_ids);
2092 if (!read_unique_ids)
2094#ifdef LIBMESH_ENABLE_UNIQUE_ID
2096 for (
auto & elem :
mesh.element_ptr_range())
2097 max_elem_unique_id = std::max(max_elem_unique_id,
2098 elem->unique_id()+1);
2101 for (
auto & node :
mesh.node_ptr_range())
2102 node->set_unique_id(max_elem_unique_id + node->id());
2109 std::vector<uint32_t> unique_32;
2110 std::vector<uint64_t> unique_64;
2113 pos.first = needed_nodes.begin();
2115 for (std::size_t blk=0, first_node=0, last_node=0; last_node<
n_nodes; blk++)
2123 unique_64.resize(last_node - first_node);
2125 unique_32.resize(last_node - first_node);
2130 io.
data_stream (unique_64.empty() ?
nullptr : unique_64.data(),
2131 cast_int<unsigned int>(unique_64.size()));
2133 io.
data_stream (unique_32.empty() ? nullptr : unique_32.data(),
2134 cast_int<unsigned int>(unique_32.size()));
2137#ifdef LIBMESH_ENABLE_UNIQUE_ID
2143 for (std::size_t n=first_node, idx=0; n<last_node; n++, idx++)
2148 pos = std::equal_range (pos.first, needed_nodes.end(), n);
2150 if (pos.first != pos.second)
2152 libmesh_assert_equal_to (*pos.first, n);
2167 if (n_node_integers)
2169 std::vector<dof_id_type> extra_integers;
2172 pos.first = needed_nodes.begin();
2174 for (std::size_t blk=0, first_node=0, last_node=0; last_node<
n_nodes; blk++)
2179 extra_integers.resize((last_node - first_node) * n_node_integers);
2183 io.
data_stream (extra_integers.empty() ?
nullptr : extra_integers.data(),
2184 cast_int<unsigned int>(extra_integers.size()));
2189 for (std::size_t n=first_node, idx=0; n<last_node; n++, idx++)
2194 pos = std::equal_range (pos.first, needed_nodes.end(), n);
2196 if (pos.first != pos.second)
2198 libmesh_assert_equal_to (*pos.first, n);
2201 for (
unsigned int i=0; i != n_node_integers; ++i)
2211template <
typename T>
2227 std::vector<T> input_buffer;
2243 for (std::size_t blk=0, first_bc=0, last_bc=0; last_bc<n_bcs; blk++)
2246 last_bc = std::min((blk+1)*
io_blksize, std::size_t(n_bcs));
2248 input_buffer.resize (3*(last_bc - first_bc));
2251 io.
data_stream (input_buffer.empty() ?
nullptr : input_buffer.data(),
2252 cast_int<unsigned int>(input_buffer.size()));
2261 for (std::size_t idx=0, ibs=input_buffer.size(); idx<ibs; idx+=3)
2264 cast_int<dof_id_type>(input_buffer[idx+0]);
2265 const unsigned short side =
2266 cast_int<unsigned short>(input_buffer[idx+1]);
2268 cast_int<boundary_id_type>(input_buffer[idx+2]);
2274 if (bc_type ==
"side")
2276 libmesh_assert_less (side, elem->
n_sides());
2277 boundary_info.
add_side (elem, side, bc_id);
2279 else if (bc_type ==
"edge")
2281 libmesh_assert_less (side, elem->
n_edges());
2282 boundary_info.
add_edge (elem, side, bc_id);
2284 else if (bc_type ==
"shellface")
2287 libmesh_assert_less(side, 2);
2293 libmesh_error_msg(
"bc_type not recognized: " + bc_type);
2296 input_buffer.clear();
2302template <
typename T>
2310template <
typename T>
2318template <
typename T>
2326template <
typename T>
2342 std::vector<T> input_buffer;
2348 io.
data (n_nodesets);
2358 for (std::size_t blk=0, first_bc=0, last_bc=0; last_bc<n_nodesets; blk++)
2361 last_bc = std::min((blk+1)*
io_blksize, std::size_t(n_nodesets));
2363 input_buffer.resize (2*(last_bc - first_bc));
2366 io.
data_stream (input_buffer.empty() ?
nullptr : input_buffer.data(),
2367 cast_int<unsigned int>(input_buffer.size()));
2374 for (std::size_t idx=0, ibs=input_buffer.size(); idx<ibs; idx+=2)
2377 cast_int<dof_id_type>(input_buffer[idx+0]);
2379 cast_int<boundary_id_type>(input_buffer[idx+1]);
2383 boundary_info.
add_node (node, bc_id);
2385 input_buffer.clear();
2395 if (read_entity_info)
2398 std::vector<new_header_id_type> boundary_ids;
2399 std::vector<std::string> boundary_names;
2404 if (use_new_header_type)
2405 io.
data(n_boundary_names);
2410 n_boundary_names = temp;
2413 boundary_names.resize(n_boundary_names);
2415 if (n_boundary_names)
2417 if (use_new_header_type)
2418 io.
data(boundary_ids);
2421 std::vector<old_header_id_type> temp(n_boundary_names);
2423 boundary_ids.assign(temp.begin(), temp.end());
2425 io.
data(boundary_names);
2431 if (n_boundary_names == 0)
2434 boundary_ids.resize(n_boundary_names);
2435 boundary_names.resize(n_boundary_names);
2440 std::map<boundary_id_type, std::string> & boundary_map = is_sideset ?
2441 info.set_sideset_name_map() : info.set_nodeset_name_map();
2443 for (
unsigned int i=0; i<n_boundary_names; ++i)
2444 boundary_map.emplace(cast_int<boundary_id_type>(boundary_ids[i]), boundary_names[i]);
2459 conn.push_back(elem->
n_nodes());
2461 conn.push_back (elem->
type());
2470 conn.push_back (parent_id);
2472 conn.push_back (parent_pid);
2478#ifdef LIBMESH_ENABLE_AMR
2479 conn.push_back (elem->
p_level());
2483 conn.push_back (elem->
node_id(n));
2486 for (
unsigned int i=0; i != n_elem_integers; ++i)
2493 (this->
version().find(
"0.9.2") != std::string::npos) ||
2494 (this->
version().find(
"0.9.6") != std::string::npos) ||
2495 (this->
version().find(
"1.1.0") != std::string::npos) ||
2496 (this->
version().find(
"1.3.0") != std::string::npos) ||
2497 (this->
version().find(
"1.8.0") != std::string::npos);
2503 (this->
version().find(
"0.9.6") != std::string::npos) ||
2504 (this->
version().find(
"1.1.0") != std::string::npos) ||
2505 (this->
version().find(
"1.3.0") != std::string::npos) ||
2506 (this->
version().find(
"1.8.0") != std::string::npos);
2512 (this->
version().find(
"1.1.0") != std::string::npos) ||
2513 (this->
version().find(
"1.3.0") != std::string::npos) ||
2514 (this->
version().find(
"1.8.0") != std::string::npos);
2520 (this->
version().find(
"1.3.0") != std::string::npos) ||
2521 (this->
version().find(
"1.8.0") != std::string::npos);
2527 (this->
version().find(
"1.8.0") != std::string::npos);
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) 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 send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
void add_shellface(const dof_id_type elem, const unsigned short int shellface, const boundary_id_type id)
Add shell face shellface of element number elem with boundary id id to the boundary information data ...
void shellface_boundary_ids(const Elem *const elem, const unsigned short int shellface, std::vector< boundary_id_type > &vec_to_fill) const
std::size_t n_nodeset_conds() const
void add_edge(const dof_id_type elem, const unsigned short int edge, const boundary_id_type id)
Add edge edge of element number elem with boundary id id to the boundary information data structure.
std::size_t n_boundary_conds() const
std::size_t n_edge_conds() const
void edge_boundary_ids(const Elem *const elem, const unsigned short int edge, std::vector< boundary_id_type > &vec_to_fill) 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.
std::size_t n_shellface_conds() const
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
static const boundary_id_type invalid_id
Number used for internal use.
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure.
dof_id_type get_extra_integer(const unsigned int index) const
Gets the value on this object of the extra integer associated with index, which should have been obta...
unsigned int n_extra_integers() const
Returns how many extra integers are associated to the DofObject.
processor_id_type processor_id() const
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
unique_id_type unique_id() const
void set_unique_id(unique_id_type new_id)
Sets the unique_id for this DofObject.
void set_extra_integer(const unsigned int index, const dof_id_type value)
Sets the value on this object of the extra integer associated with index, which should have been obta...
This is the base class from which all geometric element types are derived.
static const unsigned int type_to_n_nodes_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of nodes in the element...
virtual unsigned int n_nodes() const =0
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
subdomain_id_type subdomain_id() const
void add_child(Elem *elem)
Adds a child pointer to the array of children of this element.
virtual ElemType type() const =0
IntRange< unsigned short > node_index_range() const
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
virtual unsigned int n_edges() const =0
virtual unsigned int n_sides() const =0
dof_id_type node_id(const unsigned int i) const
unsigned int p_level() const
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
This is the MeshBase class.
virtual const Node & node_ref(const dof_id_type i) const
unsigned int n_elem_integers() const
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
unsigned int mesh_dimension() const
virtual dof_id_type n_elem() const =0
const std::map< subdomain_id_type, std::string > & get_subdomain_name_map() const
std::vector< unsigned int > add_node_integers(const std::vector< std::string > &names, bool allocate_data=true, const std::vector< dof_id_type > *default_values=nullptr)
Register integer data (of type dof_id_type) to be added to each node in the mesh.
const std::string & get_node_integer_name(unsigned int i) const
std::vector< dof_id_type > get_elemset_codes() const
Return a vector of all elemset codes defined on the mesh.
virtual dof_id_type n_nodes() const =0
virtual dof_id_type max_node_id() const =0
virtual const Node * query_node_ptr(const dof_id_type i) const =0
void set_mesh_dimension(unsigned char d)
Resets the logical dimension of the mesh.
virtual const Elem * elem_ptr(const dof_id_type i) const =0
virtual void set_next_unique_id(unique_id_type id)=0
Sets the next available unique id to be used.
virtual Node * add_node(Node *n)=0
Add Node n to the end of the vertex array.
const std::string & get_elem_integer_name(unsigned int i) const
void add_elemset_code(dof_id_type code, MeshBase::elemset_type id_set)
Tabulate a user-defined "code" for elements which belong to the element sets specified in id_set.
unsigned int n_node_integers() const
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
void get_elemsets(dof_id_type elemset_code, MeshBase::elemset_type &id_set_to_fill) const
Look up the element sets for a given elemset code and vice-versa.
virtual void reserve_elem(const dof_id_type ne)=0
Reserves space for a known number of elements.
std::set< elemset_id_type > elemset_type
Typedef for the "set" container used to store elemset ids.
std::vector< unsigned int > add_elem_integers(const std::vector< std::string > &names, bool allocate_data=true, const std::vector< dof_id_type > *default_values=nullptr)
Register integer data (of type dof_id_type) to be added to each element in the mesh,...
std::map< subdomain_id_type, std::string > & set_subdomain_name_map()
subdomain_id_type n_subdomains() const
virtual void reserve_nodes(const dof_id_type nn)=0
Reserves space for a known number of nodes.
This class defines an abstract interface for Mesh output.
A Node is like a Point, but with more information.
static std::unique_ptr< Node > build(const Node &n)
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
static void set_node_processor_ids(MeshBase &mesh)
This function is called after partitioning to set the processor IDs for the nodes.
A Point defines a location in LIBMESH_DIM dimensional Real space.
void write_serialized_connectivity(Xdr &io, const dof_id_type n_elem, const new_header_id_type n_elem_integers) const
Write the connectivity for a parallel, distributed mesh.
XdrIO(MeshBase &, const bool=false)
Constructor.
bool binary() const
Get/Set the flag indicating if we should read/write binary.
bool legacy() const
Get/Set the flag indicating if we should read/write legacy.
void read_serialized_edge_bcs(Xdr &io, T type_size)
Read the edge boundary conditions for a parallel, distributed mesh.
bool write_parallel() const
Report whether we should write parallel files.
bool version_at_least_1_3_0() const
void write_serialized_bcs_helper(Xdr &io, const new_header_id_type n_side_bcs, const std::string bc_type) const
Helper function used in write_serialized_side_bcs, write_serialized_edge_bcs, and write_serialized_sh...
void read_serialized_bcs_helper(Xdr &io, T type_size, const std::string bc_type)
Helper function used in read_serialized_side_bcs, read_serialized_edge_bcs, and read_serialized_shell...
largest_id_type xdr_id_type
virtual ~XdrIO()
Destructor.
void write_serialized_edge_bcs(Xdr &io, const new_header_id_type n_edge_bcs) const
Write the edge boundary conditions for a parallel, distributed mesh.
bool version_at_least_1_8_0() const
void write_serialized_nodesets(Xdr &io, const new_header_id_type n_nodesets) const
Write the boundary conditions for a parallel, distributed mesh.
bool version_at_least_0_9_6() const
void read_serialized_nodes(Xdr &io, const dof_id_type n_nodes, const std::vector< new_header_id_type > &meta_data)
Read the nodal locations for a parallel, distributed mesh.
bool version_at_least_0_9_2() const
void read_serialized_nodesets(Xdr &io, T type_size)
Read the nodeset conditions for a parallel, distributed mesh.
void write_serialized_nodes(Xdr &io, const dof_id_type n_nodes, const new_header_id_type n_node_integers) const
Write the nodal locations for a parallel, distributed mesh.
const std::string & boundary_condition_file_name() const
Get/Set the boundary condition file name.
void read_header(Xdr &io, std::vector< T > &meta_data)
Read header information - templated to handle old (4-byte) or new (8-byte) header id types.
void write_serialized_shellface_bcs(Xdr &io, const new_header_id_type n_shellface_bcs) const
Write the "shell face" boundary conditions for a parallel, distributed mesh.
uint32_t old_header_id_type
void read_serialized_shellface_bcs(Xdr &io, T type_size)
Read the "shell face" boundary conditions for a parallel, distributed mesh.
void read_serialized_subdomain_names(Xdr &io)
Read subdomain name information - NEW in 0.9.2 format.
const std::string & polynomial_level_file_name() const
Get/Set the polynomial degree file name.
const std::string & version() const
Get/Set the version string.
void pack_element(std::vector< xdr_id_type > &conn, const Elem *elem, const dof_id_type parent_id, const dof_id_type parent_pid, const new_header_id_type n_elem_integers) const
Pack an element into a transfer buffer for parallel communication.
void read_serialized_bc_names(Xdr &io, BoundaryInfo &info, bool is_sideset)
Read boundary names information (sideset and nodeset) - NEW in 0.9.2 format.
unsigned int _field_width
void write_serialized_subdomain_names(Xdr &io) const
Write subdomain name information - NEW in 0.9.2 format.
static const std::size_t io_blksize
Define the block size to use for chunked IO.
void read_serialized_side_bcs(Xdr &io, T type_size)
Read the side boundary conditions for a parallel, distributed mesh.
virtual void write(const std::string &) override
This method implements writing a mesh to a specified file.
void write_serialized_side_bcs(Xdr &io, const new_header_id_type n_side_bcs) const
Write the side boundary conditions for a parallel, distributed mesh.
const std::string & partition_map_file_name() const
Get/Set the partitioning file name.
const std::string & subdomain_map_file_name() const
Get/Set the subdomain file name.
void write_serialized_bc_names(Xdr &io, const BoundaryInfo &info, bool is_sideset) const
Write boundary names information (sideset and nodeset) - NEW in 0.9.2 format.
void read_serialized_connectivity(Xdr &io, const dof_id_type n_elem, const std::vector< new_header_id_type > &meta_data, T type_size)
Read the connectivity for a parallel, distributed mesh.
bool version_at_least_1_1_0() const
uint64_t new_header_id_type
virtual void read(const std::string &) override
This method implements reading a mesh from a specified file.
This class implements a C++ interface to the XDR (eXternal Data Representation) format.
void data_stream(T *val, const unsigned int len, const unsigned int line_break=libMesh::invalid_uint)
Inputs or outputs a raw data stream.
void close()
Closes the file if it is open.
void data(T &a, std::string_view comment="")
Inputs or outputs a single value.
void pull_parallel_vector_data(const Communicator &comm, const MapToVectors &queries, GatherFunctor &gather_data, const ActionFunctor &act_on_data, const datum *example)
The libMesh namespace provides an interface to certain functionality in the library.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
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.
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
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...
The definition of the const_node_iterator struct.
const dof_id_type n_nodes