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"
64const std::size_t max_io_blksize = 256000;
69template <
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)
301template <
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();
532template <
typename InValType>
534 const bool read_additional_data)
547 parallel_object_only();
558 this->read_serialized_vector<InValType>(io, this->
solution.get());
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);
617template <
typename iterator_type,
typename InValType>
619 const iterator_type begin,
620 const iterator_type end,
624 const unsigned int var_to_read)
const
645 vars_to_read.assign({var_to_read});
649 num_vecs = cast_int<unsigned int>(vecs.size());
651 io_blksize = cast_int<dof_id_type>(std::min(max_io_blksize,
static_cast<std::size_t
>(n_objs))),
652 num_blks = cast_int<unsigned int>(std::ceil(
static_cast<double>(n_objs)/
653 static_cast<double>(io_blksize)));
657 std::size_t n_read_values=0;
659 std::vector<std::vector<dof_id_type>> xfer_ids(num_blks);
660 std::vector<std::vector<Number>> recv_vals(num_blks);
661 std::vector<Parallel::Request>
662 id_requests(num_blks), val_requests(num_blks);
663 std::vector<Parallel::MessageTag>
664 id_tags(num_blks), val_tags(num_blks);
670 std::vector<std::size_t>
671 xfer_ids_size (num_blks,0),
672 recv_vals_size (num_blks,0);
675 for (iterator_type it=begin; it!=end; ++it)
679 block =
id/io_blksize;
681 libmesh_assert_less (block, num_blks);
683 xfer_ids_size[block] += 2;
686 for (
const auto & var : vars_to_read)
687 n_comp_tot += (*it)->n_comp(sys_num, var);
689 recv_vals_size[block] += n_comp_tot*num_vecs;
694 std::vector<std::size_t> tot_vals_size(recv_vals_size);
695 this->
comm().
sum (tot_vals_size);
707 first_object = blk*io_blksize,
708 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs);
711 std::vector<dof_id_type> & ids (xfer_ids[blk]);
712 std::vector<Number> & vals (recv_vals[blk]);
716 ids.clear(); ids.reserve (xfer_ids_size[blk]);
717 vals.resize(recv_vals_size[blk]);
720 std::unordered_set<dof_id_type> seen_ids;
723 if (recv_vals_size[blk] != 0)
724 for (iterator_type it=begin; it!=end; ++it)
734 if ((
id >= first_object) &&
739 unsigned int n_comp_tot=0;
741 for (
const auto & var : vars_to_read)
742 n_comp_tot += (*it)->n_comp(sys_num, var);
744 ids.push_back (n_comp_tot*num_vecs);
748#ifdef LIBMESH_HAVE_MPI
753 this->
comm().
send (0, ids, id_requests[blk], id_tags[blk]);
756 this->
comm().
receive (0, vals, val_requests[blk], val_tags[blk]);
766 std::vector<std::vector<dof_id_type>> recv_ids (this->
n_processors());
767 std::vector<std::vector<Number>> send_vals (this->
n_processors());
768 std::vector<Parallel::Request> reply_requests (this->
n_processors());
769 std::vector<unsigned int> obj_val_offsets;
770 std::vector<Number> input_vals;
771 std::vector<InValType> input_vals_tmp;
778 first_object = blk*io_blksize,
779 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs),
780 n_objects_blk = last_object - first_object;
788 input_vals.resize(tot_vals_size[blk]);
789 input_vals_tmp.resize(tot_vals_size[blk]);
792 ThreadedIO<InValType> threaded_io(io, input_vals_tmp);
798 obj_val_offsets.resize (n_objects_blk); std::fill (obj_val_offsets.begin(), obj_val_offsets.end(), 0);
802 std::size_t n_vals_blk = 0;
808#ifdef LIBMESH_HAVE_MPI
811 std::vector<dof_id_type> & ids (recv_ids[id_status.
source()]);
812 std::size_t & n_vals_proc (recv_vals_size[id_status.
source()]);
816 std::vector<dof_id_type> & ids (recv_ids[0]);
817 std::size_t & n_vals_proc (recv_vals_size[0]);
825 for (std::size_t idx=0, sz=ids.size(); idx<sz; idx+=2)
828 local_idx = ids[idx+0]-first_object,
829 n_vals_tot_allvecs = ids[idx+1];
831 libmesh_assert_less (local_idx, n_objects_blk);
833 obj_val_offsets[local_idx] = n_vals_tot_allvecs;
834 n_vals_proc += n_vals_tot_allvecs;
838 n_vals_blk += n_vals_proc;
845 std::partial_sum(obj_val_offsets.begin(), obj_val_offsets.end(),
846 obj_val_offsets.begin());
848 libmesh_assert_equal_to (n_vals_blk, obj_val_offsets.back());
849 libmesh_assert_equal_to (n_vals_blk, tot_vals_size[blk]);
855 input_vals[i_val] = input_vals_tmp[i_val];
857 n_read_values += input_vals.size();
862 const std::vector<dof_id_type> & ids (recv_ids[proc]);
863 std::vector<Number> & vals (send_vals[proc]);
864 const std::size_t & n_vals_proc (recv_vals_size[proc]);
866 vals.clear(); vals.reserve(n_vals_proc);
868 for (std::size_t idx=0, sz=ids.size(); idx<sz; idx+=2)
871 local_idx = ids[idx+0]-first_object,
872 n_vals_tot_allvecs = ids[idx+1];
874 std::vector<Number>::const_iterator in_vals(input_vals.begin());
876 std::advance (in_vals, obj_val_offsets[local_idx-1]);
878 for (
unsigned int val=0; val<n_vals_tot_allvecs; val++, ++in_vals)
882 vals.push_back(*in_vals);
886#ifdef LIBMESH_HAVE_MPI
888 this->
comm().
send (proc, vals, reply_requests[proc], val_tags[blk]);
890 recv_vals[blk] = vals;
899 const std::vector<Number> & vals (recv_vals[blk]);
900 std::vector<Number>::const_iterator val_it(vals.begin());
902 if (!recv_vals[blk].empty())
903 for (iterator_type it=begin; it!=end; ++it)
904 if (((*it)->id() >= first_object) &&
905 ((*it)->id() < last_object))
907 for (
auto & vec : vecs)
908 for (
const auto & var : vars_to_read)
910 const unsigned int n_comp = (*it)->n_comp(sys_num, var);
912 for (
unsigned int comp=0; comp<n_comp; comp++, ++val_it)
914 const dof_id_type dof_index = (*it)->dof_number (sys_num, var, comp);
918 libmesh_assert_greater_equal (dof_index, vec->first_local_index());
919 libmesh_assert_less (dof_index, vec->last_local_index());
921 vec->set (dof_index, *val_it);
934 return n_read_values;
943 unsigned int n_assigned_vals = 0;
947 std::vector<Number> input_buffer(n_SCALAR_dofs);
949 io.
data_stream(input_buffer.data(), n_SCALAR_dofs);
951#ifdef LIBMESH_HAVE_MPI
970 std::vector<dof_id_type> SCALAR_dofs;
976 vec->
set (SCALAR_dofs[i], input_buffer[i]);
981 return n_assigned_vals;
985template <
typename InValType>
989 parallel_object_only();
1004 unsigned int vector_length=0;
1006 std::size_t n_assigned_vals=0;
1011 io.
data(vector_length,
"# vector length");
1014 const unsigned int nv = cast_int<unsigned int>
1020 libmesh_assert_less_equal (nv, this->
n_vars());
1023 if (io.
version() >= LIBMESH_VERSION_ID(0,7,4))
1031 this->
get_mesh().local_nodes_begin(),
1032 this->
get_mesh().local_nodes_end(),
1044 this->
get_mesh().local_elements_begin(),
1045 this->
get_mesh().local_elements_end(),
1055 for (
unsigned int data_var=0; data_var<nv; data_var++)
1066 this->
get_mesh().local_nodes_begin(),
1067 this->
get_mesh().local_nodes_end(),
1080 this->
get_mesh().local_elements_begin(),
1081 this->
get_mesh().local_elements_end(),
1092 for (
unsigned int data_var=0; data_var<nv; data_var++)
1108 this->
comm().
sum (n_assigned_vals);
1109 libmesh_assert_equal_to (n_assigned_vals, vector_length);
1112 return vector_length;
1119 const bool write_additional_data)
const
1162 std::string comment;
1169 comment =
"# No. of Variables in System \"";
1170 comment += this->
name();
1173 unsigned int nv = this->
n_vars();
1174 io.
data (nv, comment);
1184 comment =
"# Name, Variable No. ";
1185 comment += std::to_string(var);
1186 comment +=
", System \"";
1187 comment += this->
name();
1191 io.
data (var_name, comment);
1197 comment =
"# Subdomains, Variable \"";
1199 comment +=
"\", System \"";
1200 comment += this->
name();
1204 std::vector<subdomain_id_type> domain_array;
1205 domain_array.assign(domains.begin(), domains.end());
1206 io.
data (domain_array, comment);
1214 comment =
"# Approximation Order, Variable \"";
1216 comment +=
"\", System \"";
1217 comment += this->
name();
1221 io.
data (order, comment);
1225#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1229 comment =
"# Radial Approximation Order, Variable \"";
1231 comment +=
"\", System \"";
1232 comment += this->
name();
1236 io.
data (rad_order, comment);
1245 comment =
"# FE Family, Variable \"";
1247 comment +=
"\", System \"";
1248 comment += this->
name();
1252 int fam =
static_cast<int>(type.
family);
1253 io.
data (fam, comment);
1255#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1257 comment =
"# Radial FE Family, Variable \"";
1259 comment +=
"\", System \"";
1260 comment += this->
name();
1264 io.
data (radial_fam, comment);
1266 comment =
"# Infinite Mapping Type, Variable \"";
1268 comment +=
"\", System \"";
1269 comment += this->
name();
1272 int i_map =
static_cast<int>(type.
inf_map);
1273 io.
data (i_map, comment);
1285 comment =
"# No. of Additional Vectors, System \"";
1286 comment += this->
name();
1289 unsigned int nvecs = write_additional_data ? this->
n_vectors () : 0;
1290 io.
data (nvecs, comment);
1293 if (write_additional_data)
1296 for (
const auto & [vec_name, vec] :
_vectors)
1300 const std::string dth_vector = std::to_string(cnt++)+
"th vector";
1301 comment =
"# Name of " + dth_vector;
1302 std::string nonconst_vec_name = vec_name;
1304 io.
data (nonconst_vec_name, comment);
1306 comment =
"# Whether to do projections for " + dth_vector;
1307 io.
data (vec_projection, comment);
1308 int vec_type = vec->type();
1309 comment =
"# Parallel type of " + dth_vector;
1310 io.
data (vec_type, comment);
1319 const bool write_additional_data)
const
1344 std::string comment;
1348 std::vector<Number> io_buffer; io_buffer.reserve(this->
solution->local_size());
1358 std::vector<const DofObject *> ordered_nodes, ordered_elements;
1360 std::set<const DofObject *, CompareDofObjectsByID>
1361 ordered_nodes_set (this->
get_mesh().local_nodes_begin(),
1362 this->
get_mesh().local_nodes_end());
1364 ordered_nodes.insert(ordered_nodes.end(),
1365 ordered_nodes_set.begin(),
1366 ordered_nodes_set.end());
1369 std::set<const DofObject *, CompareDofObjectsByID>
1370 ordered_elements_set (this->
get_mesh().local_elements_begin(),
1371 this->
get_mesh().local_elements_end());
1373 ordered_elements.insert(ordered_elements.end(),
1374 ordered_elements_set.begin(),
1375 ordered_elements_set.end());
1378 const unsigned int sys_num = this->
number();
1379 const unsigned int nv = this->
n_vars();
1382 for (
unsigned int var=0; var<nv; var++)
1386 for (
const auto & node : ordered_nodes)
1387 for (
auto comp :
make_range(node->n_comp(sys_num,var)))
1389 libmesh_assert_not_equal_to (node->dof_number(sys_num, var, comp),
1392 io_buffer.push_back((*this->
solution)(node->dof_number(sys_num, var, comp)));
1396 for (
const auto & elem : ordered_elements)
1397 for (
auto comp :
make_range(elem->n_comp(sys_num,var)))
1399 libmesh_assert_not_equal_to (elem->dof_number(sys_num, var, comp),
1402 io_buffer.push_back((*this->
solution)(elem->dof_number(sys_num, var, comp)));
1413 std::vector<dof_id_type> SCALAR_dofs;
1416 for (
auto dof : SCALAR_dofs)
1417 io_buffer.push_back((*this->solution)(dof));
1428 comment =
"# System \"";
1429 comment += this->
name();
1430 comment +=
"\" Solution Vector";
1433 io.
data (io_buffer, comment);
1438 if (write_additional_data)
1440 for (
auto & [vec_name, vec] :
_vectors)
1443 io_buffer.reserve(vec->local_size());
1446 for (
unsigned int var=0; var<nv; var++)
1450 for (
const auto & node : ordered_nodes)
1451 for (
auto comp :
make_range(node->n_comp(sys_num,var)))
1453 libmesh_assert_not_equal_to (node->dof_number(sys_num, var, comp),
1456 io_buffer.push_back((*vec)(node->dof_number(sys_num, var, comp)));
1460 for (
const auto & elem : ordered_elements)
1461 for (
auto comp :
make_range(elem->n_comp(sys_num,var)))
1463 libmesh_assert_not_equal_to (elem->dof_number(sys_num, var, comp),
1466 io_buffer.push_back((*vec)(elem->dof_number(sys_num, var, comp)));
1477 std::vector<dof_id_type> SCALAR_dofs;
1480 for (
auto dof : SCALAR_dofs)
1481 io_buffer.push_back((*vec)(dof));
1492 comment =
"# System \"";
1493 comment += this->
name();
1494 comment +=
"\" Additional Vector \"";
1495 comment += vec_name;
1499 io.
data (io_buffer, comment);
1519 const bool write_additional_data)
const
1534 parallel_object_only();
1535 std::string comment;
1547 comment =
"# System \"";
1548 comment += this->
name();
1549 comment +=
"\" Solution Vector";
1555 if (write_additional_data)
1565 comment =
"# System \"";
1566 comment += this->
name();
1567 comment +=
"\" Additional Vector \"";
1568 comment += pair.first;
1625template <
typename iterator_type>
1628 const iterator_type begin,
1629 const iterator_type end,
1631 const unsigned int var_to_write)
const
1633 parallel_object_only();
1651 std::vector<unsigned int> vars_to_write(1, var_to_write);
1655 vars_to_write.clear(); vars_to_write.reserve(this->
n_vars());
1657 vars_to_write.push_back(var);
1660 const dof_id_type io_blksize = cast_int<dof_id_type>
1661 (std::min(max_io_blksize,
static_cast<std::size_t
>(n_objs)));
1664 sys_num = this->
number(),
1665 num_vecs = cast_int<unsigned int>(vecs.size()),
1666 num_blks = cast_int<unsigned int>(std::ceil(
static_cast<double>(n_objs)/
1667 static_cast<double>(io_blksize)));
1674 std::size_t written_length=0;
1675 std::vector<std::vector<dof_id_type>> xfer_ids(num_blks);
1676 std::vector<std::vector<Number>> send_vals(num_blks);
1677 std::vector<Parallel::Request>
1678 id_requests(num_blks), val_requests(num_blks);
1679 std::vector<Parallel::MessageTag>
1680 id_tags(num_blks), val_tags(num_blks);
1686 std::vector<unsigned int>
1687 xfer_ids_size (num_blks,0),
1688 send_vals_size (num_blks,0);
1690 for (iterator_type it=begin; it!=end; ++it)
1694 block =
id/io_blksize;
1696 libmesh_assert_less (block, num_blks);
1698 xfer_ids_size[block] += 2;
1700 unsigned int n_comp_tot=0;
1702 for (
const auto & var : vars_to_write)
1703 n_comp_tot += (*it)->n_comp(sys_num, var);
1705 send_vals_size[block] += n_comp_tot*num_vecs;
1712 for (
unsigned int blk=0; blk<num_blks; blk++)
1719 first_object = blk*io_blksize,
1720 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs);
1723 std::vector<dof_id_type> & ids (xfer_ids[blk]);
1724 std::vector<Number> & vals (send_vals[blk]);
1728 ids.clear(); ids.reserve (xfer_ids_size[blk]);
1729 vals.clear(); vals.reserve (send_vals_size[blk]);
1731 if (send_vals_size[blk] != 0)
1732 for (iterator_type it=begin; it!=end; ++it)
1733 if (((*it)->id() >= first_object) &&
1734 ((*it)->id() < last_object))
1736 ids.push_back((*it)->id());
1740 unsigned int n_comp_tot=0;
1742 for (
const auto & var : vars_to_write)
1743 n_comp_tot += (*it)->n_comp(sys_num, var);
1745 ids.push_back (n_comp_tot*num_vecs);
1749 for (
const auto & vec : vecs)
1750 for (
const auto & var : vars_to_write)
1752 const unsigned int n_comp = (*it)->n_comp(sys_num, var);
1754 for (
unsigned int comp=0; comp<n_comp; comp++)
1756 libmesh_assert_greater_equal ((*it)->dof_number(sys_num, var, comp), vec->first_local_index());
1757 libmesh_assert_less ((*it)->dof_number(sys_num, var, comp), vec->last_local_index());
1758 vals.push_back((*vec)((*it)->dof_number(sys_num, var, comp)));
1763#ifdef LIBMESH_HAVE_MPI
1768 this->
comm().
send (0, ids, id_requests[blk], id_tags[blk]);
1769 this->
comm().
send (0, vals, val_requests[blk], val_tags[blk]);
1776 std::vector<std::vector<dof_id_type>> recv_ids (this->
n_processors());
1777 std::vector<std::vector<Number>> recv_vals (this->
n_processors());
1778 std::vector<unsigned int> obj_val_offsets;
1779 std::vector<Number> output_vals;
1782 ThreadedIO<Number> threaded_io(io, output_vals);
1783 std::unique_ptr<Threads::Thread> async_io;
1785 for (
unsigned int blk=0; blk<num_blks; blk++)
1790 first_object = cast_int<dof_id_type>(blk*io_blksize),
1791 last_object = std::min(cast_int<dof_id_type>((blk+1)*io_blksize), n_objs),
1792 n_objects_blk = last_object - first_object;
1797 obj_val_offsets.resize (n_objects_blk); std::fill (obj_val_offsets.begin(), obj_val_offsets.end(), 0);
1799 std::size_t n_val_recvd_blk=0;
1804#ifdef LIBMESH_HAVE_MPI
1807 std::vector<dof_id_type> & ids (recv_ids[id_status.
source()]);
1810 std::vector<dof_id_type> & ids (recv_ids[0]);
1811 ids = xfer_ids[blk];
1816 for (std::size_t idx=0, sz=ids.size(); idx<sz; idx+=2)
1819 local_idx = ids[idx+0]-first_object,
1820 n_vals_tot_allvecs = ids[idx+1];
1822 libmesh_assert_less (local_idx, n_objects_blk);
1823 libmesh_assert_less (local_idx, obj_val_offsets.size());
1825 obj_val_offsets[local_idx] = n_vals_tot_allvecs;
1828#ifdef LIBMESH_HAVE_MPI
1831 std::vector<Number> & vals (recv_vals[val_status.
source()]);
1835 std::vector<Number> & vals (recv_vals[0]);
1836 vals = send_vals[blk];
1839 n_val_recvd_blk += vals.size();
1845 std::partial_sum(obj_val_offsets.begin(), obj_val_offsets.end(),
1846 obj_val_offsets.begin());
1850 if (async_io.get()) async_io->join();
1854 output_vals.resize(n_val_recvd_blk);
1859 const std::vector<dof_id_type> & ids (recv_ids [proc]);
1860 const std::vector<Number> & vals(recv_vals[proc]);
1861 std::vector<Number>::const_iterator proc_vals(vals.begin());
1863 for (std::size_t idx=0, sz=ids.size(); idx<sz; idx+=2)
1866 local_idx = ids[idx+0]-first_object,
1867 n_vals_tot_allvecs = ids[idx+1];
1871 std::vector<Number>::iterator out_vals(output_vals.begin());
1873 std::advance (out_vals, obj_val_offsets[local_idx-1]);
1875 for (
unsigned int val=0; val<n_vals_tot_allvecs; val++, ++out_vals, ++proc_vals)
1879 *out_vals = *proc_vals;
1886 async_io = std::make_unique<Threads::Thread>(threaded_io);
1887 written_length += output_vals.size();
1907 return written_length;
1913 const unsigned int var,
1916 unsigned int written_length=0;
1917 std::vector<Number> vals;
1922 std::vector<dof_id_type> SCALAR_dofs;
1924 const unsigned int n_scalar_dofs = cast_int<unsigned int>
1925 (SCALAR_dofs.size());
1927 for (
unsigned int i=0; i<n_scalar_dofs; i++)
1929 vals.push_back( vec(SCALAR_dofs[i]) );
1933#ifdef LIBMESH_HAVE_MPI
1948 this->
comm().
send(0, vals, val_tag);
1957 const unsigned int vals_size =
1958 cast_int<unsigned int>(vals.size());
1960 written_length += vals_size;
1963 return written_length;
1971 parallel_object_only();
1982 written_length += cast_int<dof_id_type>
1985 this->
get_mesh().local_nodes_begin(),
1986 this->
get_mesh().local_nodes_end(),
1991 written_length += cast_int<dof_id_type>
1994 this->
get_mesh().local_elements_begin(),
1995 this->
get_mesh().local_elements_end(),
2008 libmesh_assert_equal_to (written_length, vec_length);
2010 return written_length;
2014template <
typename InValType>
2018 parallel_object_only();
2036 unsigned int num_vecs=0;
2042 io.
data(vector_length);
2044 libmesh_error_msg_if
2045 (num_vecs != vectors.size(),
2046 "Xdr file header declares " << num_vecs <<
" vectors, but we were asked to read " << vectors.size());
2050 libmesh_error_msg_if (vectors[0] ==
nullptr,
"vectors[0] should not be null");
2051 libmesh_error_msg_if (vectors[0]->size() != vector_length,
"Inconsistent vector sizes");
2064 std::size_t read_length = 0;
2070 this->
get_mesh().local_nodes_begin(),
2071 this->
get_mesh().local_nodes_end(),
2080 this->
get_mesh().local_elements_begin(),
2081 this->
get_mesh().local_elements_end(),
2092 libmesh_assert_not_equal_to (vec, 0);
2102 libmesh_assert_not_equal_to (vec, 0);
2114 parallel_object_only();
2123 std::size_t written_length = 0;
2128 n_vec = cast_int<unsigned int>(vectors.size());
2130 vec_size = vectors.empty() ? 0 : vectors[0]->size();
2132 io.
data(n_vec,
"# number of vectors");
2134 io.
data(vec_size,
"# vector length");
2142 this->
get_mesh().local_nodes_begin(),
2143 this->
get_mesh().local_nodes_end(),
2151 this->
get_mesh().local_elements_begin(),
2152 this->
get_mesh().local_elements_end(),
2161 libmesh_assert_not_equal_to (vec, 0);
2167 return written_length;
2173template LIBMESH_EXPORT
void System::read_parallel_data<Number> (
Xdr & io,
const bool read_additional_data);
2174template LIBMESH_EXPORT
void System::read_serialized_data<Number> (
Xdr & io,
const bool read_additional_data);
2176template LIBMESH_EXPORT std::size_t System::read_serialized_vectors<Number> (
Xdr & io,
const std::vector<
NumericVector<Number> *> & vectors)
const;
2177#ifdef LIBMESH_USE_COMPLEX_NUMBERS
2178template LIBMESH_EXPORT
void System::read_parallel_data<Real> (
Xdr & io,
const bool read_additional_data);
2179template LIBMESH_EXPORT
void System::read_serialized_data<Real> (
Xdr & io,
const bool read_additional_data);
2181template LIBMESH_EXPORT std::size_t System::read_serialized_vectors<Real> (
Xdr & io,
const std::vector<
NumericVector<Number> *> & vectors)
const;
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 send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
This class handles the numbering of degrees of freedom on a mesh.
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...
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
InfMapType inf_map
The coordinate mapping type of the infinite element.
OrderWrapper radial_order
The approximation order in radial direction of the infinite element.
OrderWrapper order
The approximation order of the element (at 0 p-refinement level).
FEFamily radial_family
The type of approximation in radial direction.
FEFamily family
The type of finite element.
unsigned int mesh_dimension() const
virtual dof_id_type n_elem() const =0
virtual dof_id_type n_nodes() const =0
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
virtual void set(const numeric_index_type i, const T value)=0
Sets v(i) = value.
ParallelType type() const
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
virtual numeric_index_type size() const =0
int get_order() const
Explicitly request the order as an int.
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
unsigned int n_vectors() const
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.
const std::string & name() const
std::size_t read_serialized_vectors(Xdr &io, const std::vector< NumericVector< Number > * > &vectors) const
Read a number of identically distributed vectors.
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.
const Variable & variable(unsigned int var) const
Return a constant reference to Variable var.
void write_parallel_data(Xdr &io, const bool write_additional_data) const
Writes additional data, namely vectors, for this System.
dof_id_type write_serialized_vector(Xdr &io, const NumericVector< Number > &vec) const
Writes a vector for this System.
void read_serialized_data(Xdr &io, const bool read_additional_data=true)
Reads additional data, namely vectors, for this System.
std::map< std::string, std::unique_ptr< NumericVector< Number > >, std::less<> > _vectors
Some systems need an arbitrary number of vectors.
numeric_index_type read_serialized_vector(Xdr &io, NumericVector< Number > *vec)
Reads a vector for this System.
std::vector< unsigned int > _written_var_indices
This vector is used only when reading in a system from file.
const FEType & variable_type(const unsigned int i) 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.
void write_header(Xdr &io, std::string_view version, const bool write_additional_data) const
Writes the basic data header for this System.
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.
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.
std::size_t write_serialized_vectors(Xdr &io, const std::vector< const NumericVector< Number > * > &vectors) const
Serialize & write a number of identically distributed vectors.
virtual void clear()
Clear all the data structures associated with the system.
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...
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
const std::string & variable_name(const unsigned int i) const
unsigned int variable_number(std::string_view var) const
void read_parallel_data(Xdr &io, const bool read_additional_data)
Reads additional data, namely vectors, for this System.
unsigned int n_vars() const
const DofMap & get_dof_map() const
unsigned int _additional_data_written
This flag is used only when reading in a system from file.
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 number() const
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.
const MeshBase & get_mesh() const
void write_serialized_data(Xdr &io, const bool write_additional_data=true) const
Writes additional data, namely vectors, for this System.
Simple compatibility class for std::thread 'concurrent' execution.
void join()
Join is a no-op, since the constructor blocked until completion.
const std::set< subdomain_id_type > & active_subdomains() const
const FEType & type() const
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 comment(std::string &)
Writes or reads (ignores) a comment line.
int version() const
Gets the version of the file that is being read.
void data(T &a, std::string_view comment="")
Inputs or outputs a single value.
const unsigned int any_source
bool contains(std::string_view superstring, std::string_view substring)
Look for a substring within a string.
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
ParallelType
Defines an enum for parallel data structure types.
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
dof_id_type numeric_index_type
Tnew cast_int(Told oldvar)
bool on_command_line(std::string arg)
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...
const dof_id_type n_nodes