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 =
143 (version.rfind(
" with infinite elements") < version.size()) ||
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" 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 #ifdef LIBMESH_ENABLE_DEPRECATED 303 const bool read_additional_data)
305 libmesh_deprecated();
322 std::vector<Number> global_vector;
323 std::vector<Number> reordered_vector;
325 auto reorder_vector_into =
326 [
this, &global_vector, &reordered_vector]
334 reordered_vector.size() == global_vector.size());
339 reordered_vector.resize(global_vector.size());
344 libmesh_assert_equal_to (global_vector.size(), this->
n_dofs());
348 const unsigned int sys = this->
number();
349 const unsigned int nv = cast_int<unsigned int>
351 libmesh_assert_less_equal (nv, this->
n_vars());
353 for (
unsigned int data_var=0; data_var<nv; data_var++)
358 for (
auto & node : this->
get_mesh().node_ptr_range())
359 for (
auto index :
make_range(node->n_comp(sys,var)))
361 libmesh_assert_not_equal_to (node->dof_number(sys, var, index),
364 libmesh_assert_less (cnt, global_vector.size());
366 reordered_vector[node->dof_number(sys, var, index)] =
367 global_vector[cnt++];
371 for (
auto & elem : this->
get_mesh().active_element_ptr_range())
372 for (
auto index :
make_range(elem->n_comp(sys,var)))
374 libmesh_assert_not_equal_to (elem->dof_number(sys, var, index),
377 libmesh_assert_less (cnt, global_vector.size());
379 reordered_vector[elem->dof_number(sys, var, index)] =
380 global_vector[cnt++];
385 vec = reordered_vector;
391 io.
data (global_vector);
392 reorder_vector_into(*(this->
solution));
400 const std::size_t nvecs = this->
_vectors.size();
406 if (read_additional_data && nvecs &&
409 (
"Additional vectors in file do not match system");
420 std::fill (global_vector.begin(), global_vector.end(),
libMesh::zero);
423 io.
data (global_vector);
428 if (read_additional_data && nvecs)
430 std::fill (reordered_vector.begin(),
431 reordered_vector.end(),
434 reorder_vector_into(*(pos->second));
448 template <
typename InValType>
450 const bool read_additional_data)
486 std::vector<const DofObject *> ordered_nodes, ordered_elements;
488 std::set<const DofObject *, CompareDofObjectsByID>
489 ordered_nodes_set (this->
get_mesh().local_nodes_begin(),
490 this->
get_mesh().local_nodes_end());
492 ordered_nodes.insert(ordered_nodes.end(),
493 ordered_nodes_set.begin(),
494 ordered_nodes_set.end());
497 std::set<const DofObject *, CompareDofObjectsByID>
498 ordered_elements_set (this->
get_mesh().local_elements_begin(),
499 this->
get_mesh().local_elements_end());
501 ordered_elements.insert(ordered_elements.end(),
502 ordered_elements_set.begin(),
503 ordered_elements_set.end());
507 std::vector<InValType> io_buffer;
515 total_read_size += cast_int<dof_id_type>(io_buffer.size());
517 const unsigned int sys_num = this->
number();
518 const unsigned int nv = cast_int<unsigned int>
520 libmesh_assert_less_equal (nv, this->
n_vars());
525 for (
unsigned int data_var=0; data_var<nv; data_var++)
531 for (
const auto & node : ordered_nodes)
532 for (
auto comp :
make_range(node->n_comp(sys_num,var)))
534 libmesh_assert_not_equal_to (node->dof_number(sys_num, var, comp),
536 libmesh_assert_less (cnt, io_buffer.size());
537 this->
solution->set(node->dof_number(sys_num, var, comp), io_buffer[cnt++]);
541 for (
const auto & elem : ordered_elements)
542 for (
auto comp :
make_range(elem->n_comp(sys_num,var)))
544 libmesh_assert_not_equal_to (elem->dof_number(sys_num, var, comp),
546 libmesh_assert_less (cnt, io_buffer.size());
547 this->
solution->set(elem->dof_number(sys_num, var, comp), io_buffer[cnt++]);
553 for (
unsigned int data_var=0; data_var<nv; data_var++)
561 std::vector<dof_id_type> SCALAR_dofs;
564 for (
auto dof : SCALAR_dofs)
565 this->
solution->set(dof, io_buffer[cnt++]);
579 const std::size_t nvecs = this->
_vectors.size();
585 if (read_additional_data && nvecs &&
588 (
"Additional vectors in file do not match system");
603 total_read_size += cast_int<dof_id_type>(io_buffer.size());
608 if (read_additional_data && nvecs)
611 for (
unsigned int data_var=0; data_var<nv; data_var++)
617 for (
const auto & node : ordered_nodes)
618 for (
auto comp :
make_range(node->n_comp(sys_num,var)))
620 libmesh_assert_not_equal_to (node->dof_number(sys_num, var, comp),
622 libmesh_assert_less (cnt, io_buffer.size());
623 pos->second->set(node->dof_number(sys_num, var, comp), io_buffer[cnt++]);
627 for (
const auto & elem : ordered_elements)
628 for (
auto comp :
make_range(elem->n_comp(sys_num,var)))
630 libmesh_assert_not_equal_to (elem->dof_number(sys_num, var, comp),
632 libmesh_assert_less (cnt, io_buffer.size());
633 pos->second->set(elem->dof_number(sys_num, var, comp), io_buffer[cnt++]);
639 for (
unsigned int data_var=0; data_var<nv; data_var++)
647 std::vector<dof_id_type> SCALAR_dofs;
650 for (
auto dof : SCALAR_dofs)
651 pos->second->set(dof, io_buffer[cnt++]);
657 pos->second->close();
679 template <
typename InValType>
681 const bool read_additional_data)
694 parallel_object_only();
705 this->read_serialized_vector<InValType>(io, this->
solution.get());
709 io.comment (comment);
717 const std::size_t nvecs = this->
_vectors.size();
723 if (read_additional_data && nvecs &&
726 (
"Additional vectors in file do not match system");
736 this->read_serialized_vector<InValType>
737 (io, (read_additional_data && nvecs) ? pos->second.get() :
nullptr);
741 io.comment (comment);
764 template <
typename iterator_type,
typename InValType>
766 const iterator_type begin,
767 const iterator_type end,
771 const unsigned int var_to_read)
const 793 vars_to_read.clear();
794 vars_to_read.push_back(var_to_read);
799 num_vecs = cast_int<unsigned int>(vecs.size());
801 io_blksize = cast_int<dof_id_type>(std::min(max_io_blksize, static_cast<std::size_t>(n_objs))),
802 num_blks = cast_int<unsigned int>(std::ceil(static_cast<double>(n_objs)/
803 static_cast<double>(io_blksize)));
807 std::size_t n_read_values=0;
809 std::vector<std::vector<dof_id_type>> xfer_ids(num_blks);
810 std::vector<std::vector<Number>> recv_vals(num_blks);
811 std::vector<Parallel::Request>
812 id_requests(num_blks), val_requests(num_blks);
813 std::vector<Parallel::MessageTag>
814 id_tags(num_blks), val_tags(num_blks);
820 std::vector<std::size_t>
821 xfer_ids_size (num_blks,0),
822 recv_vals_size (num_blks,0);
825 for (iterator_type it=begin; it!=end; ++it)
829 block =
id/io_blksize;
831 libmesh_assert_less (block, num_blks);
833 xfer_ids_size[block] += 2;
836 for (
const auto & var : vars_to_read)
837 n_comp_tot += (*it)->n_comp(sys_num, var);
839 recv_vals_size[block] += n_comp_tot*num_vecs;
844 std::vector<std::size_t> tot_vals_size(recv_vals_size);
845 this->
comm().
sum (tot_vals_size);
857 first_object = blk*io_blksize,
858 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs);
861 std::vector<dof_id_type> & ids (xfer_ids[blk]);
862 std::vector<Number> & vals (recv_vals[blk]);
866 ids.clear(); ids.reserve (xfer_ids_size[blk]);
867 vals.resize(recv_vals_size[blk]);
870 std::unordered_set<dof_id_type> seen_ids;
873 if (recv_vals_size[blk] != 0)
874 for (iterator_type it=begin; it!=end; ++it)
884 if ((
id >= first_object) &&
889 unsigned int n_comp_tot=0;
891 for (
const auto & var : vars_to_read)
892 n_comp_tot += (*it)->n_comp(sys_num, var);
894 ids.push_back (n_comp_tot*num_vecs);
898 #ifdef LIBMESH_HAVE_MPI 903 this->
comm().
send (0, ids, id_requests[blk], id_tags[blk]);
906 this->
comm().
receive (0, vals, val_requests[blk], val_tags[blk]);
916 std::vector<std::vector<dof_id_type>> recv_ids (this->
n_processors());
917 std::vector<std::vector<Number>> send_vals (this->
n_processors());
918 std::vector<Parallel::Request> reply_requests (this->
n_processors());
919 std::vector<unsigned int> obj_val_offsets;
920 std::vector<Number> input_vals;
921 std::vector<InValType> input_vals_tmp;
928 first_object = blk*io_blksize,
929 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs),
930 n_objects_blk = last_object - first_object;
938 input_vals.resize(tot_vals_size[blk]);
939 input_vals_tmp.resize(tot_vals_size[blk]);
942 ThreadedIO<InValType> threaded_io(io, input_vals_tmp);
948 obj_val_offsets.resize (n_objects_blk); std::fill (obj_val_offsets.begin(), obj_val_offsets.end(), 0);
952 std::size_t n_vals_blk = 0;
958 #ifdef LIBMESH_HAVE_MPI 961 std::vector<dof_id_type> & ids (recv_ids[id_status.
source()]);
962 std::size_t & n_vals_proc (recv_vals_size[id_status.
source()]);
966 std::vector<dof_id_type> & ids (recv_ids[0]);
967 std::size_t & n_vals_proc (recv_vals_size[0]);
975 for (std::size_t
idx=0, sz=ids.size();
idx<sz;
idx+=2)
978 local_idx = ids[
idx+0]-first_object,
979 n_vals_tot_allvecs = ids[
idx+1];
981 libmesh_assert_less (local_idx, n_objects_blk);
983 obj_val_offsets[local_idx] = n_vals_tot_allvecs;
984 n_vals_proc += n_vals_tot_allvecs;
988 n_vals_blk += n_vals_proc;
995 std::partial_sum(obj_val_offsets.begin(), obj_val_offsets.end(),
996 obj_val_offsets.begin());
998 libmesh_assert_equal_to (n_vals_blk, obj_val_offsets.back());
999 libmesh_assert_equal_to (n_vals_blk, tot_vals_size[blk]);
1005 input_vals[i_val] = input_vals_tmp[i_val];
1007 n_read_values += input_vals.size();
1012 const std::vector<dof_id_type> & ids (recv_ids[proc]);
1013 std::vector<Number> & vals (send_vals[proc]);
1014 const std::size_t & n_vals_proc (recv_vals_size[proc]);
1016 vals.clear(); vals.reserve(n_vals_proc);
1018 for (std::size_t
idx=0, sz=ids.size();
idx<sz;
idx+=2)
1021 local_idx = ids[
idx+0]-first_object,
1022 n_vals_tot_allvecs = ids[
idx+1];
1024 std::vector<Number>::const_iterator in_vals(input_vals.begin());
1026 std::advance (in_vals, obj_val_offsets[local_idx-1]);
1028 for (
unsigned int val=0; val<n_vals_tot_allvecs; val++, ++in_vals)
1032 vals.push_back(*in_vals);
1036 #ifdef LIBMESH_HAVE_MPI 1038 this->
comm().
send (proc, vals, reply_requests[proc], val_tags[blk]);
1040 recv_vals[blk] = vals;
1047 Parallel::wait (val_requests[blk]);
1049 const std::vector<Number> & vals (recv_vals[blk]);
1050 std::vector<Number>::const_iterator val_it(vals.begin());
1052 if (!recv_vals[blk].empty())
1053 for (iterator_type it=begin; it!=end; ++it)
1054 if (((*it)->id() >= first_object) &&
1055 ((*it)->id() < last_object))
1057 for (
auto & vec : vecs)
1058 for (
const auto & var : vars_to_read)
1060 const unsigned int n_comp = (*it)->n_comp(sys_num, var);
1062 for (
unsigned int comp=0; comp<n_comp; comp++, ++val_it)
1064 const dof_id_type dof_index = (*it)->dof_number (sys_num, var, comp);
1068 libmesh_assert_greater_equal (dof_index, vec->first_local_index());
1069 libmesh_assert_less (dof_index, vec->last_local_index());
1071 vec->set (dof_index, *val_it);
1079 Parallel::wait(reply_requests);
1082 Parallel::wait(id_requests);
1084 return n_read_values;
1093 unsigned int n_assigned_vals = 0;
1097 std::vector<Number> input_buffer(n_SCALAR_dofs);
1099 io.
data_stream(input_buffer.data(), n_SCALAR_dofs);
1101 #ifdef LIBMESH_HAVE_MPI 1120 std::vector<dof_id_type> SCALAR_dofs;
1126 vec->
set (SCALAR_dofs[i], input_buffer[i]);
1131 return n_assigned_vals;
1135 template <
typename InValType>
1139 parallel_object_only();
1154 unsigned int vector_length=0;
1156 std::size_t n_assigned_vals=0;
1161 io.
data(vector_length,
"# vector length");
1164 const unsigned int nv = cast_int<unsigned int>
1170 libmesh_assert_less_equal (nv, this->
n_vars());
1173 if (io.
version() >= LIBMESH_VERSION_ID(0,7,4))
1181 this->
get_mesh().local_nodes_begin(),
1182 this->
get_mesh().local_nodes_end(),
1194 this->
get_mesh().local_elements_begin(),
1195 this->
get_mesh().local_elements_end(),
1205 for (
unsigned int data_var=0; data_var<nv; data_var++)
1216 this->
get_mesh().local_nodes_begin(),
1217 this->
get_mesh().local_nodes_end(),
1230 this->
get_mesh().local_elements_begin(),
1231 this->
get_mesh().local_elements_end(),
1242 for (
unsigned int data_var=0; data_var<nv; data_var++)
1258 this->
comm().
sum (n_assigned_vals);
1259 libmesh_assert_equal_to (n_assigned_vals, vector_length);
1262 return vector_length;
1269 const bool write_additional_data)
const 1312 std::string comment;
1319 comment =
"# No. of Variables in System \"";
1320 comment += this->
name();
1323 unsigned int nv = this->
n_vars();
1324 io.
data (nv, comment);
1334 comment =
"# Name, Variable No. ";
1335 comment += std::to_string(var);
1336 comment +=
", System \"";
1337 comment += this->
name();
1341 io.
data (var_name, comment);
1347 comment =
"# Subdomains, Variable \"";
1349 comment +=
"\", System \"";
1350 comment += this->
name();
1354 std::vector<subdomain_id_type> domain_array;
1355 domain_array.assign(domains.begin(), domains.end());
1356 io.
data (domain_array, comment);
1364 comment =
"# Approximation Order, Variable \"";
1366 comment +=
"\", System \"";
1367 comment += this->
name();
1371 io.
data (order, comment);
1375 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 1379 comment =
"# Radial Approximation Order, Variable \"";
1381 comment +=
"\", System \"";
1382 comment += this->
name();
1386 io.
data (rad_order, comment);
1395 comment =
"# FE Family, Variable \"";
1397 comment +=
"\", System \"";
1398 comment += this->
name();
1402 int fam =
static_cast<int>(type.
family);
1403 io.
data (fam, comment);
1405 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 1407 comment =
"# Radial FE Family, Variable \"";
1409 comment +=
"\", System \"";
1410 comment += this->
name();
1414 io.
data (radial_fam, comment);
1416 comment =
"# Infinite Mapping Type, Variable \"";
1418 comment +=
"\", System \"";
1419 comment += this->
name();
1422 int i_map =
static_cast<int>(type.
inf_map);
1423 io.
data (i_map, comment);
1435 comment =
"# No. of Additional Vectors, System \"";
1436 comment += this->
name();
1439 unsigned int nvecs = write_additional_data ? this->
n_vectors () : 0;
1440 io.
data (nvecs, comment);
1443 if (write_additional_data)
1446 for (
const auto & [vec_name, vec] :
_vectors)
1450 const std::string dth_vector = std::to_string(cnt++)+
"th vector";
1451 comment =
"# Name of " + dth_vector;
1452 std::string nonconst_vec_name = vec_name;
1454 io.
data (nonconst_vec_name, comment);
1456 comment =
"# Whether to do projections for " + dth_vector;
1457 io.
data (vec_projection, comment);
1458 int vec_type = vec->type();
1459 comment =
"# Parallel type of " + dth_vector;
1460 io.
data (vec_type, comment);
1469 const bool write_additional_data)
const 1494 std::string comment;
1498 std::vector<Number> io_buffer; io_buffer.reserve(this->
solution->local_size());
1508 std::vector<const DofObject *> ordered_nodes, ordered_elements;
1510 std::set<const DofObject *, CompareDofObjectsByID>
1511 ordered_nodes_set (this->
get_mesh().local_nodes_begin(),
1512 this->
get_mesh().local_nodes_end());
1514 ordered_nodes.insert(ordered_nodes.end(),
1515 ordered_nodes_set.begin(),
1516 ordered_nodes_set.end());
1519 std::set<const DofObject *, CompareDofObjectsByID>
1520 ordered_elements_set (this->
get_mesh().local_elements_begin(),
1521 this->
get_mesh().local_elements_end());
1523 ordered_elements.insert(ordered_elements.end(),
1524 ordered_elements_set.begin(),
1525 ordered_elements_set.end());
1528 const unsigned int sys_num = this->
number();
1529 const unsigned int nv = this->
n_vars();
1532 for (
unsigned int var=0; var<nv; var++)
1536 for (
const auto & node : ordered_nodes)
1537 for (
auto comp :
make_range(node->n_comp(sys_num,var)))
1539 libmesh_assert_not_equal_to (node->dof_number(sys_num, var, comp),
1542 io_buffer.push_back((*this->
solution)(node->dof_number(sys_num, var, comp)));
1546 for (
const auto & elem : ordered_elements)
1547 for (
auto comp :
make_range(elem->n_comp(sys_num,var)))
1549 libmesh_assert_not_equal_to (elem->dof_number(sys_num, var, comp),
1552 io_buffer.push_back((*this->
solution)(elem->dof_number(sys_num, var, comp)));
1563 std::vector<dof_id_type> SCALAR_dofs;
1566 for (
auto dof : SCALAR_dofs)
1567 io_buffer.push_back((*this->
solution)(dof));
1578 comment =
"# System \"";
1579 comment += this->
name();
1580 comment +=
"\" Solution Vector";
1583 io.
data (io_buffer, comment);
1588 if (write_additional_data)
1590 for (
auto & [vec_name, vec] :
_vectors)
1593 io_buffer.reserve(vec->local_size());
1596 for (
unsigned int var=0; var<nv; var++)
1600 for (
const auto & node : ordered_nodes)
1601 for (
auto comp :
make_range(node->n_comp(sys_num,var)))
1603 libmesh_assert_not_equal_to (node->dof_number(sys_num, var, comp),
1606 io_buffer.push_back((*vec)(node->dof_number(sys_num, var, comp)));
1610 for (
const auto & elem : ordered_elements)
1611 for (
auto comp :
make_range(elem->n_comp(sys_num,var)))
1613 libmesh_assert_not_equal_to (elem->dof_number(sys_num, var, comp),
1616 io_buffer.push_back((*vec)(elem->dof_number(sys_num, var, comp)));
1627 std::vector<dof_id_type> SCALAR_dofs;
1630 for (
auto dof : SCALAR_dofs)
1631 io_buffer.push_back((*vec)(dof));
1642 comment =
"# System \"";
1643 comment += this->
name();
1644 comment +=
"\" Additional Vector \"";
1645 comment += vec_name;
1649 io.
data (io_buffer, comment);
1669 const bool write_additional_data)
const 1684 parallel_object_only();
1685 std::string comment;
1697 comment =
"# System \"";
1698 comment += this->
name();
1699 comment +=
"\" Solution Vector";
1705 if (write_additional_data)
1715 comment =
"# System \"";
1716 comment += this->
name();
1717 comment +=
"\" Additional Vector \"";
1718 comment += pair.first;
1775 template <
typename iterator_type>
1778 const iterator_type begin,
1779 const iterator_type end,
1781 const unsigned int var_to_write)
const 1783 parallel_object_only();
1801 std::vector<unsigned int> vars_to_write(1, var_to_write);
1805 vars_to_write.clear(); vars_to_write.reserve(this->
n_vars());
1807 vars_to_write.push_back(var);
1810 const dof_id_type io_blksize = cast_int<dof_id_type>
1811 (std::min(max_io_blksize, static_cast<std::size_t>(n_objs)));
1814 sys_num = this->
number(),
1815 num_vecs = cast_int<unsigned int>(vecs.size()),
1816 num_blks = cast_int<unsigned int>(std::ceil(static_cast<double>(n_objs)/
1817 static_cast<double>(io_blksize)));
1824 std::size_t written_length=0;
1825 std::vector<std::vector<dof_id_type>> xfer_ids(num_blks);
1826 std::vector<std::vector<Number>> send_vals(num_blks);
1827 std::vector<Parallel::Request>
1828 id_requests(num_blks), val_requests(num_blks);
1829 std::vector<Parallel::MessageTag>
1830 id_tags(num_blks), val_tags(num_blks);
1836 std::vector<unsigned int>
1837 xfer_ids_size (num_blks,0),
1838 send_vals_size (num_blks,0);
1840 for (iterator_type it=begin; it!=end; ++it)
1844 block =
id/io_blksize;
1846 libmesh_assert_less (block, num_blks);
1848 xfer_ids_size[block] += 2;
1850 unsigned int n_comp_tot=0;
1852 for (
const auto & var : vars_to_write)
1853 n_comp_tot += (*it)->n_comp(sys_num, var);
1855 send_vals_size[block] += n_comp_tot*num_vecs;
1862 for (
unsigned int blk=0; blk<num_blks; blk++)
1869 first_object = blk*io_blksize,
1870 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs);
1873 std::vector<dof_id_type> & ids (xfer_ids[blk]);
1874 std::vector<Number> & vals (send_vals[blk]);
1878 ids.clear(); ids.reserve (xfer_ids_size[blk]);
1879 vals.clear(); vals.reserve (send_vals_size[blk]);
1881 if (send_vals_size[blk] != 0)
1882 for (iterator_type it=begin; it!=end; ++it)
1883 if (((*it)->id() >= first_object) &&
1884 ((*it)->id() < last_object))
1886 ids.push_back((*it)->id());
1890 unsigned int n_comp_tot=0;
1892 for (
const auto & var : vars_to_write)
1893 n_comp_tot += (*it)->n_comp(sys_num, var);
1895 ids.push_back (n_comp_tot*num_vecs);
1899 for (
const auto & vec : vecs)
1900 for (
const auto & var : vars_to_write)
1902 const unsigned int n_comp = (*it)->n_comp(sys_num, var);
1904 for (
unsigned int comp=0; comp<n_comp; comp++)
1906 libmesh_assert_greater_equal ((*it)->dof_number(sys_num, var, comp), vec->first_local_index());
1907 libmesh_assert_less ((*it)->dof_number(sys_num, var, comp), vec->last_local_index());
1908 vals.push_back((*vec)((*it)->dof_number(sys_num, var, comp)));
1913 #ifdef LIBMESH_HAVE_MPI 1918 this->
comm().
send (0, ids, id_requests[blk], id_tags[blk]);
1919 this->
comm().
send (0, vals, val_requests[blk], val_tags[blk]);
1926 std::vector<std::vector<dof_id_type>> recv_ids (this->
n_processors());
1927 std::vector<std::vector<Number>> recv_vals (this->
n_processors());
1928 std::vector<unsigned int> obj_val_offsets;
1929 std::vector<Number> output_vals;
1932 ThreadedIO<Number> threaded_io(io, output_vals);
1933 std::unique_ptr<Threads::Thread> async_io;
1935 for (
unsigned int blk=0; blk<num_blks; blk++)
1940 first_object = cast_int<dof_id_type>(blk*io_blksize),
1941 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs),
1942 n_objects_blk = last_object - first_object;
1947 obj_val_offsets.resize (n_objects_blk); std::fill (obj_val_offsets.begin(), obj_val_offsets.end(), 0);
1949 std::size_t n_val_recvd_blk=0;
1954 #ifdef LIBMESH_HAVE_MPI 1957 std::vector<dof_id_type> & ids (recv_ids[id_status.
source()]);
1960 std::vector<dof_id_type> & ids (recv_ids[0]);
1961 ids = xfer_ids[blk];
1966 for (std::size_t
idx=0, sz=ids.size();
idx<sz;
idx+=2)
1969 local_idx = ids[
idx+0]-first_object,
1970 n_vals_tot_allvecs = ids[
idx+1];
1972 libmesh_assert_less (local_idx, n_objects_blk);
1973 libmesh_assert_less (local_idx, obj_val_offsets.size());
1975 obj_val_offsets[local_idx] = n_vals_tot_allvecs;
1978 #ifdef LIBMESH_HAVE_MPI 1981 std::vector<Number> & vals (recv_vals[val_status.
source()]);
1985 std::vector<Number> & vals (recv_vals[0]);
1986 vals = send_vals[blk];
1989 n_val_recvd_blk += vals.size();
1995 std::partial_sum(obj_val_offsets.begin(), obj_val_offsets.end(),
1996 obj_val_offsets.begin());
2000 if (async_io.get()) async_io->join();
2004 output_vals.resize(n_val_recvd_blk);
2009 const std::vector<dof_id_type> & ids (recv_ids [proc]);
2010 const std::vector<Number> & vals(recv_vals[proc]);
2011 std::vector<Number>::const_iterator proc_vals(vals.begin());
2013 for (std::size_t
idx=0, sz=ids.size();
idx<sz;
idx+=2)
2016 local_idx = ids[
idx+0]-first_object,
2017 n_vals_tot_allvecs = ids[
idx+1];
2021 std::vector<Number>::iterator out_vals(output_vals.begin());
2023 std::advance (out_vals, obj_val_offsets[local_idx-1]);
2025 for (
unsigned int val=0; val<n_vals_tot_allvecs; val++, ++out_vals, ++proc_vals)
2029 *out_vals = *proc_vals;
2036 async_io = std::make_unique<Threads::Thread>(threaded_io);
2037 written_length += output_vals.size();
2045 Parallel::wait(id_requests);
2046 Parallel::wait(val_requests);
2057 return written_length;
2063 const unsigned int var,
2066 unsigned int written_length=0;
2067 std::vector<Number> vals;
2072 std::vector<dof_id_type> SCALAR_dofs;
2074 const unsigned int n_scalar_dofs = cast_int<unsigned int>
2075 (SCALAR_dofs.size());
2077 for (
unsigned int i=0; i<n_scalar_dofs; i++)
2079 vals.push_back( vec(SCALAR_dofs[i]) );
2083 #ifdef LIBMESH_HAVE_MPI 2098 this->
comm().
send(0, vals, val_tag);
2107 const unsigned int vals_size =
2108 cast_int<unsigned int>(vals.size());
2110 written_length += vals_size;
2113 return written_length;
2121 parallel_object_only();
2132 written_length += cast_int<dof_id_type>
2135 this->
get_mesh().local_nodes_begin(),
2136 this->
get_mesh().local_nodes_end(),
2141 written_length += cast_int<dof_id_type>
2144 this->
get_mesh().local_elements_begin(),
2145 this->
get_mesh().local_elements_end(),
2158 libmesh_assert_equal_to (written_length, vec_length);
2160 return written_length;
2164 template <
typename InValType>
2168 parallel_object_only();
2186 unsigned int num_vecs=0;
2192 io.
data(vector_length);
2194 libmesh_error_msg_if
2195 (num_vecs != vectors.size(),
2196 "Xdr file header declares " << num_vecs <<
" vectors, but we were asked to read " << vectors.size());
2200 libmesh_error_msg_if (vectors[0] ==
nullptr,
"vectors[0] should not be null");
2201 libmesh_error_msg_if (vectors[0]->size() != vector_length,
"Inconsistent vector sizes");
2214 std::size_t read_length = 0;
2220 this->
get_mesh().local_nodes_begin(),
2221 this->
get_mesh().local_nodes_end(),
2230 this->
get_mesh().local_elements_begin(),
2231 this->
get_mesh().local_elements_end(),
2242 libmesh_assert_not_equal_to (vec, 0);
2252 libmesh_assert_not_equal_to (vec, 0);
2264 parallel_object_only();
2273 std::size_t written_length = 0;
2278 n_vec = cast_int<unsigned int>(vectors.size());
2280 vec_size = vectors.empty() ? 0 : vectors[0]->size();
2282 io.
data(n_vec,
"# number of vectors");
2284 io.
data(vec_size,
"# vector length");
2292 this->
get_mesh().local_nodes_begin(),
2293 this->
get_mesh().local_nodes_end(),
2301 this->
get_mesh().local_elements_begin(),
2302 this->
get_mesh().local_elements_end(),
2311 libmesh_assert_not_equal_to (vec, 0);
2317 return written_length;
2323 template LIBMESH_EXPORT
void System::read_parallel_data<Number> (
Xdr & io,
const bool read_additional_data);
2324 template LIBMESH_EXPORT
void System::read_serialized_data<Number> (
Xdr & io,
const bool read_additional_data);
2326 template LIBMESH_EXPORT std::size_t System::read_serialized_vectors<Number> (
Xdr & io,
const std::vector<NumericVector<Number> *> & vectors)
const;
2327 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 2328 template LIBMESH_EXPORT
void System::read_parallel_data<Real> (
Xdr & io,
const bool read_additional_data);
2329 template LIBMESH_EXPORT
void System::read_serialized_data<Real> (
Xdr & io,
const bool read_additional_data);
2331 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.
void read_legacy_data(Xdr &io, const bool read_additional_data=true)
Reads additional data, namely vectors, for this System.
The libMesh namespace provides an interface to certain functionality in the library.
const MeshBase & get_mesh() const
dof_id_type n_dofs() 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
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.
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
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.
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.