19 #include "libmesh/libmesh_common.h" 20 #include "libmesh/parallel.h" 24 #include "libmesh/libmesh_version.h" 25 #include "libmesh/system.h" 26 #include "libmesh/mesh_base.h" 27 #include "libmesh/elem.h" 28 #include "libmesh/xdr_cxx.h" 29 #include "libmesh/numeric_vector.h" 30 #include "libmesh/dof_map.h" 64 const std::size_t max_io_blksize = 256000;
69 template <
typename InValType>
74 std::vector<InValType> & _data;
77 ThreadedIO (
libMesh::Xdr & io, std::vector<InValType> & data) :
84 if (_data.empty())
return;
85 _io.
data_stream (_data.data(), cast_int<unsigned int>(_data.size()));
98 std::string_view version,
99 const bool read_header_in,
100 const bool read_additional_data,
101 const bool read_legacy_format)
142 const bool read_ifem_info =
158 for (
unsigned int var=0; var<nv; var++)
162 std::string var_name;
168 std::set<subdomain_id_type> domains;
169 if (io.
version() >= LIBMESH_VERSION_ID(0,7,2))
171 std::vector<subdomain_id_type> domain_array;
173 io.
data (domain_array);
174 for (
const auto &
id : domain_array)
210 if (read_legacy_format)
216 libMesh::out <<
"*****************************************************************\n" 217 <<
"* WARNING: reading a potentially incompatible restart file!!! *\n" 218 <<
"* contact libmesh-users@lists.sourceforge.net for more details *\n" 219 <<
"*****************************************************************" 229 io.
data (radial_fam);
236 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 258 unsigned int nvecs=0;
268 for (
unsigned int vec=0; vec<nvecs; vec++)
272 std::string vec_name;
276 if (io.
version() >= LIBMESH_VERSION_ID(1,7,0))
278 int vec_projection = 0;
280 io.
data (vec_projection);
287 if (read_additional_data)
290 else if (read_additional_data)
301 template <
typename InValType>
303 const bool read_additional_data)
339 std::vector<const DofObject *> ordered_nodes, ordered_elements;
341 std::set<const DofObject *, CompareDofObjectsByID>
342 ordered_nodes_set (this->
get_mesh().local_nodes_begin(),
343 this->
get_mesh().local_nodes_end());
345 ordered_nodes.insert(ordered_nodes.end(),
346 ordered_nodes_set.begin(),
347 ordered_nodes_set.end());
350 std::set<const DofObject *, CompareDofObjectsByID>
351 ordered_elements_set (this->
get_mesh().local_elements_begin(),
352 this->
get_mesh().local_elements_end());
354 ordered_elements.insert(ordered_elements.end(),
355 ordered_elements_set.begin(),
356 ordered_elements_set.end());
360 std::vector<InValType> io_buffer;
368 total_read_size += cast_int<dof_id_type>(io_buffer.size());
370 const unsigned int sys_num = this->
number();
371 const unsigned int nv = cast_int<unsigned int>
373 libmesh_assert_less_equal (nv, this->
n_vars());
378 for (
unsigned int data_var=0; data_var<nv; data_var++)
384 for (
const auto & node : ordered_nodes)
385 for (
auto comp :
make_range(node->n_comp(sys_num,var)))
387 libmesh_assert_not_equal_to (node->dof_number(sys_num, var, comp),
389 libmesh_assert_less (cnt, io_buffer.size());
390 this->
solution->set(node->dof_number(sys_num, var, comp), io_buffer[cnt++]);
394 for (
const auto & elem : ordered_elements)
395 for (
auto comp :
make_range(elem->n_comp(sys_num,var)))
397 libmesh_assert_not_equal_to (elem->dof_number(sys_num, var, comp),
399 libmesh_assert_less (cnt, io_buffer.size());
400 this->
solution->set(elem->dof_number(sys_num, var, comp), io_buffer[cnt++]);
406 for (
unsigned int data_var=0; data_var<nv; data_var++)
414 std::vector<dof_id_type> SCALAR_dofs;
417 for (
auto dof : SCALAR_dofs)
418 this->
solution->set(dof, io_buffer[cnt++]);
432 const std::size_t nvecs = this->
_vectors.size();
438 if (read_additional_data && nvecs &&
441 (
"Additional vectors in file do not match system");
456 total_read_size += cast_int<dof_id_type>(io_buffer.size());
461 if (read_additional_data && nvecs)
464 for (
unsigned int data_var=0; data_var<nv; data_var++)
470 for (
const auto & node : ordered_nodes)
471 for (
auto comp :
make_range(node->n_comp(sys_num,var)))
473 libmesh_assert_not_equal_to (node->dof_number(sys_num, var, comp),
475 libmesh_assert_less (cnt, io_buffer.size());
476 pos->second->set(node->dof_number(sys_num, var, comp), io_buffer[cnt++]);
480 for (
const auto & elem : ordered_elements)
481 for (
auto comp :
make_range(elem->n_comp(sys_num,var)))
483 libmesh_assert_not_equal_to (elem->dof_number(sys_num, var, comp),
485 libmesh_assert_less (cnt, io_buffer.size());
486 pos->second->set(elem->dof_number(sys_num, var, comp), io_buffer[cnt++]);
492 for (
unsigned int data_var=0; data_var<nv; data_var++)
500 std::vector<dof_id_type> SCALAR_dofs;
503 for (
auto dof : SCALAR_dofs)
504 pos->second->set(dof, io_buffer[cnt++]);
510 pos->second->close();
532 template <
typename InValType>
534 const bool read_additional_data)
547 parallel_object_only();
558 this->read_serialized_vector<InValType>(io, this->
solution.get());
562 io.comment (comment);
570 const std::size_t nvecs = this->
_vectors.size();
576 if (read_additional_data && nvecs &&
579 (
"Additional vectors in file do not match system");
589 this->read_serialized_vector<InValType>
590 (io, (read_additional_data && nvecs) ? pos->second.get() :
nullptr);
594 io.comment (comment);
617 template <
typename iterator_type,
typename InValType>
619 const iterator_type begin,
620 const iterator_type end,
624 const unsigned int var_to_read)
const 646 vars_to_read.clear();
647 vars_to_read.push_back(var_to_read);
652 num_vecs = cast_int<unsigned int>(vecs.size());
654 io_blksize = cast_int<dof_id_type>(std::min(max_io_blksize, static_cast<std::size_t>(n_objs))),
655 num_blks = cast_int<unsigned int>(std::ceil(static_cast<double>(n_objs)/
656 static_cast<double>(io_blksize)));
660 std::size_t n_read_values=0;
662 std::vector<std::vector<dof_id_type>> xfer_ids(num_blks);
663 std::vector<std::vector<Number>> recv_vals(num_blks);
664 std::vector<Parallel::Request>
665 id_requests(num_blks), val_requests(num_blks);
666 std::vector<Parallel::MessageTag>
667 id_tags(num_blks), val_tags(num_blks);
673 std::vector<std::size_t>
674 xfer_ids_size (num_blks,0),
675 recv_vals_size (num_blks,0);
678 for (iterator_type it=begin; it!=end; ++it)
682 block =
id/io_blksize;
684 libmesh_assert_less (block, num_blks);
686 xfer_ids_size[block] += 2;
689 for (
const auto & var : vars_to_read)
690 n_comp_tot += (*it)->n_comp(sys_num, var);
692 recv_vals_size[block] += n_comp_tot*num_vecs;
697 std::vector<std::size_t> tot_vals_size(recv_vals_size);
698 this->
comm().
sum (tot_vals_size);
710 first_object = blk*io_blksize,
711 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs);
714 std::vector<dof_id_type> & ids (xfer_ids[blk]);
715 std::vector<Number> & vals (recv_vals[blk]);
719 ids.clear(); ids.reserve (xfer_ids_size[blk]);
720 vals.resize(recv_vals_size[blk]);
723 std::unordered_set<dof_id_type> seen_ids;
726 if (recv_vals_size[blk] != 0)
727 for (iterator_type it=begin; it!=end; ++it)
737 if ((
id >= first_object) &&
742 unsigned int n_comp_tot=0;
744 for (
const auto & var : vars_to_read)
745 n_comp_tot += (*it)->n_comp(sys_num, var);
747 ids.push_back (n_comp_tot*num_vecs);
751 #ifdef LIBMESH_HAVE_MPI 756 this->
comm().
send (0, ids, id_requests[blk], id_tags[blk]);
759 this->
comm().
receive (0, vals, val_requests[blk], val_tags[blk]);
769 std::vector<std::vector<dof_id_type>> recv_ids (this->
n_processors());
770 std::vector<std::vector<Number>> send_vals (this->
n_processors());
771 std::vector<Parallel::Request> reply_requests (this->
n_processors());
772 std::vector<unsigned int> obj_val_offsets;
773 std::vector<Number> input_vals;
774 std::vector<InValType> input_vals_tmp;
781 first_object = blk*io_blksize,
782 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs),
783 n_objects_blk = last_object - first_object;
791 input_vals.resize(tot_vals_size[blk]);
792 input_vals_tmp.resize(tot_vals_size[blk]);
795 ThreadedIO<InValType> threaded_io(io, input_vals_tmp);
801 obj_val_offsets.resize (n_objects_blk); std::fill (obj_val_offsets.begin(), obj_val_offsets.end(), 0);
805 std::size_t n_vals_blk = 0;
811 #ifdef LIBMESH_HAVE_MPI 814 std::vector<dof_id_type> & ids (recv_ids[id_status.
source()]);
815 std::size_t & n_vals_proc (recv_vals_size[id_status.
source()]);
819 std::vector<dof_id_type> & ids (recv_ids[0]);
820 std::size_t & n_vals_proc (recv_vals_size[0]);
828 for (std::size_t
idx=0, sz=ids.size();
idx<sz;
idx+=2)
831 local_idx = ids[
idx+0]-first_object,
832 n_vals_tot_allvecs = ids[
idx+1];
834 libmesh_assert_less (local_idx, n_objects_blk);
836 obj_val_offsets[local_idx] = n_vals_tot_allvecs;
837 n_vals_proc += n_vals_tot_allvecs;
841 n_vals_blk += n_vals_proc;
848 std::partial_sum(obj_val_offsets.begin(), obj_val_offsets.end(),
849 obj_val_offsets.begin());
851 libmesh_assert_equal_to (n_vals_blk, obj_val_offsets.back());
852 libmesh_assert_equal_to (n_vals_blk, tot_vals_size[blk]);
858 input_vals[i_val] = input_vals_tmp[i_val];
860 n_read_values += input_vals.size();
865 const std::vector<dof_id_type> & ids (recv_ids[proc]);
866 std::vector<Number> & vals (send_vals[proc]);
867 const std::size_t & n_vals_proc (recv_vals_size[proc]);
869 vals.clear(); vals.reserve(n_vals_proc);
871 for (std::size_t
idx=0, sz=ids.size();
idx<sz;
idx+=2)
874 local_idx = ids[
idx+0]-first_object,
875 n_vals_tot_allvecs = ids[
idx+1];
877 std::vector<Number>::const_iterator in_vals(input_vals.begin());
879 std::advance (in_vals, obj_val_offsets[local_idx-1]);
881 for (
unsigned int val=0; val<n_vals_tot_allvecs; val++, ++in_vals)
885 vals.push_back(*in_vals);
889 #ifdef LIBMESH_HAVE_MPI 891 this->
comm().
send (proc, vals, reply_requests[proc], val_tags[blk]);
893 recv_vals[blk] = vals;
900 Parallel::wait (val_requests[blk]);
902 const std::vector<Number> & vals (recv_vals[blk]);
903 std::vector<Number>::const_iterator val_it(vals.begin());
905 if (!recv_vals[blk].empty())
906 for (iterator_type it=begin; it!=end; ++it)
907 if (((*it)->id() >= first_object) &&
908 ((*it)->id() < last_object))
910 for (
auto & vec : vecs)
911 for (
const auto & var : vars_to_read)
913 const unsigned int n_comp = (*it)->n_comp(sys_num, var);
915 for (
unsigned int comp=0; comp<n_comp; comp++, ++val_it)
917 const dof_id_type dof_index = (*it)->dof_number (sys_num, var, comp);
921 libmesh_assert_greater_equal (dof_index, vec->first_local_index());
922 libmesh_assert_less (dof_index, vec->last_local_index());
924 vec->set (dof_index, *val_it);
932 Parallel::wait(reply_requests);
935 Parallel::wait(id_requests);
937 return n_read_values;
946 unsigned int n_assigned_vals = 0;
950 std::vector<Number> input_buffer(n_SCALAR_dofs);
952 io.
data_stream(input_buffer.data(), n_SCALAR_dofs);
954 #ifdef LIBMESH_HAVE_MPI 973 std::vector<dof_id_type> SCALAR_dofs;
979 vec->
set (SCALAR_dofs[i], input_buffer[i]);
984 return n_assigned_vals;
988 template <
typename InValType>
992 parallel_object_only();
1007 unsigned int vector_length=0;
1009 std::size_t n_assigned_vals=0;
1014 io.
data(vector_length,
"# vector length");
1017 const unsigned int nv = cast_int<unsigned int>
1023 libmesh_assert_less_equal (nv, this->
n_vars());
1026 if (io.
version() >= LIBMESH_VERSION_ID(0,7,4))
1034 this->
get_mesh().local_nodes_begin(),
1035 this->
get_mesh().local_nodes_end(),
1047 this->
get_mesh().local_elements_begin(),
1048 this->
get_mesh().local_elements_end(),
1058 for (
unsigned int data_var=0; data_var<nv; data_var++)
1069 this->
get_mesh().local_nodes_begin(),
1070 this->
get_mesh().local_nodes_end(),
1083 this->
get_mesh().local_elements_begin(),
1084 this->
get_mesh().local_elements_end(),
1095 for (
unsigned int data_var=0; data_var<nv; data_var++)
1111 this->
comm().
sum (n_assigned_vals);
1112 libmesh_assert_equal_to (n_assigned_vals, vector_length);
1115 return vector_length;
1122 const bool write_additional_data)
const 1165 std::string comment;
1172 comment =
"# No. of Variables in System \"";
1173 comment += this->
name();
1176 unsigned int nv = this->
n_vars();
1177 io.
data (nv, comment);
1187 comment =
"# Name, Variable No. ";
1188 comment += std::to_string(var);
1189 comment +=
", System \"";
1190 comment += this->
name();
1194 io.
data (var_name, comment);
1200 comment =
"# Subdomains, Variable \"";
1202 comment +=
"\", System \"";
1203 comment += this->
name();
1207 std::vector<subdomain_id_type> domain_array;
1208 domain_array.assign(domains.begin(), domains.end());
1209 io.
data (domain_array, comment);
1217 comment =
"# Approximation Order, Variable \"";
1219 comment +=
"\", System \"";
1220 comment += this->
name();
1224 io.
data (order, comment);
1228 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 1232 comment =
"# Radial Approximation Order, Variable \"";
1234 comment +=
"\", System \"";
1235 comment += this->
name();
1239 io.
data (rad_order, comment);
1248 comment =
"# FE Family, Variable \"";
1250 comment +=
"\", System \"";
1251 comment += this->
name();
1255 int fam =
static_cast<int>(type.
family);
1256 io.
data (fam, comment);
1258 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 1260 comment =
"# Radial FE Family, Variable \"";
1262 comment +=
"\", System \"";
1263 comment += this->
name();
1267 io.
data (radial_fam, comment);
1269 comment =
"# Infinite Mapping Type, Variable \"";
1271 comment +=
"\", System \"";
1272 comment += this->
name();
1275 int i_map =
static_cast<int>(type.
inf_map);
1276 io.
data (i_map, comment);
1288 comment =
"# No. of Additional Vectors, System \"";
1289 comment += this->
name();
1292 unsigned int nvecs = write_additional_data ? this->
n_vectors () : 0;
1293 io.
data (nvecs, comment);
1296 if (write_additional_data)
1299 for (
const auto & [vec_name, vec] :
_vectors)
1303 const std::string dth_vector = std::to_string(cnt++)+
"th vector";
1304 comment =
"# Name of " + dth_vector;
1305 std::string nonconst_vec_name = vec_name;
1307 io.
data (nonconst_vec_name, comment);
1309 comment =
"# Whether to do projections for " + dth_vector;
1310 io.
data (vec_projection, comment);
1311 int vec_type = vec->type();
1312 comment =
"# Parallel type of " + dth_vector;
1313 io.
data (vec_type, comment);
1322 const bool write_additional_data)
const 1347 std::string comment;
1351 std::vector<Number> io_buffer; io_buffer.reserve(this->
solution->local_size());
1361 std::vector<const DofObject *> ordered_nodes, ordered_elements;
1363 std::set<const DofObject *, CompareDofObjectsByID>
1364 ordered_nodes_set (this->
get_mesh().local_nodes_begin(),
1365 this->
get_mesh().local_nodes_end());
1367 ordered_nodes.insert(ordered_nodes.end(),
1368 ordered_nodes_set.begin(),
1369 ordered_nodes_set.end());
1372 std::set<const DofObject *, CompareDofObjectsByID>
1373 ordered_elements_set (this->
get_mesh().local_elements_begin(),
1374 this->
get_mesh().local_elements_end());
1376 ordered_elements.insert(ordered_elements.end(),
1377 ordered_elements_set.begin(),
1378 ordered_elements_set.end());
1381 const unsigned int sys_num = this->
number();
1382 const unsigned int nv = this->
n_vars();
1385 for (
unsigned int var=0; var<nv; var++)
1389 for (
const auto & node : ordered_nodes)
1390 for (
auto comp :
make_range(node->n_comp(sys_num,var)))
1392 libmesh_assert_not_equal_to (node->dof_number(sys_num, var, comp),
1395 io_buffer.push_back((*this->
solution)(node->dof_number(sys_num, var, comp)));
1399 for (
const auto & elem : ordered_elements)
1400 for (
auto comp :
make_range(elem->n_comp(sys_num,var)))
1402 libmesh_assert_not_equal_to (elem->dof_number(sys_num, var, comp),
1405 io_buffer.push_back((*this->
solution)(elem->dof_number(sys_num, var, comp)));
1416 std::vector<dof_id_type> SCALAR_dofs;
1419 for (
auto dof : SCALAR_dofs)
1420 io_buffer.push_back((*this->
solution)(dof));
1431 comment =
"# System \"";
1432 comment += this->
name();
1433 comment +=
"\" Solution Vector";
1436 io.
data (io_buffer, comment);
1441 if (write_additional_data)
1443 for (
auto & [vec_name, vec] :
_vectors)
1446 io_buffer.reserve(vec->local_size());
1449 for (
unsigned int var=0; var<nv; var++)
1453 for (
const auto & node : ordered_nodes)
1454 for (
auto comp :
make_range(node->n_comp(sys_num,var)))
1456 libmesh_assert_not_equal_to (node->dof_number(sys_num, var, comp),
1459 io_buffer.push_back((*vec)(node->dof_number(sys_num, var, comp)));
1463 for (
const auto & elem : ordered_elements)
1464 for (
auto comp :
make_range(elem->n_comp(sys_num,var)))
1466 libmesh_assert_not_equal_to (elem->dof_number(sys_num, var, comp),
1469 io_buffer.push_back((*vec)(elem->dof_number(sys_num, var, comp)));
1480 std::vector<dof_id_type> SCALAR_dofs;
1483 for (
auto dof : SCALAR_dofs)
1484 io_buffer.push_back((*vec)(dof));
1495 comment =
"# System \"";
1496 comment += this->
name();
1497 comment +=
"\" Additional Vector \"";
1498 comment += vec_name;
1502 io.
data (io_buffer, comment);
1522 const bool write_additional_data)
const 1537 parallel_object_only();
1538 std::string comment;
1550 comment =
"# System \"";
1551 comment += this->
name();
1552 comment +=
"\" Solution Vector";
1558 if (write_additional_data)
1568 comment =
"# System \"";
1569 comment += this->
name();
1570 comment +=
"\" Additional Vector \"";
1571 comment += pair.first;
1628 template <
typename iterator_type>
1631 const iterator_type begin,
1632 const iterator_type end,
1634 const unsigned int var_to_write)
const 1636 parallel_object_only();
1654 std::vector<unsigned int> vars_to_write(1, var_to_write);
1658 vars_to_write.clear(); vars_to_write.reserve(this->
n_vars());
1660 vars_to_write.push_back(var);
1663 const dof_id_type io_blksize = cast_int<dof_id_type>
1664 (std::min(max_io_blksize, static_cast<std::size_t>(n_objs)));
1667 sys_num = this->
number(),
1668 num_vecs = cast_int<unsigned int>(vecs.size()),
1669 num_blks = cast_int<unsigned int>(std::ceil(static_cast<double>(n_objs)/
1670 static_cast<double>(io_blksize)));
1677 std::size_t written_length=0;
1678 std::vector<std::vector<dof_id_type>> xfer_ids(num_blks);
1679 std::vector<std::vector<Number>> send_vals(num_blks);
1680 std::vector<Parallel::Request>
1681 id_requests(num_blks), val_requests(num_blks);
1682 std::vector<Parallel::MessageTag>
1683 id_tags(num_blks), val_tags(num_blks);
1689 std::vector<unsigned int>
1690 xfer_ids_size (num_blks,0),
1691 send_vals_size (num_blks,0);
1693 for (iterator_type it=begin; it!=end; ++it)
1697 block =
id/io_blksize;
1699 libmesh_assert_less (block, num_blks);
1701 xfer_ids_size[block] += 2;
1703 unsigned int n_comp_tot=0;
1705 for (
const auto & var : vars_to_write)
1706 n_comp_tot += (*it)->n_comp(sys_num, var);
1708 send_vals_size[block] += n_comp_tot*num_vecs;
1715 for (
unsigned int blk=0; blk<num_blks; blk++)
1722 first_object = blk*io_blksize,
1723 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs);
1726 std::vector<dof_id_type> & ids (xfer_ids[blk]);
1727 std::vector<Number> & vals (send_vals[blk]);
1731 ids.clear(); ids.reserve (xfer_ids_size[blk]);
1732 vals.clear(); vals.reserve (send_vals_size[blk]);
1734 if (send_vals_size[blk] != 0)
1735 for (iterator_type it=begin; it!=end; ++it)
1736 if (((*it)->id() >= first_object) &&
1737 ((*it)->id() < last_object))
1739 ids.push_back((*it)->id());
1743 unsigned int n_comp_tot=0;
1745 for (
const auto & var : vars_to_write)
1746 n_comp_tot += (*it)->n_comp(sys_num, var);
1748 ids.push_back (n_comp_tot*num_vecs);
1752 for (
const auto & vec : vecs)
1753 for (
const auto & var : vars_to_write)
1755 const unsigned int n_comp = (*it)->n_comp(sys_num, var);
1757 for (
unsigned int comp=0; comp<n_comp; comp++)
1759 libmesh_assert_greater_equal ((*it)->dof_number(sys_num, var, comp), vec->first_local_index());
1760 libmesh_assert_less ((*it)->dof_number(sys_num, var, comp), vec->last_local_index());
1761 vals.push_back((*vec)((*it)->dof_number(sys_num, var, comp)));
1766 #ifdef LIBMESH_HAVE_MPI 1771 this->
comm().
send (0, ids, id_requests[blk], id_tags[blk]);
1772 this->
comm().
send (0, vals, val_requests[blk], val_tags[blk]);
1779 std::vector<std::vector<dof_id_type>> recv_ids (this->
n_processors());
1780 std::vector<std::vector<Number>> recv_vals (this->
n_processors());
1781 std::vector<unsigned int> obj_val_offsets;
1782 std::vector<Number> output_vals;
1785 ThreadedIO<Number> threaded_io(io, output_vals);
1786 std::unique_ptr<Threads::Thread> async_io;
1788 for (
unsigned int blk=0; blk<num_blks; blk++)
1793 first_object = cast_int<dof_id_type>(blk*io_blksize),
1794 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs),
1795 n_objects_blk = last_object - first_object;
1800 obj_val_offsets.resize (n_objects_blk); std::fill (obj_val_offsets.begin(), obj_val_offsets.end(), 0);
1802 std::size_t n_val_recvd_blk=0;
1807 #ifdef LIBMESH_HAVE_MPI 1810 std::vector<dof_id_type> & ids (recv_ids[id_status.
source()]);
1813 std::vector<dof_id_type> & ids (recv_ids[0]);
1814 ids = xfer_ids[blk];
1819 for (std::size_t
idx=0, sz=ids.size();
idx<sz;
idx+=2)
1822 local_idx = ids[
idx+0]-first_object,
1823 n_vals_tot_allvecs = ids[
idx+1];
1825 libmesh_assert_less (local_idx, n_objects_blk);
1826 libmesh_assert_less (local_idx, obj_val_offsets.size());
1828 obj_val_offsets[local_idx] = n_vals_tot_allvecs;
1831 #ifdef LIBMESH_HAVE_MPI 1834 std::vector<Number> & vals (recv_vals[val_status.
source()]);
1838 std::vector<Number> & vals (recv_vals[0]);
1839 vals = send_vals[blk];
1842 n_val_recvd_blk += vals.size();
1848 std::partial_sum(obj_val_offsets.begin(), obj_val_offsets.end(),
1849 obj_val_offsets.begin());
1853 if (async_io.get()) async_io->join();
1857 output_vals.resize(n_val_recvd_blk);
1862 const std::vector<dof_id_type> & ids (recv_ids [proc]);
1863 const std::vector<Number> & vals(recv_vals[proc]);
1864 std::vector<Number>::const_iterator proc_vals(vals.begin());
1866 for (std::size_t
idx=0, sz=ids.size();
idx<sz;
idx+=2)
1869 local_idx = ids[
idx+0]-first_object,
1870 n_vals_tot_allvecs = ids[
idx+1];
1874 std::vector<Number>::iterator out_vals(output_vals.begin());
1876 std::advance (out_vals, obj_val_offsets[local_idx-1]);
1878 for (
unsigned int val=0; val<n_vals_tot_allvecs; val++, ++out_vals, ++proc_vals)
1882 *out_vals = *proc_vals;
1889 async_io = std::make_unique<Threads::Thread>(threaded_io);
1890 written_length += output_vals.size();
1898 Parallel::wait(id_requests);
1899 Parallel::wait(val_requests);
1910 return written_length;
1916 const unsigned int var,
1919 unsigned int written_length=0;
1920 std::vector<Number> vals;
1925 std::vector<dof_id_type> SCALAR_dofs;
1927 const unsigned int n_scalar_dofs = cast_int<unsigned int>
1928 (SCALAR_dofs.size());
1930 for (
unsigned int i=0; i<n_scalar_dofs; i++)
1932 vals.push_back( vec(SCALAR_dofs[i]) );
1936 #ifdef LIBMESH_HAVE_MPI 1951 this->
comm().
send(0, vals, val_tag);
1960 const unsigned int vals_size =
1961 cast_int<unsigned int>(vals.size());
1963 written_length += vals_size;
1966 return written_length;
1974 parallel_object_only();
1985 written_length += cast_int<dof_id_type>
1988 this->
get_mesh().local_nodes_begin(),
1989 this->
get_mesh().local_nodes_end(),
1994 written_length += cast_int<dof_id_type>
1997 this->
get_mesh().local_elements_begin(),
1998 this->
get_mesh().local_elements_end(),
2011 libmesh_assert_equal_to (written_length, vec_length);
2013 return written_length;
2017 template <
typename InValType>
2021 parallel_object_only();
2039 unsigned int num_vecs=0;
2045 io.
data(vector_length);
2047 libmesh_error_msg_if
2048 (num_vecs != vectors.size(),
2049 "Xdr file header declares " << num_vecs <<
" vectors, but we were asked to read " << vectors.size());
2053 libmesh_error_msg_if (vectors[0] ==
nullptr,
"vectors[0] should not be null");
2054 libmesh_error_msg_if (vectors[0]->size() != vector_length,
"Inconsistent vector sizes");
2067 std::size_t read_length = 0;
2073 this->
get_mesh().local_nodes_begin(),
2074 this->
get_mesh().local_nodes_end(),
2083 this->
get_mesh().local_elements_begin(),
2084 this->
get_mesh().local_elements_end(),
2095 libmesh_assert_not_equal_to (vec, 0);
2105 libmesh_assert_not_equal_to (vec, 0);
2117 parallel_object_only();
2126 std::size_t written_length = 0;
2131 n_vec = cast_int<unsigned int>(vectors.size());
2133 vec_size = vectors.empty() ? 0 : vectors[0]->size();
2135 io.
data(n_vec,
"# number of vectors");
2137 io.
data(vec_size,
"# vector length");
2145 this->
get_mesh().local_nodes_begin(),
2146 this->
get_mesh().local_nodes_end(),
2154 this->
get_mesh().local_elements_begin(),
2155 this->
get_mesh().local_elements_end(),
2164 libmesh_assert_not_equal_to (vec, 0);
2170 return written_length;
2176 template LIBMESH_EXPORT
void System::read_parallel_data<Number> (
Xdr & io,
const bool read_additional_data);
2177 template LIBMESH_EXPORT
void System::read_serialized_data<Number> (
Xdr & io,
const bool read_additional_data);
2179 template LIBMESH_EXPORT std::size_t System::read_serialized_vectors<Number> (
Xdr & io,
const std::vector<NumericVector<Number> *> & vectors)
const;
2180 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 2181 template LIBMESH_EXPORT
void System::read_parallel_data<Real> (
Xdr & io,
const bool read_additional_data);
2182 template LIBMESH_EXPORT
void System::read_serialized_data<Real> (
Xdr & io,
const bool read_additional_data);
2184 template LIBMESH_EXPORT std::size_t System::read_serialized_vectors<Real> (
Xdr & io,
const std::vector<NumericVector<Number> *> & vectors)
const;
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Simple compatibility class for std::thread 'concurrent' execution.
FEFamily family
The type of finite element.
void write_serialized_data(Xdr &io, const bool write_additional_data=true) const
Writes additional data, namely vectors, for this System.
virtual void clear()
Clear all the data structures associated with the system.
Order
defines an enum for polynomial orders.
void write_parallel_data(Xdr &io, const bool write_additional_data) const
Writes additional data, namely vectors, for this System.
const Variable & variable(unsigned int var) const
Return a constant reference to Variable var.
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
void join()
Join is a no-op, since the constructor blocked until completion.
void write_header(Xdr &io, std::string_view version, const bool write_additional_data) const
Writes the basic data header for this System.
MessageTag get_unique_tag(int tagvalue=MessageTag::invalid_tag) const
void comment(std::string &)
Writes or reads (ignores) a comment line.
std::size_t read_serialized_blocked_dof_objects(const dof_id_type n_objects, const iterator_type begin, const iterator_type end, const InValType dummy, Xdr &io, const std::vector< NumericVector< Number > *> &vecs, const unsigned int var_to_read=libMesh::invalid_uint) const
Reads an input vector from the stream io and assigns the values to a set of DofObjects.
virtual numeric_index_type size() const =0
OrderWrapper radial_order
The approximation order in radial direction of the infinite element.
unsigned int write_SCALAR_dofs(const NumericVector< Number > &vec, const unsigned int var, Xdr &io) const
Writes the SCALAR dofs associated with var to the stream io.
int version() const
Gets the version of the file that is being read.
const Parallel::Communicator & comm() const
std::map< std::string, std::unique_ptr< NumericVector< Number > >, std::less<> > _vectors
Some systems need an arbitrary number of vectors.
NumericVector< Number > & add_vector(std::string_view vec_name, const bool projections=true, const ParallelType type=PARALLEL)
Adds the additional vector vec_name to this system.
OrderWrapper order
The approximation order of the element (at 0 p-refinement level).
The libMesh namespace provides an interface to certain functionality in the library.
const MeshBase & get_mesh() const
uint8_t processor_id_type
void SCALAR_dof_indices(std::vector< dof_id_type > &di, const unsigned int vn, const bool old_dofs=false) const
Fills the vector di with the global degree of freedom indices corresponding to the SCALAR variable vn...
unsigned int variable_number(std::string_view var) const
Tnew cast_int(Told oldvar)
void data(T &a, std::string_view comment="")
Inputs or outputs a single value.
This class handles the numbering of degrees of freedom on a mesh.
processor_id_type n_processors() const
const dof_id_type n_nodes
unsigned int number() const
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
const std::set< subdomain_id_type > & active_subdomains() const
dof_id_type numeric_index_type
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
void read_header(Xdr &io, std::string_view version, const bool read_header=true, const bool read_additional_data=true, const bool read_legacy_format=false)
Reads the basic data header for this System.
unsigned int n_vectors() const
numeric_index_type read_serialized_vector(Xdr &io, NumericVector< Number > *vec)
Reads a vector for this System.
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
unsigned int _additional_data_written
This flag is used only when reading in a system from file.
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variable var to the list of variables for this system.
const std::string & variable_name(const unsigned int i) const
InfMapType inf_map
The coordinate mapping type of the infinite element.
bool contains(std::string_view superstring, std::string_view substring)
Look for a substring within a string.
std::size_t read_serialized_vectors(Xdr &io, const std::vector< NumericVector< Number > *> &vectors) const
Read a number of identically distributed vectors.
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
This class implements a C++ interface to the XDR (eXternal Data Representation) format.
FEFamily radial_family
The type of approximation in radial direction.
int get_order() const
Explicitly request the order as an int.
std::size_t write_serialized_vectors(Xdr &io, const std::vector< const NumericVector< Number > *> &vectors) const
Serialize & write a number of identically distributed vectors.
void read_parallel_data(Xdr &io, const bool read_additional_data)
Reads additional data, namely vectors, for this System.
ParallelType type() const
const FEType & variable_type(const unsigned int i) const
InfMapType
defines an enum for the types of coordinate mappings available in infinite elements.
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
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 DofObject defines an abstract base class for objects that have degrees of freedom associated with...
unsigned int mesh_dimension() const
unsigned int read_SCALAR_dofs(const unsigned int var, Xdr &io, NumericVector< Number > *vec) const
Reads the SCALAR dofs from the stream io and assigns the values to the appropriate entries of vec...
virtual void set(const numeric_index_type i, const T value)=0
Sets v(i) = value.
bool on_command_line(std::string arg)
const std::string & name() const
FEFamily
defines an enum for finite element families.
unsigned int n_vars() const
virtual dof_id_type n_elem() const =0
processor_id_type processor_id() const
void data_stream(T *val, const unsigned int len, const unsigned int line_break=libMesh::invalid_uint)
Inputs or outputs a raw data stream.
const DofMap & get_dof_map() const
void read_serialized_data(Xdr &io, const bool read_additional_data=true)
Reads additional data, namely vectors, for this System.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
std::map< std::string, bool, std::less<> > _vector_projections
Holds true if a vector by that name should be projected onto a changed grid, false if it should be ze...
virtual dof_id_type n_nodes() const =0
std::size_t write_serialized_blocked_dof_objects(const std::vector< const NumericVector< Number > *> &vecs, const dof_id_type n_objects, const iterator_type begin, const iterator_type end, Xdr &io, const unsigned int var_to_write=libMesh::invalid_uint) const
Writes an output vector to the stream io for a set of DofObjects.
std::vector< unsigned int > _written_var_indices
This vector is used only when reading in a system from file.
const FEType & type() const
ParallelType
Defines an enum for parallel data structure types.
dof_id_type write_serialized_vector(Xdr &io, const NumericVector< Number > &vec) const
Writes a vector for this System.