21 #include "libmesh/sparse_matrix.h" 24 #include "libmesh/dof_map.h" 25 #include "libmesh/dense_matrix.h" 26 #include "libmesh/diagonal_matrix.h" 27 #include "libmesh/laspack_matrix.h" 28 #include "libmesh/libmesh_logging.h" 29 #include "libmesh/eigen_sparse_matrix.h" 30 #include "libmesh/parallel.h" 31 #include "libmesh/petsc_matrix.h" 32 #include "libmesh/trilinos_epetra_matrix.h" 33 #include "libmesh/numeric_vector.h" 34 #include "libmesh/enum_solver_package.h" 38 #ifdef LIBMESH_HAVE_GZSTREAM 39 # include "gzstream.h" 42 #ifdef LIBMESH_HAVE_HDF5 51 #ifdef LIBMESH_HAVE_CXX11_REGEX 58 #ifdef LIBMESH_HAVE_HDF5 59 void check_open(
const std::string & filename,
61 const std::string & objname)
63 if (
id == H5I_INVALID_HID)
64 libmesh_error_msg(
"Couldn't open " + objname +
" in " + filename);
69 void check_hdf5(
const std::string & filename, T hdf5val,
const std::string & objname)
72 libmesh_error_msg(
"HDF5 error from " + objname +
" in " + filename);
94 _use_hash_table(false)
109 template <
typename T>
118 template <
typename T>
120 const std::vector<numeric_index_type> & brows,
121 const std::vector<numeric_index_type> & bcols)
123 libmesh_assert_equal_to (dm.
m() / brows.size(), dm.
n() / bcols.size());
126 (dm.
m() / brows.size());
128 libmesh_assert_equal_to (dm.
m()%blocksize, 0);
129 libmesh_assert_equal_to (dm.
n()%blocksize, 0);
131 std::vector<numeric_index_type> rows, cols;
133 rows.reserve(blocksize*brows.size());
134 cols.reserve(blocksize*bcols.size());
136 for (
auto & row : brows)
140 for (
unsigned int v=0; v<blocksize; v++)
144 for (
auto & col : bcols)
148 for (
unsigned int v=0; v<blocksize; v++)
152 this->add_matrix (dm, rows, cols);
165 libmesh_not_implemented();
168 os <<
"Real part:" << std::endl;
172 os << std::setw(8) << (*this)(i,j).
real() <<
" ";
176 os << std::endl <<
"Imaginary part:" << std::endl;
180 os << std::setw(8) << (*this)(i,j).
imag() <<
" ";
191 template <
typename T>
192 std::unique_ptr<SparseMatrix<T>>
201 return std::make_unique<DiagonalMatrix<T>>(comm);
204 switch (solver_package)
207 #ifdef LIBMESH_HAVE_LASPACK 209 return std::make_unique<LaspackMatrix<T>>(comm);
213 #ifdef LIBMESH_HAVE_PETSC 215 return std::make_unique<PetscMatrix<T>>(comm);
219 #ifdef LIBMESH_TRILINOS_HAVE_EPETRA 221 return std::make_unique<EpetraMatrix<T>>(comm);
225 #ifdef LIBMESH_HAVE_EIGEN 227 return std::make_unique<EigenSparseMatrix<T>>(comm);
231 libmesh_error_msg(
"ERROR: Unrecognized solver package: " << solver_package);
236 template <
typename T>
241 this->vector_mult_add(dest,arg);
246 template <
typename T>
257 template <
typename T>
261 libmesh_not_implemented();
265 template <
typename T>
274 template <
typename T>
277 parallel_object_only();
282 end_dof = this->row_stop();
286 if (this->processor_id() == 0)
288 libmesh_assert_equal_to (first_dof, 0);
296 if (c != static_cast<T>(0.0))
298 os << i <<
" " << j <<
" " << c << std::endl;
305 os << (*
this)(i,j) <<
" ";
310 std::vector<numeric_index_type> ibuf, jbuf;
315 this->comm().receive(p, ibuf);
316 this->comm().receive(p, jbuf);
317 this->comm().receive(p, cbuf);
318 libmesh_assert_equal_to (ibuf.size(), jbuf.size());
319 libmesh_assert_equal_to (ibuf.size(), cbuf.size());
323 libmesh_assert_greater_equal (ibuf.front(), currenti);
324 libmesh_assert_greater_equal (ibuf.back(), ibuf.front());
326 std::size_t currentb = 0;
327 for (;currenti <= ibuf.back(); ++currenti)
333 if (currentb < ibuf.size() &&
334 ibuf[currentb] == currenti &&
337 os << currenti <<
" " << j <<
" " << cbuf[currentb] << std::endl;
346 if (currentb < ibuf.size() &&
347 ibuf[currentb] == currenti &&
350 os << cbuf[currentb] <<
" ";
354 os << static_cast<T>(0.0) <<
" ";
362 for (; currenti != this->m(); ++currenti)
365 os << static_cast<T>(0.0) <<
" ";
372 std::vector<numeric_index_type> ibuf, jbuf;
382 if (c != static_cast<T>(0.0))
390 this->comm().send(0,ibuf);
391 this->comm().send(0,jbuf);
392 this->comm().send(0,cbuf);
397 template <
typename T>
400 parallel_object_only();
405 end_dof = this->row_stop();
409 if (this->processor_id() == 0)
411 std::unique_ptr<std::ofstream> file;
414 file = std::make_unique<std::ofstream>(
name.c_str());
418 std::size_t sparsity_nonzeros = this->n_nonzeros();
420 std::size_t real_nonzeros = 0;
422 libmesh_assert_equal_to(first_dof, 0);
428 if (c != static_cast<T>(0.0))
436 std::size_t nonzeros_on_p = 0;
437 this->comm().receive(p, nonzeros_on_p);
438 real_nonzeros += nonzeros_on_p;
441 if (sparsity_nonzeros &&
442 sparsity_nonzeros != real_nonzeros)
443 libmesh_warning(sparsity_nonzeros <<
444 " nonzeros allocated, but " <<
445 real_nonzeros <<
" used.");
451 os <<
"%Mat Object: () " << this->n_processors() <<
" MPI processes\n" 452 <<
"% type: " << (this->n_processors() > 1 ?
"mpi" :
"seq") <<
"aij\n" 453 <<
"% Size = " << this->m() <<
' ' << this->n() <<
'\n' 454 <<
"% Nonzeros = " << real_nonzeros <<
'\n' 455 <<
"zzz = zeros(" << real_nonzeros <<
",3);\n" 465 if (c != static_cast<T>(0.0))
468 os << (i+1) <<
' ' << (j+1) <<
" " << c <<
'\n';
473 std::vector<numeric_index_type> ibuf, jbuf;
477 this->comm().receive(p, ibuf);
478 this->comm().receive(p, jbuf);
479 this->comm().receive(p, cbuf);
480 libmesh_assert_equal_to (ibuf.size(), jbuf.size());
481 libmesh_assert_equal_to (ibuf.size(), cbuf.size());
484 os << ibuf[n] <<
' ' << jbuf[n] <<
" " << cbuf[n] <<
'\n';
487 os <<
"];\n" <<
"Mat_sparse = spconvert(zzz);" << std::endl;
491 std::vector<numeric_index_type> ibuf, jbuf;
493 std::size_t my_nonzeros = 0;
502 if (c != static_cast<T>(0.0))
511 this->comm().send(0,my_nonzeros);
512 this->comm().send(0,ibuf);
513 this->comm().send(0,jbuf);
514 this->comm().send(0,cbuf);
520 template <
typename T>
522 const std::string & groupname)
const 524 #if defined(LIBMESH_USE_COMPLEX_NUMBERS) || !defined(LIBMESH_HAVE_HDF5) 530 libmesh_error_msg(
"ERROR: need HDF5 support to handle .h5 files!!!");
532 LOG_SCOPE(
"print_coreform_hdf5()",
"SparseMatrix");
537 if constexpr (
sizeof(T) >
sizeof(
double))
538 libmesh_not_implemented();
541 end_dof = this->row_stop();
543 std::vector<std::size_t> cols, row_offsets;
544 std::vector<double> vals;
546 if (this->processor_id() == 0)
547 row_offsets.push_back(0);
554 if (c != static_cast<T>(0.0))
561 row_offsets.push_back(cols.size());
564 if (this->processor_id() == 0)
566 const hid_t file = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC,
567 H5P_DEFAULT, H5P_DEFAULT);
568 if (file == H5I_INVALID_HID)
569 libmesh_file_error(filename);
572 H5Gcreate2(file, groupname.c_str(), H5P_DEFAULT, H5P_DEFAULT,
574 check_open(filename, group, groupname);
576 auto write_size_attribute = [&filename, &group]
577 (
const std::string & attribute_name,
unsigned long long writeval)
579 const hid_t fspace = H5Screate(H5S_SCALAR);
580 check_hdf5(filename, fspace, attribute_name +
" fspace");
582 const hid_t attr = H5Acreate2(group, attribute_name.c_str(),
583 H5T_STD_I64LE, fspace,
584 H5P_DEFAULT, H5P_DEFAULT);
585 check_hdf5(filename, attr, attribute_name);
589 const herr_t errval = H5Awrite(attr, H5T_NATIVE_ULLONG, &writeval);
590 check_hdf5(filename, errval, attribute_name +
" write");
596 write_size_attribute(
"num_cols", this->n());
597 write_size_attribute(
"num_rows", this->m());
599 auto write_vector = [&filename, &group]
600 (
const std::string & dataname,
auto hdf5_file_type,
601 auto hdf5_native_type,
auto & datavec)
603 const hsize_t len[1] = {cast_int<hsize_t>(datavec.size())};
605 const hid_t space = H5Screate_simple(1, len,
nullptr);
606 check_hdf5(filename, space, dataname +
" space");
609 H5Dcreate2(group, dataname.c_str(), hdf5_file_type, space,
610 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
611 check_hdf5(filename, data, dataname +
" data");
614 H5Dwrite(data, hdf5_native_type, H5S_ALL, H5S_ALL,
615 H5P_DEFAULT, datavec.data());
616 check_hdf5(filename, errval, dataname +
" write");
622 std::vector<std::size_t> vals_sizes, first_dofs;
623 this->comm().gather(0, vals.size(), vals_sizes);
624 this->comm().gather(0, cast_int<std::size_t>(first_dof), first_dofs);
625 first_dofs.push_back(this->m());
627 this->comm().allgather(cols);
628 this->comm().allgather(vals);
629 this->comm().allgather(row_offsets);
631 libmesh_assert_equal_to(vals.size(),
633 libmesh_assert_equal_to(vals.size(),
634 std::accumulate(vals_sizes.begin(),
638 std::size_t extra_offset = 0;
641 extra_offset += vals_sizes[p-1];
642 for (
auto i :
make_range(first_dofs[p]+1, first_dofs[p+1]+1))
643 row_offsets[i] += extra_offset;
646 write_vector(
"cols", H5T_STD_U64LE, H5T_NATIVE_ULLONG, cols);
647 write_vector(
"row_offsets", H5T_STD_U64LE, H5T_NATIVE_ULLONG, row_offsets);
648 write_vector(
"vals", H5T_IEEE_F64LE, H5T_NATIVE_DOUBLE, vals);
655 std::vector<std::size_t> dummy;
656 this->comm().gather(0, vals.size(), dummy);
657 this->comm().gather(0, cast_int<std::size_t>(first_dof), dummy);
658 this->comm().allgather(cols);
659 this->comm().allgather(vals);
660 this->comm().allgather(row_offsets);
662 #endif // LIBMESH_HAVE_HDF5 667 template <
typename T>
670 libmesh_not_implemented_msg
671 (
"libMesh cannot write PETSc binary-format files from non-PETSc matrices");
676 template <
typename T>
679 libmesh_not_implemented_msg
680 (
"libMesh cannot write PETSc HDF5-format files from non-PETSc matrices");
685 template <
typename T>
689 std::ifstream in (filename.c_str());
691 (!in.good(),
"ERROR: cannot read file:\n\t" <<
700 basename.remove_suffix(3);
704 this->read_matlab(filename);
707 #ifndef LIBMESH_HAVE_PETSC 708 libmesh_error_msg(
"Cannot load PETSc matrix file " <<
709 filename <<
" without PETSc-enabled libMesh.");
710 #elif LIBMESH_DOF_ID_BYTES != 8 711 libmesh_error_msg(
"Cannot load 64-bit PETSc matrix file " <<
712 filename <<
" with non-64-bit libMesh.");
715 libmesh_not_implemented_msg(
"Gzipped PETSc matrices are not currently supported");
716 this->read_petsc_binary(filename);
720 #ifndef LIBMESH_HAVE_PETSC 721 libmesh_error_msg(
"Cannot load PETSc matrix file " <<
722 filename <<
" without PETSc-enabled libMesh.");
723 #elif LIBMESH_DOF_ID_BYTES != 4 724 libmesh_error_msg(
"Cannot load 32-bit PETSc matrix file " <<
725 filename <<
" with non-32-bit libMesh.");
728 libmesh_not_implemented_msg(
"Gzipped PETSc matrices are not currently supported");
729 this->read_petsc_binary(filename);
734 libmesh_not_implemented_msg(
"Gzipped HDF5 matrices are not currently supported");
735 this->read_coreform_hdf5(filename);
738 libmesh_error_msg(
" ERROR: Unrecognized matrix file extension on: " 740 <<
"\n I understand the following:\n\n" 741 <<
" *.h5 -- CoreForm HDF5 sparse matrix format\n" 742 <<
" *.matlab -- Matlab sparse matrix format\n" 743 <<
" *.matlab.gz -- Matlab sparse matrix format, gzipped\n" 744 <<
" *.m -- Matlab sparse matrix format\n" 745 <<
" *.m.gz -- Matlab sparse matrix format, gzipped\n" 746 <<
" *.petsc32 -- PETSc binary format, 32-bit\n" 747 <<
" *.petsc64 -- PETSc binary format, 64-bit\n" 753 template <
typename T>
757 std::ofstream outstr (filename.c_str());
759 (!outstr.good(),
"ERROR: cannot write to file:\n\t" <<
768 basename.remove_suffix(3);
772 this->print_matlab(filename);
775 #ifndef LIBMESH_HAVE_PETSC 776 libmesh_error_msg(
"Cannot load PETSc matrix file " <<
777 filename <<
" without PETSc-enabled libMesh.");
778 #elif LIBMESH_DOF_ID_BYTES != 8 779 libmesh_error_msg(
"Cannot load 64-bit PETSc matrix file " <<
780 filename <<
" with non-64-bit libMesh.");
783 libmesh_not_implemented_msg(
"Gzipped PETSc matrices are not currently supported");
784 this->print_petsc_binary(filename);
788 #ifndef LIBMESH_HAVE_PETSC 789 libmesh_error_msg(
"Cannot load PETSc matrix file " <<
790 filename <<
" without PETSc-enabled libMesh.");
791 #elif LIBMESH_DOF_ID_BYTES != 4 792 libmesh_error_msg(
"Cannot load 32-bit PETSc matrix file " <<
793 filename <<
" with non-32-bit libMesh.");
796 libmesh_not_implemented_msg(
"Gzipped PETSc matrices are not currently supported");
797 this->print_petsc_binary(filename);
802 libmesh_not_implemented_msg(
"Gzipped HDF5 matrices are not currently supported");
803 this->print_coreform_hdf5(filename);
806 libmesh_error_msg(
" ERROR: Unrecognized matrix file extension on: " 808 <<
"\n I understand the following:\n\n" 809 <<
" *.h5 -- CoreForm HDF5 sparse matrix format\n" 810 <<
" *.matlab -- Matlab sparse matrix format\n" 811 <<
" *.matlab.gz -- Matlab sparse matrix format, gzipped\n" 812 <<
" *.m -- Matlab sparse matrix format\n" 813 <<
" *.m.gz -- Matlab sparse matrix format, gzipped\n" 814 <<
" *.petsc32 -- PETSc binary format, 32-bit\n" 815 <<
" *.petsc64 -- PETSc binary format, 64-bit\n" 821 template <
typename T>
823 const std::string & groupname)
825 #ifndef LIBMESH_HAVE_HDF5 827 libmesh_error_msg(
"ERROR: need HDF5 support to handle .h5 files!!!");
829 LOG_SCOPE(
"read_coreform_hdf5()",
"SparseMatrix");
831 std::size_t num_rows = 0, num_cols = 0;
834 hid_t group = H5I_INVALID_HID;
835 hid_t file = H5I_INVALID_HID;
837 if (this->processor_id() == 0)
839 file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
841 if (file == H5I_INVALID_HID)
842 libmesh_file_error(filename);
844 group = H5Gopen(file, groupname.c_str(), H5P_DEFAULT);
845 check_open(filename, group, groupname);
847 auto read_size_attribute = [&filename, &group]
848 (
const std::string & attribute_name)
850 unsigned long long returnval = 0;
852 const hid_t attr = H5Aopen(group, attribute_name.c_str(), H5P_DEFAULT);
853 check_open(filename, attr, attribute_name);
855 const hid_t attr_type = H5Aget_type(attr);
856 check_hdf5(filename, attr_type, attribute_name +
" type");
860 if (H5Tget_class(attr_type) != H5T_INTEGER)
861 libmesh_error_msg(
"Non-integer type for " + attribute_name +
" in " + filename);
867 const herr_t errval = H5Aread(attr, H5T_NATIVE_ULLONG, &returnval);
868 check_hdf5(filename, errval, attribute_name +
" read");
875 num_cols = read_size_attribute(
"num_cols");
876 num_rows = read_size_attribute(
"num_rows");
878 this->comm().broadcast(num_cols);
879 this->comm().broadcast(num_rows);
883 this->comm().broadcast(num_cols);
884 this->comm().broadcast(num_rows);
888 new_col_start, new_col_stop;
892 std::vector<numeric_index_type> new_row_starts, new_row_stops,
893 new_col_starts, new_col_stops;
896 num_cols == this->n() &&
897 num_rows == this->m())
899 new_row_start = this->row_start(),
900 new_row_stop = this->row_stop();
902 new_col_start = this->col_start(),
903 new_col_stop = this->col_stop();
908 new_row_start = this->processor_id() * num_rows / this->n_processors(),
909 new_row_stop = (this->processor_id()+1) * num_rows / this->n_processors();
911 new_col_start = this->processor_id() * num_cols / this->n_processors(),
912 new_col_stop = (this->processor_id()+1) * num_cols / this->n_processors();
915 this->comm().gather(0, new_row_start, new_row_starts);
916 this->comm().gather(0, new_row_stop, new_row_stops);
917 this->comm().gather(0, new_col_start, new_col_starts);
918 this->comm().gather(0, new_col_stop, new_col_stops);
921 off_diagonal_nonzeros = 0;
923 std::vector<std::size_t> cols, row_offsets;
924 std::vector<double> vals;
926 if (this->processor_id() == 0)
928 auto read_vector = [&filename, &group]
929 (
const std::string & dataname,
auto hdf5_class,
930 auto hdf5_type,
auto & datavec)
932 const hid_t data = H5Dopen1(group, dataname.c_str());
933 check_open(filename, data, dataname.c_str());
935 const hid_t
data_type = H5Dget_type(data);
936 check_hdf5(filename,
data_type, dataname +
" type");
940 if (H5Tget_class(
data_type) != hdf5_class)
941 libmesh_error_msg(
"Unexpected type for " + dataname +
" in " + filename);
945 const hid_t dataspace = H5Dget_space(data);
946 check_hdf5(filename, dataspace, dataname +
" space");
948 int ndims = H5Sget_simple_extent_ndims(dataspace);
950 libmesh_error_msg(
"Non-vector space for " + dataname +
" in " + filename);
953 herr_t errval = H5Sget_simple_extent_dims(dataspace, &len, &maxlen);
954 check_hdf5(filename, errval, dataname +
" dims");
958 errval = H5Dread(data, hdf5_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, datavec.data());
959 check_hdf5(filename, errval, dataname +
" read");
964 read_vector(
"cols", H5T_INTEGER, H5T_NATIVE_ULLONG, cols);
965 read_vector(
"row_offsets", H5T_INTEGER, H5T_NATIVE_ULLONG, row_offsets);
966 read_vector(
"vals", H5T_FLOAT, H5T_NATIVE_DOUBLE, vals);
968 if (cols.size() != vals.size())
969 libmesh_error_msg(
"Inconsistent cols/vals sizes in " + filename);
971 if (row_offsets.size() != num_rows + 1)
972 libmesh_error_msg(
"Inconsistent row_offsets size in " + filename);
979 if (row_offsets[0] != 0)
980 libmesh_error_msg(
"Unexpected row_offsets[0] in " + filename);
984 while (row_offsets[current_row+1] <= i)
987 if (row_offsets[current_row] < row_offsets[current_row-1])
988 libmesh_error_msg(
"Non-monotonic row_offsets in " + filename);
989 current_on_diagonal_nonzeros = 0;
990 current_off_diagonal_nonzeros = 0;
993 while (current_row >= new_row_stops[current_proc])
997 if (cols[i] >= new_col_starts[current_proc] &&
998 cols[i] < new_col_stops[current_proc])
1000 ++current_on_diagonal_nonzeros;
1001 on_diagonal_nonzeros =
1002 std::max(on_diagonal_nonzeros,
1003 current_on_diagonal_nonzeros);
1007 ++current_off_diagonal_nonzeros;
1008 off_diagonal_nonzeros =
1009 std::max(off_diagonal_nonzeros,
1010 current_off_diagonal_nonzeros);
1015 this->comm().broadcast(on_diagonal_nonzeros);
1016 this->comm().broadcast(off_diagonal_nonzeros);
1018 this->
init(num_rows, num_cols,
1019 new_row_stop-new_row_start,
1020 new_col_stop-new_col_start,
1021 on_diagonal_nonzeros,
1022 off_diagonal_nonzeros);
1025 if (this->processor_id() == 0)
1030 while (row_offsets[current_row+1] <= i)
1033 libmesh_assert_greater_equal (row_offsets[current_row],
1034 row_offsets[current_row-1]);
1036 this->
set(current_row, cols[i], vals[i]);
1044 #endif // LIBMESH_HAVE_HDF5 1049 template <
typename T>
1052 LOG_SCOPE(
"read_matlab()",
"SparseMatrix");
1054 #ifndef LIBMESH_HAVE_CXX11_REGEX 1055 libmesh_not_implemented();
1058 parallel_object_only();
1068 std::vector<numeric_index_type> new_row_starts, new_row_stops,
1069 new_col_starts, new_col_stops;
1072 new_col_start, new_col_stop;
1083 std::unique_ptr<std::istream> file;
1092 std::vector<std::tuple<numeric_index_type, numeric_index_type, T>> entries;
1098 if (this->processor_id() == 0)
1102 const std::regex start_regex
1103 (
"\\s*\\w+\\s*=\\s*\\[");
1104 const std::regex end_regex
1109 #ifdef LIBMESH_HAVE_GZSTREAM 1110 auto inf = std::make_unique<igzstream>();
1112 inf->open(filename.c_str(), std::ios::in);
1113 file = std::move(inf);
1115 libmesh_error_msg(
"ERROR: need gzstream to handle .gz files!!!");
1120 auto inf = std::make_unique<std::ifstream>();
1125 inf->open(new_name.c_str(), std::ios::in);
1126 file = std::move(inf);
1131 const std::regex size_regex
1132 (
"%\\s*[Ss][Ii][Zz][Ee]\\s*=\\s*(\\d+)\\s+(\\d+)");
1133 const std::string whitespace =
" \t";
1135 bool have_started =
false;
1136 bool have_ended =
false;
1137 std::size_t largest_i_seen = 0, largest_j_seen = 0;
1141 std::size_t current_row = 1;
1143 for (std::string line; std::getline(*file, line);)
1153 std::istringstream l(line);
1158 l >> i >> j >>
value;
1162 libmesh_error_msg_if
1163 (!have_started,
"Confused by premature entries in matrix file " << filename);
1165 entries.emplace_back(cast_int<numeric_index_type>(i),
1166 cast_int<numeric_index_type>(j),
1169 libmesh_error_msg_if
1170 (!i || !j,
"Expected 1-based indexing in matrix file " 1173 current_row = std::max(current_row, i);
1175 libmesh_error_msg_if
1177 "Can't handle out-of-order entries in matrix file " 1180 largest_i_seen = std::max(i, largest_i_seen);
1181 largest_j_seen = std::max(j, largest_j_seen);
1184 else if (std::regex_search(line, sm, size_regex))
1186 const std::string msize = sm[1];
1187 const std::string nsize = sm[2];
1188 m = std::stoull(msize);
1189 n = std::stoull(nsize);
1192 else if (std::regex_search(line, start_regex))
1193 have_started =
true;
1195 else if (std::regex_search(line, end_regex))
1202 libmesh_error_msg_if
1203 (!have_started,
"Confused by missing assignment beginning in matrix file " << filename);
1205 libmesh_error_msg_if
1206 (!have_ended,
"Confused by missing assignment ending in matrix file " << filename);
1208 libmesh_error_msg_if
1209 (m > largest_i_seen,
"Confused by missing final row(s) in matrix file " << filename);
1211 libmesh_error_msg_if
1212 (m > 0 && m < largest_i_seen,
"Confused by extra final row(s) in matrix file " << filename);
1217 libmesh_error_msg_if
1218 (n > largest_j_seen,
"Confused by missing final column(s) in matrix file " << filename);
1220 libmesh_error_msg_if
1221 (n > 0 && n < largest_j_seen,
"Confused by extra final column(s) in matrix file " << filename);
1226 this->comm().broadcast(m);
1227 this->comm().broadcast(n);
1231 this->comm().broadcast(m);
1232 this->comm().broadcast(n);
1239 new_row_start = this->row_start(),
1240 new_row_stop = this->row_stop();
1242 new_col_start = this->col_start(),
1243 new_col_stop = this->col_stop();
1248 new_row_start = this->processor_id() * m / this->n_processors(),
1249 new_row_stop = (this->processor_id()+1) * m / this->n_processors();
1251 new_col_start = this->processor_id() * n / this->n_processors(),
1252 new_col_stop = (this->processor_id()+1) * n / this->n_processors();
1255 this->comm().gather(0, new_row_start, new_row_starts);
1256 this->comm().gather(0, new_row_stop, new_row_stops);
1257 this->comm().gather(0, new_col_start, new_col_starts);
1258 this->comm().gather(0, new_col_stop, new_col_stops);
1267 off_diagonal_nonzeros =0;
1269 if (this->processor_id() == 0)
1278 for (
auto [i, j,
value] : entries)
1280 if (i > current_row)
1284 while (current_row >= (new_row_stops[current_proc]+1))
1286 current_on_diagonal_nonzeros = 0;
1287 current_off_diagonal_nonzeros = 0;
1291 if (j >= (new_col_starts[current_proc]+1) &&
1292 j < (new_col_stops[current_proc]+1))
1294 ++current_on_diagonal_nonzeros;
1295 on_diagonal_nonzeros =
1296 std::max(on_diagonal_nonzeros,
1297 current_on_diagonal_nonzeros);
1301 ++current_off_diagonal_nonzeros;
1302 off_diagonal_nonzeros =
1303 std::max(off_diagonal_nonzeros,
1304 current_off_diagonal_nonzeros);
1309 this->comm().broadcast(on_diagonal_nonzeros);
1310 this->comm().broadcast(off_diagonal_nonzeros);
1313 new_row_stop-new_row_start,
1314 new_col_stop-new_col_start,
1315 on_diagonal_nonzeros,
1316 off_diagonal_nonzeros);
1321 if (this->processor_id() == 0)
1322 for (
auto [i, j,
value] : entries)
1323 this->
set(i-1, j-1,
value);
1331 template <
typename T>
1334 libmesh_not_implemented_msg
1335 (
"libMesh cannot read PETSc binary-format files into non-PETSc matrices");
1340 template <
typename T>
1343 libmesh_not_implemented_msg
1344 (
"libMesh cannot read PETSc HDF5-format files into non-PETSc matrices");
1349 template <
typename T>
1354 for (
const auto i :
make_range(this->row_start(), this->row_stop()))
1355 for (
const auto j :
make_range(this->col_start(), this->col_stop()))
1356 this->
set(i, j, (*this)(i, j) *
scale);
1361 template <
typename T>
1364 auto diff_mat = this->clone();
1365 diff_mat->add(-1.0, other_mat);
1366 return diff_mat->l1_norm();
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
bool closed()
Checks that the library has been closed.
virtual std::size_t n_nonzeros() const
SparseMatrix(const Parallel::Communicator &comm)
Constructor; initializes the matrix to be empty, without any structure, i.e.
This helper class can be called on multiple threads to compute the sparsity pattern (or graph) of the...
boost::multiprecision::float128 real(const boost::multiprecision::float128 in)
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
bool ends_with(std::string_view superstring, std::string_view suffix)
Look for a substring at the very end of a string.
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i]...
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
The libMesh namespace provides an interface to certain functionality in the library.
const SparsityPattern::Build * get_sparsity_pattern() const
uint8_t processor_id_type
virtual void zero()=0
Set all entries to zero.
This class handles the numbering of degrees of freedom on a mesh.
void libmesh_ignore(const Args &...)
dof_id_type numeric_index_type
bool _is_initialized
Flag that tells if init() has been called.
auto l1_norm_diff(const NumericVector< T > &vec1, const NumericVector< T > &vec2)
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
std::string unzip_file(std::string_view name)
Create an unzipped copy of a bz2 or xz file, returning the name of the now-unzipped file that can be ...
An object whose state is distributed along a set of processors.
std::string_view basename_of(const std::string &fullname)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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...
bool initialized()
Checks that library initialization has been done.
boost::multiprecision::float128 imag(const boost::multiprecision::float128)
SolverPackage
Defines an enum for various linear solver packages.
MatrixBuildType
Defines an enum for matrix build types.
Defines a dense matrix for use in Finite Element-type computations.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...