23 #include "libmesh/libmesh_config.h"
25 #ifdef LIBMESH_HAVE_PETSC
28 #include "libmesh/petsc_matrix.h"
29 #include "libmesh/dof_map.h"
30 #include "libmesh/dense_matrix.h"
31 #include "libmesh/petsc_vector.h"
32 #include "libmesh/parallel.h"
42 #if PETSC_VERSION_LESS_THAN(3,3,0)
43 # undef LIBMESH_ENABLE_BLOCKED_STORAGE
48 #ifdef LIBMESH_ENABLE_BLOCKED_STORAGE
58 void transform_preallocation_arrays (
const PetscInt blocksize,
59 const std::vector<numeric_index_type> & n_nz,
60 const std::vector<numeric_index_type> & n_oz,
61 std::vector<numeric_index_type> & b_n_nz,
62 std::vector<numeric_index_type> & b_n_oz)
64 libmesh_assert_equal_to (n_nz.size(), n_oz.size());
65 libmesh_assert_equal_to (n_nz.size()%blocksize, 0);
67 b_n_nz.clear(); b_n_nz.reserve(n_nz.size()/blocksize);
68 b_n_oz.clear(); b_n_oz.reserve(n_oz.size()/blocksize);
70 for (std::size_t nn=0, nnzs=n_nz.size(); nn<nnzs; nn += blocksize)
72 b_n_nz.push_back (n_nz[nn]/blocksize);
73 b_n_oz.push_back (n_oz[nn]/blocksize);
94 _destroy_mat_on_exit(true),
102 template <
typename T>
104 const Parallel::Communicator & comm_in) :
106 _destroy_mat_on_exit(false),
116 template <
typename T>
122 template <
typename T>
125 _mat_type = mat_type;
128 template <
typename T>
147 PetscErrorCode
ierr = 0;
148 PetscInt m_global = static_cast<PetscInt>(m_in);
149 PetscInt n_global = static_cast<PetscInt>(n_in);
150 PetscInt m_local = static_cast<PetscInt>(m_l);
151 PetscInt n_local = static_cast<PetscInt>(n_l);
152 PetscInt n_nz = static_cast<PetscInt>(nnz);
153 PetscInt n_oz = static_cast<PetscInt>(noz);
155 ierr = MatCreate(this->comm().
get(), &_mat);
156 LIBMESH_CHKERR(
ierr);
157 ierr = MatSetSizes(_mat, m_local, n_local, m_global, n_global);
158 LIBMESH_CHKERR(
ierr);
159 PetscInt blocksize = static_cast<PetscInt>(blocksize_in);
160 ierr = MatSetBlockSize(_mat,blocksize);
161 LIBMESH_CHKERR(
ierr);
163 #ifdef LIBMESH_ENABLE_BLOCKED_STORAGE
168 libmesh_assert_equal_to (m_local % blocksize, 0);
169 libmesh_assert_equal_to (n_local % blocksize, 0);
170 libmesh_assert_equal_to (m_global % blocksize, 0);
171 libmesh_assert_equal_to (n_global % blocksize, 0);
172 libmesh_assert_equal_to (n_nz % blocksize, 0);
173 libmesh_assert_equal_to (n_oz % blocksize, 0);
175 ierr = MatSetType(_mat, MATBAIJ);
176 LIBMESH_CHKERR(
ierr);
177 ierr = MatSeqBAIJSetPreallocation(_mat, blocksize, n_nz/blocksize, NULL);
178 LIBMESH_CHKERR(
ierr);
179 ierr = MatMPIBAIJSetPreallocation(_mat, blocksize,
180 n_nz/blocksize, NULL,
181 n_oz/blocksize, NULL);
182 LIBMESH_CHKERR(
ierr);
189 ierr = MatSetType(_mat, MATAIJ);
190 LIBMESH_CHKERR(
ierr);
191 ierr = MatSeqAIJSetPreallocation(_mat, n_nz, NULL);
192 LIBMESH_CHKERR(
ierr);
193 ierr = MatMPIAIJSetPreallocation(_mat, n_nz, NULL, n_oz, NULL);
194 LIBMESH_CHKERR(
ierr);
198 #if !PETSC_VERSION_LESS_THAN(3,9,4) && LIBMESH_HAVE_PETSC_HYPRE
199 ierr = MatSetType(_mat, MATHYPRE);
200 LIBMESH_CHKERR(
ierr);
201 ierr = MatHYPRESetPreallocation(_mat, n_nz, NULL, n_oz, NULL);
202 LIBMESH_CHKERR(
ierr);
204 libmesh_error_msg(
"PETSc 3.9.4 or higher with hypre is required for MatHypre");
208 default: libmesh_error_msg(
"Unsupported petsc matrix type");
213 #if PETSC_VERSION_LESS_THAN(3,0,0)
214 ierr = MatSetOption(_mat, MAT_NEW_NONZERO_ALLOCATION_ERR);
216 ierr = MatSetOption(_mat, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);
218 LIBMESH_CHKERR(
ierr);
221 ierr = MatSetOptionsPrefix(_mat,
"");
222 LIBMESH_CHKERR(
ierr);
223 ierr = MatSetFromOptions(_mat);
224 LIBMESH_CHKERR(
ierr);
230 template <
typename T>
235 const std::vector<numeric_index_type> & n_nz,
236 const std::vector<numeric_index_type> & n_oz,
249 libmesh_assert_equal_to (n_nz.size(), m_l);
250 libmesh_assert_equal_to (n_oz.size(), m_l);
252 PetscErrorCode
ierr = 0;
253 PetscInt m_global = static_cast<PetscInt>(m_in);
254 PetscInt n_global = static_cast<PetscInt>(n_in);
255 PetscInt m_local = static_cast<PetscInt>(m_l);
256 PetscInt n_local = static_cast<PetscInt>(n_l);
258 ierr = MatCreate(this->comm().
get(), &_mat);
259 LIBMESH_CHKERR(
ierr);
260 ierr = MatSetSizes(_mat, m_local, n_local, m_global, n_global);
261 LIBMESH_CHKERR(
ierr);
262 PetscInt blocksize = static_cast<PetscInt>(blocksize_in);
263 ierr = MatSetBlockSize(_mat,blocksize);
264 LIBMESH_CHKERR(
ierr);
266 #ifdef LIBMESH_ENABLE_BLOCKED_STORAGE
271 libmesh_assert_equal_to (m_local % blocksize, 0);
272 libmesh_assert_equal_to (n_local % blocksize, 0);
273 libmesh_assert_equal_to (m_global % blocksize, 0);
274 libmesh_assert_equal_to (n_global % blocksize, 0);
276 ierr = MatSetType(_mat, MATBAIJ);
277 LIBMESH_CHKERR(
ierr);
280 std::vector<numeric_index_type> b_n_nz, b_n_oz;
282 transform_preallocation_arrays (blocksize,
286 ierr = MatSeqBAIJSetPreallocation (_mat,
290 LIBMESH_CHKERR(
ierr);
292 ierr = MatMPIBAIJSetPreallocation (_mat,
298 LIBMESH_CHKERR(
ierr);
305 ierr = MatSetType(_mat, MATAIJ);
306 LIBMESH_CHKERR(
ierr);
307 ierr = MatSeqAIJSetPreallocation (_mat,
310 LIBMESH_CHKERR(
ierr);
311 ierr = MatMPIAIJSetPreallocation (_mat,
319 #if !PETSC_VERSION_LESS_THAN(3,9,4) && LIBMESH_HAVE_PETSC_HYPRE
320 ierr = MatSetType(_mat, MATHYPRE);
321 LIBMESH_CHKERR(
ierr);
322 ierr = MatHYPRESetPreallocation (_mat,
327 LIBMESH_CHKERR(
ierr);
329 libmesh_error_msg(
"PETSc 3.9.4 or higher with hypre is required for MatHypre");
333 default: libmesh_error_msg(
"Unsupported petsc matrix type");
339 #if PETSC_VERSION_LESS_THAN(3,0,0)
340 ierr = MatSetOption(_mat, MAT_NEW_NONZERO_ALLOCATION_ERR);
342 ierr = MatSetOption(_mat, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);
344 LIBMESH_CHKERR(
ierr);
347 ierr = MatSetOptionsPrefix(_mat,
"");
348 LIBMESH_CHKERR(
ierr);
349 ierr = MatSetFromOptions(_mat);
350 LIBMESH_CHKERR(
ierr);
357 template <
typename T>
371 const numeric_index_type n_l = this->_dof_map->n_dofs_on_processor(this->processor_id());
375 const std::vector<numeric_index_type> & n_nz = this->_dof_map->get_n_nz();
376 const std::vector<numeric_index_type> & n_oz = this->_dof_map->get_n_oz();
379 libmesh_assert_equal_to (n_nz.size(), m_l);
380 libmesh_assert_equal_to (n_oz.size(), m_l);
382 PetscErrorCode
ierr = 0;
383 PetscInt m_global = static_cast<PetscInt>(my_m);
384 PetscInt n_global = static_cast<PetscInt>(my_n);
385 PetscInt m_local = static_cast<PetscInt>(m_l);
386 PetscInt n_local = static_cast<PetscInt>(n_l);
388 ierr = MatCreate(this->comm().
get(), &_mat);
389 LIBMESH_CHKERR(
ierr);
390 ierr = MatSetSizes(_mat, m_local, n_local, m_global, n_global);
391 LIBMESH_CHKERR(
ierr);
392 PetscInt blocksize = static_cast<PetscInt>(this->_dof_map->block_size());
393 ierr = MatSetBlockSize(_mat,blocksize);
394 LIBMESH_CHKERR(
ierr);
396 #ifdef LIBMESH_ENABLE_BLOCKED_STORAGE
401 libmesh_assert_equal_to (m_local % blocksize, 0);
402 libmesh_assert_equal_to (n_local % blocksize, 0);
403 libmesh_assert_equal_to (m_global % blocksize, 0);
404 libmesh_assert_equal_to (n_global % blocksize, 0);
406 ierr = MatSetType(_mat, MATBAIJ);
407 LIBMESH_CHKERR(
ierr);
410 std::vector<numeric_index_type> b_n_nz, b_n_oz;
412 transform_preallocation_arrays (blocksize,
416 ierr = MatSeqBAIJSetPreallocation (_mat,
420 LIBMESH_CHKERR(
ierr);
422 ierr = MatMPIBAIJSetPreallocation (_mat,
428 LIBMESH_CHKERR(
ierr);
435 ierr = MatSetType(_mat, MATAIJ);
436 LIBMESH_CHKERR(
ierr);
437 ierr = MatSeqAIJSetPreallocation (_mat,
440 LIBMESH_CHKERR(
ierr);
441 ierr = MatMPIAIJSetPreallocation (_mat,
449 #if !PETSC_VERSION_LESS_THAN(3,9,4) && LIBMESH_HAVE_PETSC_HYPRE
450 ierr = MatSetType(_mat, MATHYPRE);
451 LIBMESH_CHKERR(
ierr);
452 ierr = MatHYPRESetPreallocation (_mat,
457 LIBMESH_CHKERR(
ierr);
459 libmesh_error_msg(
"PETSc 3.9.4 or higher with hypre is required for MatHypre");
463 default: libmesh_error_msg(
"Unsupported petsc matrix type");
468 #if PETSC_VERSION_LESS_THAN(3,0,0)
469 ierr = MatSetOption(_mat, MAT_NEW_NONZERO_ALLOCATION_ERR);
471 ierr = MatSetOption(_mat, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);
473 LIBMESH_CHKERR(
ierr);
476 ierr = MatSetOptionsPrefix(_mat,
"");
477 LIBMESH_CHKERR(
ierr);
478 ierr = MatSetFromOptions(_mat);
479 LIBMESH_CHKERR(
ierr);
485 template <
typename T>
488 libmesh_not_implemented();
491 template <
typename T>
494 #if !PETSC_VERSION_LESS_THAN(3,9,0)
497 auto ierr = MatResetPreallocation(_mat);
498 LIBMESH_CHKERR(
ierr);
500 libmesh_warning(
"Your version of PETSc doesn't support resetting of "
501 "preallocation, so we will use your most recent sparsity "
502 "pattern. This may result in a degradation of performance\n");
506 template <
typename T>
513 PetscErrorCode
ierr=0;
517 ierr = MatGetLocalSize(_mat,&m_l,&n_l);
518 LIBMESH_CHKERR(
ierr);
522 ierr = MatZeroEntries(_mat);
523 LIBMESH_CHKERR(
ierr);
527 template <
typename T>
534 PetscErrorCode
ierr=0;
536 #if PETSC_RELEASE_LESS_THAN(3,1,1)
538 ierr = MatZeroRows(_mat, rows.size(),
541 ierr = MatZeroRows(_mat, 0, NULL, diag_value);
548 ierr = MatZeroRows(_mat, cast_int<PetscInt>(rows.size()),
552 ierr = MatZeroRows(_mat, 0, NULL,
PS(diag_value), NULL,
556 LIBMESH_CHKERR(
ierr);
559 template <
typename T>
562 PetscErrorCode
ierr=0;
564 if ((this->
initialized()) && (this->_destroy_mat_on_exit))
568 ierr = LibMeshMatDestroy (&_mat);
569 LIBMESH_CHKERR(
ierr);
577 template <
typename T>
584 PetscErrorCode
ierr=0;
585 PetscReal petsc_value;
590 ierr = MatNorm(_mat, NORM_1, &petsc_value);
591 LIBMESH_CHKERR(
ierr);
593 value = static_cast<Real>(petsc_value);
600 template <
typename T>
607 PetscErrorCode
ierr=0;
608 PetscReal petsc_value;
613 ierr = MatNorm(_mat, NORM_INFINITY, &petsc_value);
614 LIBMESH_CHKERR(
ierr);
616 value = static_cast<Real>(petsc_value);
623 template <
typename T>
632 libmesh_deprecated();
633 libmesh_warning(
"The matrix must be assembled before calling PetscMatrix::print_matlab().\n"
634 "Please update your code, as this warning will become an error in a future release.");
638 PetscErrorCode
ierr=0;
639 PetscViewer petsc_viewer;
642 ierr = PetscViewerCreate (this->comm().
get(),
644 LIBMESH_CHKERR(
ierr);
652 ierr = PetscViewerASCIIOpen( this->comm().
get(),
655 LIBMESH_CHKERR(
ierr);
657 #if PETSC_VERSION_LESS_THAN(3,7,0)
658 ierr = PetscViewerSetFormat (petsc_viewer,
659 PETSC_VIEWER_ASCII_MATLAB);
661 ierr = PetscViewerPushFormat (petsc_viewer,
662 PETSC_VIEWER_ASCII_MATLAB);
665 LIBMESH_CHKERR(
ierr);
667 ierr = MatView (_mat, petsc_viewer);
668 LIBMESH_CHKERR(
ierr);
676 #if PETSC_VERSION_LESS_THAN(3,7,0)
677 ierr = PetscViewerSetFormat (PETSC_VIEWER_STDOUT_WORLD,
678 PETSC_VIEWER_ASCII_MATLAB);
680 ierr = PetscViewerPushFormat (PETSC_VIEWER_STDOUT_WORLD,
681 PETSC_VIEWER_ASCII_MATLAB);
684 LIBMESH_CHKERR(
ierr);
686 ierr = MatView (_mat, PETSC_VIEWER_STDOUT_WORLD);
687 LIBMESH_CHKERR(
ierr);
694 ierr = LibMeshPetscViewerDestroy (&petsc_viewer);
695 LIBMESH_CHKERR(
ierr);
702 template <
typename T>
719 libmesh_deprecated();
720 libmesh_warning(
"The matrix must be assembled before calling PetscMatrix::print_personal().\n"
721 "Please update your code, as this warning will become an error in a future release.");
725 PetscErrorCode
ierr=0;
728 if (os.rdbuf() == std::cout.rdbuf())
730 ierr = MatView(_mat, PETSC_VIEWER_STDOUT_SELF);
731 LIBMESH_CHKERR(
ierr);
739 std::string temp_filename;
743 char c[] =
"temp_petsc_matrix.XXXXXX";
748 if (this->processor_id() == 0)
754 libmesh_error_msg(
"mkstemp failed in PetscMatrix::print_personal()");
766 this->comm().broadcast(temp_filename);
769 PetscViewer petsc_viewer;
775 ierr = PetscViewerASCIIOpen( this->comm().
get(),
776 temp_filename.c_str(),
778 LIBMESH_CHKERR(
ierr);
786 ierr = MatView (_mat, petsc_viewer);
787 LIBMESH_CHKERR(
ierr);
789 if (this->processor_id() == 0)
793 std::ifstream input_stream(temp_filename.c_str());
794 os << input_stream.rdbuf();
798 input_stream.close();
799 std::remove(temp_filename.c_str());
809 template <
typename T>
811 const std::vector<numeric_index_type> & rows,
812 const std::vector<numeric_index_type> & cols)
819 libmesh_assert_equal_to (rows.size(), n_rows);
820 libmesh_assert_equal_to (cols.size(), n_cols);
822 PetscErrorCode
ierr=0;
823 ierr = MatSetValues(_mat,
828 LIBMESH_CHKERR(
ierr);
836 template <
typename T>
838 const std::vector<numeric_index_type> & brows,
839 const std::vector<numeric_index_type> & bcols)
844 cast_int<numeric_index_type>(brows.size());
846 cast_int<numeric_index_type>(bcols.size());
848 PetscErrorCode
ierr=0;
852 cast_int<numeric_index_type>(dm.
m());
854 cast_int<numeric_index_type>(dm.
n());
857 libmesh_assert_equal_to (n_cols / n_bcols, blocksize);
858 libmesh_assert_equal_to (blocksize*n_brows, n_rows);
859 libmesh_assert_equal_to (blocksize*n_bcols, n_cols);
861 PetscInt petsc_blocksize;
862 ierr = MatGetBlockSize(_mat, &petsc_blocksize);
863 LIBMESH_CHKERR(
ierr);
864 libmesh_assert_equal_to (blocksize, static_cast<numeric_index_type>(petsc_blocksize));
868 ierr = MatSetValuesBlocked(_mat,
873 LIBMESH_CHKERR(
ierr);
880 template <
typename T>
882 const std::vector<numeric_index_type> & rows,
883 const std::vector<numeric_index_type> & cols,
884 const bool reuse_submatrix)
const
888 libmesh_deprecated();
889 libmesh_warning(
"The matrix must be assembled before calling PetscMatrix::create_submatrix().\n"
890 "Please update your code, as this warning will become an error in a future release.");
895 PetscMatrix<T> * petsc_submatrix = cast_ptr<PetscMatrix<T> *>(&submatrix);
903 PetscErrorCode
ierr=0;
906 ierr = ISCreateLibMesh(this->comm().
get(),
907 cast_int<PetscInt>(rows.size()),
910 &isrow); LIBMESH_CHKERR(
ierr);
912 ierr = ISCreateLibMesh(this->comm().
get(),
913 cast_int<PetscInt>(cols.size()),
916 &iscol); LIBMESH_CHKERR(
ierr);
919 ierr = LibMeshCreateSubMatrix(_mat,
922 #
if PETSC_RELEASE_LESS_THAN(3,0,1)
925 (reuse_submatrix ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX),
926 &(petsc_submatrix->
_mat)); LIBMESH_CHKERR(
ierr);
930 petsc_submatrix->
close();
933 ierr = LibMeshISDestroy(&isrow); LIBMESH_CHKERR(
ierr);
934 ierr = LibMeshISDestroy(&iscol); LIBMESH_CHKERR(
ierr);
939 template <
typename T>
946 PetscErrorCode
ierr =
952 template <
typename T>
960 if (&petsc_dest !=
this)
964 #if PETSC_VERSION_LESS_THAN(3,0,0)
965 if (&petsc_dest ==
this)
966 ierr = MatTranspose(_mat,NULL);
968 ierr = MatTranspose(_mat,&petsc_dest.
_mat);
969 LIBMESH_CHKERR(
ierr);
972 if (&petsc_dest ==
this)
973 ierr = MatTranspose(_mat,MAT_REUSE_MATRIX,&petsc_dest.
_mat);
975 ierr = MatTranspose(_mat,MAT_INITIAL_MATRIX,&petsc_dest.
_mat);
976 LIBMESH_CHKERR(
ierr);
988 template <
typename T>
1000 PetscErrorCode
ierr=0;
1002 ierr = MatAssemblyBegin (_mat, MAT_FINAL_ASSEMBLY);
1003 LIBMESH_CHKERR(
ierr);
1004 ierr = MatAssemblyEnd (_mat, MAT_FINAL_ASSEMBLY);
1005 LIBMESH_CHKERR(
ierr);
1008 template <
typename T>
1011 semiparallel_only();
1013 PetscErrorCode
ierr=0;
1015 ierr = MatAssemblyBegin (_mat, MAT_FLUSH_ASSEMBLY);
1016 LIBMESH_CHKERR(
ierr);
1017 ierr = MatAssemblyEnd (_mat, MAT_FLUSH_ASSEMBLY);
1018 LIBMESH_CHKERR(
ierr);
1023 template <
typename T>
1028 PetscInt petsc_m=0, petsc_n=0;
1029 PetscErrorCode
ierr=0;
1031 ierr = MatGetSize (_mat, &petsc_m, &petsc_n);
1032 LIBMESH_CHKERR(
ierr);
1034 return static_cast<numeric_index_type>(petsc_m);
1037 template <
typename T>
1044 auto ierr = MatGetLocalSize (_mat, &m, NULL);
1045 LIBMESH_CHKERR(
ierr);
1047 return static_cast<numeric_index_type>(m);
1050 template <
typename T>
1055 PetscInt petsc_m=0, petsc_n=0;
1056 PetscErrorCode
ierr=0;
1058 ierr = MatGetSize (_mat, &petsc_m, &petsc_n);
1059 LIBMESH_CHKERR(
ierr);
1061 return static_cast<numeric_index_type>(petsc_n);
1064 template <
typename T>
1071 auto ierr = MatGetLocalSize (_mat, NULL, &n);
1072 LIBMESH_CHKERR(
ierr);
1074 return static_cast<numeric_index_type>(n);
1077 template <
typename T>
1083 PetscInt petsc_m = 0, petsc_n = 0;
1085 auto ierr = MatGetLocalSize (_mat, &petsc_m, &petsc_n);
1086 LIBMESH_CHKERR(
ierr);
1088 m = static_cast<numeric_index_type>(petsc_m);
1089 n = static_cast<numeric_index_type>(petsc_n);
1092 template <
typename T>
1097 PetscInt start=0,
stop=0;
1098 PetscErrorCode
ierr=0;
1100 ierr = MatGetOwnershipRange(_mat, &start, &
stop);
1101 LIBMESH_CHKERR(
ierr);
1103 return static_cast<numeric_index_type>(start);
1108 template <
typename T>
1113 PetscInt start=0,
stop=0;
1114 PetscErrorCode
ierr=0;
1116 ierr = MatGetOwnershipRange(_mat, &start, &
stop);
1117 LIBMESH_CHKERR(
ierr);
1119 return static_cast<numeric_index_type>(
stop);
1124 template <
typename T>
1131 PetscErrorCode
ierr=0;
1132 PetscInt i_val=i, j_val=j;
1134 PetscScalar petsc_value = static_cast<PetscScalar>(
value);
1135 ierr = MatSetValues(_mat, 1, &i_val, 1, &j_val,
1136 &petsc_value, INSERT_VALUES);
1137 LIBMESH_CHKERR(
ierr);
1142 template <
typename T>
1149 PetscErrorCode
ierr=0;
1150 PetscInt i_val=i, j_val=j;
1152 PetscScalar petsc_value = static_cast<PetscScalar>(
value);
1153 ierr = MatSetValues(_mat, 1, &i_val, 1, &j_val,
1154 &petsc_value, ADD_VALUES);
1155 LIBMESH_CHKERR(
ierr);
1160 template <
typename T>
1162 const std::vector<numeric_index_type> & dof_indices)
1164 this->add_matrix (dm, dof_indices, dof_indices);
1173 template <
typename T>
1180 libmesh_assert_equal_to (this->m(), X_in.
m());
1181 libmesh_assert_equal_to (this->n(), X_in.
n());
1183 PetscScalar a = static_cast<PetscScalar> (a_in);
1184 const PetscMatrix<T> * X = cast_ptr<const PetscMatrix<T> *> (&X_in);
1188 PetscErrorCode
ierr=0;
1193 semiparallel_only();
1195 ierr = MatAXPY(_mat, a, X->
_mat, DIFFERENT_NONZERO_PATTERN);
1196 LIBMESH_CHKERR(
ierr);
1202 template <
typename T>
1209 const PetscScalar * petsc_row;
1210 const PetscInt * petsc_cols;
1219 i_val=static_cast<PetscInt>(i_in),
1220 j_val=static_cast<PetscInt>(j_in);
1229 ierr = MatGetRow(_mat, i_val, &ncols, &petsc_cols, &petsc_row);
1230 LIBMESH_CHKERR(
ierr);
1234 std::pair<const PetscInt *, const PetscInt *> p =
1235 std::equal_range (petsc_cols, petsc_cols + ncols, j_val);
1238 if (p.first != p.second)
1242 const std::size_t j =
1244 const_cast<PetscInt *>(p.first));
1246 libmesh_assert_less (j, ncols);
1247 libmesh_assert_equal_to (petsc_cols[j], j_val);
1249 value = static_cast<T> (petsc_row[j]);
1252 ierr = MatRestoreRow(_mat, i_val,
1253 &ncols, &petsc_cols, &petsc_row);
1254 LIBMESH_CHKERR(
ierr);
1259 template <
typename T>
1261 std::vector<numeric_index_type> & indices,
1262 std::vector<T> & values)
const
1266 const PetscScalar * petsc_row;
1267 const PetscInt * petsc_cols;
1269 PetscErrorCode
ierr=0;
1272 i_val = static_cast<PetscInt>(i_in);
1290 #ifdef LIBMESH_HAVE_CXX11_THREAD
1291 std::lock_guard<std::mutex>
1293 Threads::spin_mutex::scoped_lock
1295 lock(_petsc_matrix_mutex);
1297 ierr = MatGetRow(_mat, i_val, &ncols, &petsc_cols, &petsc_row);
1298 LIBMESH_CHKERR(
ierr);
1301 indices.resize(static_cast<std::size_t>(ncols));
1302 values.resize(static_cast<std::size_t>(ncols));
1306 indices[i] = static_cast<numeric_index_type>(petsc_cols[i]);
1307 values[i] = static_cast<T>(petsc_row[i]);
1310 ierr = MatRestoreRow(_mat, i_val,
1311 &ncols, &petsc_cols, &petsc_row);
1312 LIBMESH_CHKERR(
ierr);
1316 template <
typename T>
1321 PetscErrorCode
ierr=0;
1324 ierr = MatAssembled(_mat, &assembled);
1325 LIBMESH_CHKERR(
ierr);
1327 return (assembled == PETSC_TRUE);
1330 template <
typename T>
1333 this->_destroy_mat_on_exit =
destroy;
1337 template <
typename T>
1353 #endif // #ifdef LIBMESH_HAVE_PETSC