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