Actual source code: matrix.c

petsc-master 2014-09-12
Report Typos and Errors
  2: /*
  3:    This is where the abstract matrix operations are defined
  4: */

  6: #include <petsc-private/matimpl.h>        /*I "petscmat.h" I*/
  7: #include <petsc-private/vecimpl.h>

  9: /* Logging support */
 10: PetscClassId MAT_CLASSID;
 11: PetscClassId MAT_COLORING_CLASSID;
 12: PetscClassId MAT_FDCOLORING_CLASSID;
 13: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;

 15: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
 16: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
 17: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
 18: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
 19: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
 20: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
 21: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
 22: PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
 23: PetscLogEvent MAT_TransposeColoringCreate;
 24: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
 25: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
 26: PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
 27: PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
 28: PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
 29: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
 30: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
 31: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
 32: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
 33: PetscLogEvent MAT_GetMultiProcBlock;
 34: PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
 35: PetscLogEvent MAT_ViennaCLCopyToGPU;
 36: PetscLogEvent MAT_Merge,MAT_Residual;
 37: PetscLogEvent Mat_Coloring_Apply,Mat_Coloring_Comm,Mat_Coloring_Local,Mat_Coloring_ISCreate,Mat_Coloring_SetUp,Mat_Coloring_Weights;

 39: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};

 43: /*@
 44:    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations

 46:    Logically Collective on Vec

 48:    Input Parameters:
 49: +  x  - the vector
 50: -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
 51:           it will create one internally.

 53:    Output Parameter:
 54: .  x  - the vector

 56:    Example of Usage:
 57: .vb
 58:      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
 59:      VecSetRandom(x,rctx);
 60:      PetscRandomDestroy(rctx);
 61: .ve

 63:    Level: intermediate

 65:    Concepts: vector^setting to random
 66:    Concepts: random^vector

 68: .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
 69: @*/
 70: PetscErrorCode  MatSetRandom(Mat x,PetscRandom rctx)
 71: {
 73:   PetscRandom    randObj = NULL;


 80:   if (!rctx) {
 81:     MPI_Comm comm;
 82:     PetscObjectGetComm((PetscObject)x,&comm);
 83:     PetscRandomCreate(comm,&randObj);
 84:     PetscRandomSetFromOptions(randObj);
 85:     rctx = randObj;
 86:   }

 88:   PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
 89:   (*x->ops->setrandom)(x,rctx);
 90:   PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);

 92:   x->assembled = PETSC_TRUE;
 93:   PetscRandomDestroy(&randObj);
 94:   return(0);
 95: }


100: /*@
101:       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix

103:   Input Parameter:
104: .    A  - the matrix

106:   Output Parameter:
107: .    keptrows - the rows that are not completely zero

109:   Level: intermediate

111:  @*/
112: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
113: {

118:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
119:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
120:   if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
121:   (*mat->ops->findnonzerorows)(mat,keptrows);
122:   return(0);
123: }

127: /*@
128:    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling

130:    Not Collective

132:    Input Parameters:
133: .   A - the matrix

135:    Output Parameters:
136: .   a - the diagonal part (which is a SEQUENTIAL matrix)

138:    Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.

140:    Level: advanced

142: @*/
143: PetscErrorCode  MatGetDiagonalBlock(Mat A,Mat *a)
144: {
145:   PetscErrorCode ierr,(*f)(Mat,Mat*);
146:   PetscMPIInt    size;

152:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
153:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
154:   MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
155:   PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);
156:   if (f) {
157:     (*f)(A,a);
158:     return(0);
159:   } else if (size == 1) {
160:     *a = A;
161:   } else {
162:     MatType mattype;
163:     MatGetType(A,&mattype);
164:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
165:   }
166:   return(0);
167: }

171: /*@
172:    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.

174:    Collective on Mat

176:    Input Parameters:
177: .  mat - the matrix

179:    Output Parameter:
180: .   trace - the sum of the diagonal entries

182:    Level: advanced

184: @*/
185: PetscErrorCode  MatGetTrace(Mat mat,PetscScalar *trace)
186: {
188:   Vec            diag;

191:   MatGetVecs(mat,&diag,NULL);
192:   MatGetDiagonal(mat,diag);
193:   VecSum(diag,trace);
194:   VecDestroy(&diag);
195:   return(0);
196: }

200: /*@
201:    MatRealPart - Zeros out the imaginary part of the matrix

203:    Logically Collective on Mat

205:    Input Parameters:
206: .  mat - the matrix

208:    Level: advanced


211: .seealso: MatImaginaryPart()
212: @*/
213: PetscErrorCode  MatRealPart(Mat mat)
214: {

220:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
221:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
222:   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
223:   MatCheckPreallocated(mat,1);
224:   (*mat->ops->realpart)(mat);
225: #if defined(PETSC_HAVE_CUSP)
226:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
227:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
228:   }
229: #endif
230: #if defined(PETSC_HAVE_VIENNACL)
231:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
232:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
233:   }
234: #endif
235:   return(0);
236: }

240: /*@C
241:    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix

243:    Collective on Mat

245:    Input Parameter:
246: .  mat - the matrix

248:    Output Parameters:
249: +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
250: -   ghosts - the global indices of the ghost points

252:    Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()

254:    Level: advanced

256: @*/
257: PetscErrorCode  MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
258: {

264:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
265:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
266:   if (!mat->ops->getghosts) {
267:     if (nghosts) *nghosts = 0;
268:     if (ghosts) *ghosts = 0;
269:   } else {
270:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
271:   }
272:   return(0);
273: }


278: /*@
279:    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part

281:    Logically Collective on Mat

283:    Input Parameters:
284: .  mat - the matrix

286:    Level: advanced


289: .seealso: MatRealPart()
290: @*/
291: PetscErrorCode  MatImaginaryPart(Mat mat)
292: {

298:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
299:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
300:   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
301:   MatCheckPreallocated(mat,1);
302:   (*mat->ops->imaginarypart)(mat);
303: #if defined(PETSC_HAVE_CUSP)
304:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
305:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
306:   }
307: #endif
308: #if defined(PETSC_HAVE_VIENNACL)
309:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
310:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
311:   }
312: #endif
313:   return(0);
314: }

318: /*@
319:    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)

321:    Collective on Mat

323:    Input Parameter:
324: .  mat - the matrix

326:    Output Parameters:
327: +  missing - is any diagonal missing
328: -  dd - first diagonal entry that is missing (optional)

330:    Level: advanced


333: .seealso: MatRealPart()
334: @*/
335: PetscErrorCode  MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
336: {

342:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
343:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
344:   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
345:   (*mat->ops->missingdiagonal)(mat,missing,dd);
346:   return(0);
347: }

351: /*@C
352:    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
353:    for each row that you get to ensure that your application does
354:    not bleed memory.

356:    Not Collective

358:    Input Parameters:
359: +  mat - the matrix
360: -  row - the row to get

362:    Output Parameters:
363: +  ncols -  if not NULL, the number of nonzeros in the row
364: .  cols - if not NULL, the column numbers
365: -  vals - if not NULL, the values

367:    Notes:
368:    This routine is provided for people who need to have direct access
369:    to the structure of a matrix.  We hope that we provide enough
370:    high-level matrix routines that few users will need it.

372:    MatGetRow() always returns 0-based column indices, regardless of
373:    whether the internal representation is 0-based (default) or 1-based.

375:    For better efficiency, set cols and/or vals to NULL if you do
376:    not wish to extract these quantities.

378:    The user can only examine the values extracted with MatGetRow();
379:    the values cannot be altered.  To change the matrix entries, one
380:    must use MatSetValues().

382:    You can only have one call to MatGetRow() outstanding for a particular
383:    matrix at a time, per processor. MatGetRow() can only obtain rows
384:    associated with the given processor, it cannot get rows from the
385:    other processors; for that we suggest using MatGetSubMatrices(), then
386:    MatGetRow() on the submatrix. The row indix passed to MatGetRows()
387:    is in the global number of rows.

389:    Fortran Notes:
390:    The calling sequence from Fortran is
391: .vb
392:    MatGetRow(matrix,row,ncols,cols,values,ierr)
393:          Mat     matrix (input)
394:          integer row    (input)
395:          integer ncols  (output)
396:          integer cols(maxcols) (output)
397:          double precision (or double complex) values(maxcols) output
398: .ve
399:    where maxcols >= maximum nonzeros in any row of the matrix.


402:    Caution:
403:    Do not try to change the contents of the output arrays (cols and vals).
404:    In some cases, this may corrupt the matrix.

406:    Level: advanced

408:    Concepts: matrices^row access

410: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
411: @*/
412: PetscErrorCode  MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
413: {
415:   PetscInt       incols;

420:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
421:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
422:   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
423:   MatCheckPreallocated(mat,1);
424:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
425:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
426:   if (ncols) *ncols = incols;
427:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
428:   return(0);
429: }

433: /*@
434:    MatConjugate - replaces the matrix values with their complex conjugates

436:    Logically Collective on Mat

438:    Input Parameters:
439: .  mat - the matrix

441:    Level: advanced

443: .seealso:  VecConjugate()
444: @*/
445: PetscErrorCode  MatConjugate(Mat mat)
446: {
447: #if defined(PETSC_USE_COMPLEX)

452:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
453:   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
454:   (*mat->ops->conjugate)(mat);
455: #if defined(PETSC_HAVE_CUSP)
456:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
457:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
458:   }
459: #endif
460: #if defined(PETSC_HAVE_VIENNACL)
461:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
462:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
463:   }
464: #endif
465:   return(0);
466: #else
467:   return 0;
468: #endif
469: }

473: /*@C
474:    MatRestoreRow - Frees any temporary space allocated by MatGetRow().

476:    Not Collective

478:    Input Parameters:
479: +  mat - the matrix
480: .  row - the row to get
481: .  ncols, cols - the number of nonzeros and their columns
482: -  vals - if nonzero the column values

484:    Notes:
485:    This routine should be called after you have finished examining the entries.

487:    This routine zeros out ncols, cols, and vals. This is to prevent accidental
488:    us of the array after it has been restored. If you pass NULL, it will
489:    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.

491:    Fortran Notes:
492:    The calling sequence from Fortran is
493: .vb
494:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
495:       Mat     matrix (input)
496:       integer row    (input)
497:       integer ncols  (output)
498:       integer cols(maxcols) (output)
499:       double precision (or double complex) values(maxcols) output
500: .ve
501:    Where maxcols >= maximum nonzeros in any row of the matrix.

503:    In Fortran MatRestoreRow() MUST be called after MatGetRow()
504:    before another call to MatGetRow() can be made.

506:    Level: advanced

508: .seealso:  MatGetRow()
509: @*/
510: PetscErrorCode  MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
511: {

517:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
518:   if (!mat->ops->restorerow) return(0);
519:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
520:   if (ncols) *ncols = 0;
521:   if (cols)  *cols = NULL;
522:   if (vals)  *vals = NULL;
523:   return(0);
524: }

528: /*@
529:    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
530:    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.

532:    Not Collective

534:    Input Parameters:
535: +  mat - the matrix

537:    Notes:
538:    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.

540:    Level: advanced

542:    Concepts: matrices^row access

544: .seealso: MatRestoreRowRowUpperTriangular()
545: @*/
546: PetscErrorCode  MatGetRowUpperTriangular(Mat mat)
547: {

553:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
554:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
555:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
556:   MatCheckPreallocated(mat,1);
557:   (*mat->ops->getrowuppertriangular)(mat);
558:   return(0);
559: }

563: /*@
564:    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.

566:    Not Collective

568:    Input Parameters:
569: +  mat - the matrix

571:    Notes:
572:    This routine should be called after you have finished MatGetRow/MatRestoreRow().


575:    Level: advanced

577: .seealso:  MatGetRowUpperTriangular()
578: @*/
579: PetscErrorCode  MatRestoreRowUpperTriangular(Mat mat)
580: {

585:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
586:   if (!mat->ops->restorerowuppertriangular) return(0);
587:   (*mat->ops->restorerowuppertriangular)(mat);
588:   return(0);
589: }

593: /*@C
594:    MatSetOptionsPrefix - Sets the prefix used for searching for all
595:    Mat options in the database.

597:    Logically Collective on Mat

599:    Input Parameter:
600: +  A - the Mat context
601: -  prefix - the prefix to prepend to all option names

603:    Notes:
604:    A hyphen (-) must NOT be given at the beginning of the prefix name.
605:    The first character of all runtime options is AUTOMATICALLY the hyphen.

607:    Level: advanced

609: .keywords: Mat, set, options, prefix, database

611: .seealso: MatSetFromOptions()
612: @*/
613: PetscErrorCode  MatSetOptionsPrefix(Mat A,const char prefix[])
614: {

619:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
620:   return(0);
621: }

625: /*@C
626:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
627:    Mat options in the database.

629:    Logically Collective on Mat

631:    Input Parameters:
632: +  A - the Mat context
633: -  prefix - the prefix to prepend to all option names

635:    Notes:
636:    A hyphen (-) must NOT be given at the beginning of the prefix name.
637:    The first character of all runtime options is AUTOMATICALLY the hyphen.

639:    Level: advanced

641: .keywords: Mat, append, options, prefix, database

643: .seealso: MatGetOptionsPrefix()
644: @*/
645: PetscErrorCode  MatAppendOptionsPrefix(Mat A,const char prefix[])
646: {

651:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
652:   return(0);
653: }

657: /*@C
658:    MatGetOptionsPrefix - Sets the prefix used for searching for all
659:    Mat options in the database.

661:    Not Collective

663:    Input Parameter:
664: .  A - the Mat context

666:    Output Parameter:
667: .  prefix - pointer to the prefix string used

669:    Notes: On the fortran side, the user should pass in a string 'prefix' of
670:    sufficient length to hold the prefix.

672:    Level: advanced

674: .keywords: Mat, get, options, prefix, database

676: .seealso: MatAppendOptionsPrefix()
677: @*/
678: PetscErrorCode  MatGetOptionsPrefix(Mat A,const char *prefix[])
679: {

684:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
685:   return(0);
686: }

690: /*@
691:    MatSetUp - Sets up the internal matrix data structures for the later use.

693:    Collective on Mat

695:    Input Parameters:
696: .  A - the Mat context

698:    Notes:
699:    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.

701:    If a suitable preallocation routine is used, this function does not need to be called.

703:    See the Performance chapter of the PETSc users manual for how to preallocate matrices

705:    Level: beginner

707: .keywords: Mat, setup

709: .seealso: MatCreate(), MatDestroy()
710: @*/
711: PetscErrorCode  MatSetUp(Mat A)
712: {
713:   PetscMPIInt    size;

718:   if (!((PetscObject)A)->type_name) {
719:     MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
720:     if (size == 1) {
721:       MatSetType(A, MATSEQAIJ);
722:     } else {
723:       MatSetType(A, MATMPIAIJ);
724:     }
725:   }
726:   if (!A->preallocated && A->ops->setup) {
727:     PetscInfo(A,"Warning not preallocating matrix storage\n");
728:     (*A->ops->setup)(A);
729:   }
730:   A->preallocated = PETSC_TRUE;
731:   return(0);
732: }

734: #if defined(PETSC_HAVE_SAWS)
735: #include <petscviewersaws.h>
736: #endif
739: /*@C
740:    MatView - Visualizes a matrix object.

742:    Collective on Mat

744:    Input Parameters:
745: +  mat - the matrix
746: -  viewer - visualization context

748:   Notes:
749:   The available visualization contexts include
750: +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
751: .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
752:         output where only the first processor opens
753:         the file.  All other processors send their
754:         data to the first processor to print.
755: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

757:    The user can open alternative visualization contexts with
758: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
759: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
760:          specified file; corresponding input uses MatLoad()
761: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
762:          an X window display
763: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
764:          Currently only the sequential dense and AIJ
765:          matrix types support the Socket viewer.

767:    The user can call PetscViewerSetFormat() to specify the output
768:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
769:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
770: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
771: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
772: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
773: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
774:          format common among all matrix types
775: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
776:          format (which is in many cases the same as the default)
777: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
778:          size and structure (not the matrix entries)
779: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
780:          the matrix structure

782:    Options Database Keys:
783: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
784: .  -mat_view ::ascii_info_detail - Prints more detailed info
785: .  -mat_view - Prints matrix in ASCII format
786: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
787: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
788: .  -display <name> - Sets display name (default is host)
789: .  -draw_pause <sec> - Sets number of seconds to pause after display
790: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 10 Using MATLAB with PETSc for details)
791: .  -viewer_socket_machine <machine>
792: .  -viewer_socket_port <port>
793: .  -mat_view binary - save matrix to file in binary format
794: -  -viewer_binary_filename <name>
795:    Level: beginner

797:    Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
798:       viewer is used.

800:       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
801:       viewer is used.

803:       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
804:       And then use the following mouse functions:
805:           left mouse: zoom in
806:           middle mouse: zoom out
807:           right mouse: continue with the simulation

809:    Concepts: matrices^viewing
810:    Concepts: matrices^plotting
811:    Concepts: matrices^printing

813: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
814:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
815: @*/
816: PetscErrorCode  MatView(Mat mat,PetscViewer viewer)
817: {
818:   PetscErrorCode    ierr;
819:   PetscInt          rows,cols,bs;
820:   PetscBool         iascii;
821:   PetscViewerFormat format;
822: #if defined(PETSC_HAVE_SAWS)
823:   PetscBool         isams;
824: #endif

829:   if (!viewer) {
830:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
831:   }
834:   MatCheckPreallocated(mat,1);

836:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
837:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
838:   PetscViewerGetFormat(viewer,&format);
839:   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
840:     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
841:   }

843: #if defined(PETSC_HAVE_SAWS)
844:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&isams);
845: #endif
846:   if (iascii) {
847:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
848:     PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
849:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
850:       PetscViewerASCIIPushTab(viewer);
851:       MatGetSize(mat,&rows,&cols);
852:       MatGetBlockSize(mat,&bs);
853:       if (bs != 1) {
854:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,bs);
855:       } else {
856:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
857:       }
858:       if (mat->factortype) {
859:         const MatSolverPackage solver;
860:         MatFactorGetSolverPackage(mat,&solver);
861:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
862:       }
863:       if (mat->ops->getinfo) {
864:         MatInfo info;
865:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
866:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%g, allocated nonzeros=%g\n",info.nz_used,info.nz_allocated);
867:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
868:       }
869:       if (mat->nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached null space\n");}
870:       if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");}
871:     }
872: #if defined(PETSC_HAVE_SAWS)
873:   } else if (isams) {
874:     PetscMPIInt rank;

876:     PetscObjectName((PetscObject)mat);
877:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
878:     if (!((PetscObject)mat)->amsmem && !rank) {
879:       PetscObjectViewSAWs((PetscObject)mat,viewer);
880:     }
881: #endif
882:   }
883:   if (mat->ops->view) {
884:     PetscViewerASCIIPushTab(viewer);
885:     (*mat->ops->view)(mat,viewer);
886:     PetscViewerASCIIPopTab(viewer);
887:   }
888:   if (iascii) {
889:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
890:     PetscViewerGetFormat(viewer,&format);
891:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
892:       PetscViewerASCIIPopTab(viewer);
893:     }
894:   }
895:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
896:   return(0);
897: }

899: #if defined(PETSC_USE_DEBUG)
900: #include <../src/sys/totalview/tv_data_display.h>
901: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
902: {
903:   TV_add_row("Local rows", "int", &mat->rmap->n);
904:   TV_add_row("Local columns", "int", &mat->cmap->n);
905:   TV_add_row("Global rows", "int", &mat->rmap->N);
906:   TV_add_row("Global columns", "int", &mat->cmap->N);
907:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
908:   return TV_format_OK;
909: }
910: #endif

914: /*@C
915:    MatLoad - Loads a matrix that has been stored in binary format
916:    with MatView().  The matrix format is determined from the options database.
917:    Generates a parallel MPI matrix if the communicator has more than one
918:    processor.  The default matrix type is AIJ.

920:    Collective on PetscViewer

922:    Input Parameters:
923: +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
924:             or some related function before a call to MatLoad()
925: -  viewer - binary file viewer, created with PetscViewerBinaryOpen()

927:    Options Database Keys:
928:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
929:    block size
930: .    -matload_block_size <bs>

932:    Level: beginner

934:    Notes:
935:    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
936:    Mat before calling this routine if you wish to set it from the options database.

938:    MatLoad() automatically loads into the options database any options
939:    given in the file filename.info where filename is the name of the file
940:    that was passed to the PetscViewerBinaryOpen(). The options in the info
941:    file will be ignored if you use the -viewer_binary_skip_info option.

943:    If the type or size of newmat is not set before a call to MatLoad, PETSc
944:    sets the default matrix type AIJ and sets the local and global sizes.
945:    If type and/or size is already set, then the same are used.

947:    In parallel, each processor can load a subset of rows (or the
948:    entire matrix).  This routine is especially useful when a large
949:    matrix is stored on disk and only part of it is desired on each
950:    processor.  For example, a parallel solver may access only some of
951:    the rows from each processor.  The algorithm used here reads
952:    relatively small blocks of data rather than reading the entire
953:    matrix and then subsetting it.

955:    Notes for advanced users:
956:    Most users should not need to know the details of the binary storage
957:    format, since MatLoad() and MatView() completely hide these details.
958:    But for anyone who's interested, the standard binary matrix storage
959:    format is

961: $    int    MAT_FILE_CLASSID
962: $    int    number of rows
963: $    int    number of columns
964: $    int    total number of nonzeros
965: $    int    *number nonzeros in each row
966: $    int    *column indices of all nonzeros (starting index is zero)
967: $    PetscScalar *values of all nonzeros

969:    PETSc automatically does the byte swapping for
970: machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
971: linux, Windows and the paragon; thus if you write your own binary
972: read/write routines you have to swap the bytes; see PetscBinaryRead()
973: and PetscBinaryWrite() to see how this may be done.

975: .keywords: matrix, load, binary, input

977: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()

979:  @*/
980: PetscErrorCode  MatLoad(Mat newmat,PetscViewer viewer)
981: {
983:   PetscBool      isbinary,flg;

988:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
989:   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");

991:   if (!((PetscObject)newmat)->type_name) {
992:     MatSetType(newmat,MATAIJ);
993:   }

995:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
996:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
997:   (*newmat->ops->load)(newmat,viewer);
998:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

1000:   flg  = PETSC_FALSE;
1001:   PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1002:   if (flg) {
1003:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1004:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1005:   }
1006:   flg  = PETSC_FALSE;
1007:   PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1008:   if (flg) {
1009:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1010:   }
1011:   return(0);
1012: }

1016: /*@
1017:    MatDestroy - Frees space taken by a matrix.

1019:    Collective on Mat

1021:    Input Parameter:
1022: .  A - the matrix

1024:    Level: beginner

1026: @*/
1027: PetscErrorCode  MatDestroy(Mat *A)
1028: {

1032:   if (!*A) return(0);
1034:   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; return(0);}

1036:   /* if memory was published with SAWs then destroy it */
1037:   PetscObjectSAWsViewOff((PetscObject)*A);
1038:   if ((*A)->ops->destroy) {
1039:     (*(*A)->ops->destroy)(*A);
1040:   }
1041:   MatNullSpaceDestroy(&(*A)->nullsp);
1042:   MatNullSpaceDestroy(&(*A)->nearnullsp);
1043:   PetscLayoutDestroy(&(*A)->rmap);
1044:   PetscLayoutDestroy(&(*A)->cmap);
1045:   PetscHeaderDestroy(A);
1046:   return(0);
1047: }

1051: /*@
1052:    MatSetValues - Inserts or adds a block of values into a matrix.
1053:    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1054:    MUST be called after all calls to MatSetValues() have been completed.

1056:    Not Collective

1058:    Input Parameters:
1059: +  mat - the matrix
1060: .  v - a logically two-dimensional array of values
1061: .  m, idxm - the number of rows and their global indices
1062: .  n, idxn - the number of columns and their global indices
1063: -  addv - either ADD_VALUES or INSERT_VALUES, where
1064:    ADD_VALUES adds values to any existing entries, and
1065:    INSERT_VALUES replaces existing entries with new values

1067:    Notes:
1068:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1069:       MatSetUp() before using this routine

1071:    By default the values, v, are row-oriented. See MatSetOption() for other options.

1073:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1074:    options cannot be mixed without intervening calls to the assembly
1075:    routines.

1077:    MatSetValues() uses 0-based row and column numbers in Fortran
1078:    as well as in C.

1080:    Negative indices may be passed in idxm and idxn, these rows and columns are
1081:    simply ignored. This allows easily inserting element stiffness matrices
1082:    with homogeneous Dirchlet boundary conditions that you don't want represented
1083:    in the matrix.

1085:    Efficiency Alert:
1086:    The routine MatSetValuesBlocked() may offer much better efficiency
1087:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1089:    Level: beginner

1091:    Concepts: matrices^putting entries in

1093: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1094:           InsertMode, INSERT_VALUES, ADD_VALUES
1095: @*/
1096: PetscErrorCode  MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1097: {
1099: #if defined(PETSC_USE_DEBUG)
1100:   PetscInt       i,j;
1101: #endif

1106:   if (!m || !n) return(0); /* no values to insert */
1110:   MatCheckPreallocated(mat,1);
1111:   if (mat->insertmode == NOT_SET_VALUES) {
1112:     mat->insertmode = addv;
1113:   }
1114: #if defined(PETSC_USE_DEBUG)
1115:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1116:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1117:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);

1119:   for (i=0; i<m; i++) {
1120:     for (j=0; j<n; j++) {
1121:       if (PetscIsInfOrNanScalar(v[i*n+j]))
1122: #if defined(PETSC_USE_COMPLEX)
1123:         SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1124: #else
1125:       SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1126: #endif
1127:     }
1128:   }
1129: #endif

1131:   if (mat->assembled) {
1132:     mat->was_assembled = PETSC_TRUE;
1133:     mat->assembled     = PETSC_FALSE;
1134:   }
1135:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1136:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1137:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1138: #if defined(PETSC_HAVE_CUSP)
1139:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1140:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1141:   }
1142: #endif
1143: #if defined(PETSC_HAVE_VIENNACL)
1144:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1145:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1146:   }
1147: #endif
1148:   return(0);
1149: }


1154: /*@
1155:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1156:         values into a matrix

1158:    Not Collective

1160:    Input Parameters:
1161: +  mat - the matrix
1162: .  row - the (block) row to set
1163: -  v - a logically two-dimensional array of values

1165:    Notes:
1166:    By the values, v, are column-oriented (for the block version) and sorted

1168:    All the nonzeros in the row must be provided

1170:    The matrix must have previously had its column indices set

1172:    The row must belong to this process

1174:    Level: intermediate

1176:    Concepts: matrices^putting entries in

1178: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1179:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1180: @*/
1181: PetscErrorCode  MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1182: {
1184:   PetscInt       globalrow;

1190:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1191:   MatSetValuesRow(mat,globalrow,v);
1192: #if defined(PETSC_HAVE_CUSP)
1193:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1194:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1195:   }
1196: #endif
1197: #if defined(PETSC_HAVE_VIENNACL)
1198:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1199:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1200:   }
1201: #endif
1202:   return(0);
1203: }

1207: /*@
1208:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1209:         values into a matrix

1211:    Not Collective

1213:    Input Parameters:
1214: +  mat - the matrix
1215: .  row - the (block) row to set
1216: -  v - a logically two-dimensional array of values

1218:    Notes:
1219:    The values, v, are column-oriented for the block version.

1221:    All the nonzeros in the row must be provided

1223:    THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.

1225:    The row must belong to this process

1227:    Level: advanced

1229:    Concepts: matrices^putting entries in

1231: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1232:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1233: @*/
1234: PetscErrorCode  MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1235: {

1241:   MatCheckPreallocated(mat,1);
1243: #if defined(PETSC_USE_DEBUG)
1244:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1245:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1246: #endif
1247:   mat->insertmode = INSERT_VALUES;

1249:   if (mat->assembled) {
1250:     mat->was_assembled = PETSC_TRUE;
1251:     mat->assembled     = PETSC_FALSE;
1252:   }
1253:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1254:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1255:   (*mat->ops->setvaluesrow)(mat,row,v);
1256:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1257: #if defined(PETSC_HAVE_CUSP)
1258:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1259:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1260:   }
1261: #endif
1262: #if defined(PETSC_HAVE_VIENNACL)
1263:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1264:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1265:   }
1266: #endif
1267:   return(0);
1268: }

1272: /*@
1273:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1274:      Using structured grid indexing

1276:    Not Collective

1278:    Input Parameters:
1279: +  mat - the matrix
1280: .  m - number of rows being entered
1281: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1282: .  n - number of columns being entered
1283: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1284: .  v - a logically two-dimensional array of values
1285: -  addv - either ADD_VALUES or INSERT_VALUES, where
1286:    ADD_VALUES adds values to any existing entries, and
1287:    INSERT_VALUES replaces existing entries with new values

1289:    Notes:
1290:    By default the values, v, are row-oriented.  See MatSetOption() for other options.

1292:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1293:    options cannot be mixed without intervening calls to the assembly
1294:    routines.

1296:    The grid coordinates are across the entire grid, not just the local portion

1298:    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1299:    as well as in C.

1301:    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine

1303:    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1304:    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.

1306:    The columns and rows in the stencil passed in MUST be contained within the
1307:    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1308:    if you create a DMDA with an overlap of one grid level and on a particular process its first
1309:    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1310:    first i index you can use in your column and row indices in MatSetStencil() is 5.

1312:    In Fortran idxm and idxn should be declared as
1313: $     MatStencil idxm(4,m),idxn(4,n)
1314:    and the values inserted using
1315: $    idxm(MatStencil_i,1) = i
1316: $    idxm(MatStencil_j,1) = j
1317: $    idxm(MatStencil_k,1) = k
1318: $    idxm(MatStencil_c,1) = c
1319:    etc

1321:    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1322:    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1323:    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1324:    DM_BOUNDARY_PERIODIC boundary type.

1326:    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1327:    a single value per point) you can skip filling those indices.

1329:    Inspired by the structured grid interface to the HYPRE package
1330:    (http://www.llnl.gov/CASC/hypre)

1332:    Efficiency Alert:
1333:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1334:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1336:    Level: beginner

1338:    Concepts: matrices^putting entries in

1340: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1341:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1342: @*/
1343: PetscErrorCode  MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1344: {
1346:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1347:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1348:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

1351:   if (!m || !n) return(0); /* no values to insert */

1358:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1359:     jdxm = buf; jdxn = buf+m;
1360:   } else {
1361:     PetscMalloc2(m,&bufm,n,&bufn);
1362:     jdxm = bufm; jdxn = bufn;
1363:   }
1364:   for (i=0; i<m; i++) {
1365:     for (j=0; j<3-sdim; j++) dxm++;
1366:     tmp = *dxm++ - starts[0];
1367:     for (j=0; j<dim-1; j++) {
1368:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1369:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1370:     }
1371:     if (mat->stencil.noc) dxm++;
1372:     jdxm[i] = tmp;
1373:   }
1374:   for (i=0; i<n; i++) {
1375:     for (j=0; j<3-sdim; j++) dxn++;
1376:     tmp = *dxn++ - starts[0];
1377:     for (j=0; j<dim-1; j++) {
1378:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1379:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1380:     }
1381:     if (mat->stencil.noc) dxn++;
1382:     jdxn[i] = tmp;
1383:   }
1384:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1385:   PetscFree2(bufm,bufn);
1386:   return(0);
1387: }

1391: /*@
1392:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1393:      Using structured grid indexing

1395:    Not Collective

1397:    Input Parameters:
1398: +  mat - the matrix
1399: .  m - number of rows being entered
1400: .  idxm - grid coordinates for matrix rows being entered
1401: .  n - number of columns being entered
1402: .  idxn - grid coordinates for matrix columns being entered
1403: .  v - a logically two-dimensional array of values
1404: -  addv - either ADD_VALUES or INSERT_VALUES, where
1405:    ADD_VALUES adds values to any existing entries, and
1406:    INSERT_VALUES replaces existing entries with new values

1408:    Notes:
1409:    By default the values, v, are row-oriented and unsorted.
1410:    See MatSetOption() for other options.

1412:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1413:    options cannot be mixed without intervening calls to the assembly
1414:    routines.

1416:    The grid coordinates are across the entire grid, not just the local portion

1418:    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1419:    as well as in C.

1421:    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine

1423:    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1424:    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.

1426:    The columns and rows in the stencil passed in MUST be contained within the
1427:    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1428:    if you create a DMDA with an overlap of one grid level and on a particular process its first
1429:    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1430:    first i index you can use in your column and row indices in MatSetStencil() is 5.

1432:    In Fortran idxm and idxn should be declared as
1433: $     MatStencil idxm(4,m),idxn(4,n)
1434:    and the values inserted using
1435: $    idxm(MatStencil_i,1) = i
1436: $    idxm(MatStencil_j,1) = j
1437: $    idxm(MatStencil_k,1) = k
1438:    etc

1440:    Negative indices may be passed in idxm and idxn, these rows and columns are
1441:    simply ignored. This allows easily inserting element stiffness matrices
1442:    with homogeneous Dirchlet boundary conditions that you don't want represented
1443:    in the matrix.

1445:    Inspired by the structured grid interface to the HYPRE package
1446:    (http://www.llnl.gov/CASC/hypre)

1448:    Level: beginner

1450:    Concepts: matrices^putting entries in

1452: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1453:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1454:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1455: @*/
1456: PetscErrorCode  MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1457: {
1459:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1460:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1461:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

1464:   if (!m || !n) return(0); /* no values to insert */

1471:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1472:     jdxm = buf; jdxn = buf+m;
1473:   } else {
1474:     PetscMalloc2(m,&bufm,n,&bufn);
1475:     jdxm = bufm; jdxn = bufn;
1476:   }
1477:   for (i=0; i<m; i++) {
1478:     for (j=0; j<3-sdim; j++) dxm++;
1479:     tmp = *dxm++ - starts[0];
1480:     for (j=0; j<sdim-1; j++) {
1481:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1482:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1483:     }
1484:     dxm++;
1485:     jdxm[i] = tmp;
1486:   }
1487:   for (i=0; i<n; i++) {
1488:     for (j=0; j<3-sdim; j++) dxn++;
1489:     tmp = *dxn++ - starts[0];
1490:     for (j=0; j<sdim-1; j++) {
1491:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1492:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1493:     }
1494:     dxn++;
1495:     jdxn[i] = tmp;
1496:   }
1497:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1498:   PetscFree2(bufm,bufn);
1499: #if defined(PETSC_HAVE_CUSP)
1500:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1501:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1502:   }
1503: #endif
1504: #if defined(PETSC_HAVE_VIENNACL)
1505:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1506:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1507:   }
1508: #endif
1509:   return(0);
1510: }

1514: /*@
1515:    MatSetStencil - Sets the grid information for setting values into a matrix via
1516:         MatSetValuesStencil()

1518:    Not Collective

1520:    Input Parameters:
1521: +  mat - the matrix
1522: .  dim - dimension of the grid 1, 2, or 3
1523: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1524: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1525: -  dof - number of degrees of freedom per node


1528:    Inspired by the structured grid interface to the HYPRE package
1529:    (www.llnl.gov/CASC/hyper)

1531:    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1532:    user.

1534:    Level: beginner

1536:    Concepts: matrices^putting entries in

1538: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1539:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1540: @*/
1541: PetscErrorCode  MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1542: {
1543:   PetscInt i;


1550:   mat->stencil.dim = dim + (dof > 1);
1551:   for (i=0; i<dim; i++) {
1552:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1553:     mat->stencil.starts[i] = starts[dim-i-1];
1554:   }
1555:   mat->stencil.dims[dim]   = dof;
1556:   mat->stencil.starts[dim] = 0;
1557:   mat->stencil.noc         = (PetscBool)(dof == 1);
1558:   return(0);
1559: }

1563: /*@
1564:    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.

1566:    Not Collective

1568:    Input Parameters:
1569: +  mat - the matrix
1570: .  v - a logically two-dimensional array of values
1571: .  m, idxm - the number of block rows and their global block indices
1572: .  n, idxn - the number of block columns and their global block indices
1573: -  addv - either ADD_VALUES or INSERT_VALUES, where
1574:    ADD_VALUES adds values to any existing entries, and
1575:    INSERT_VALUES replaces existing entries with new values

1577:    Notes:
1578:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1579:    MatXXXXSetPreallocation() or MatSetUp() before using this routine.

1581:    The m and n count the NUMBER of blocks in the row direction and column direction,
1582:    NOT the total number of rows/columns; for example, if the block size is 2 and
1583:    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1584:    The values in idxm would be 1 2; that is the first index for each block divided by
1585:    the block size.

1587:    Note that you must call MatSetBlockSize() when constructing this matrix (after
1588:    preallocating it).

1590:    By default the values, v, are row-oriented, so the layout of
1591:    v is the same as for MatSetValues(). See MatSetOption() for other options.

1593:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1594:    options cannot be mixed without intervening calls to the assembly
1595:    routines.

1597:    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1598:    as well as in C.

1600:    Negative indices may be passed in idxm and idxn, these rows and columns are
1601:    simply ignored. This allows easily inserting element stiffness matrices
1602:    with homogeneous Dirchlet boundary conditions that you don't want represented
1603:    in the matrix.

1605:    Each time an entry is set within a sparse matrix via MatSetValues(),
1606:    internal searching must be done to determine where to place the the
1607:    data in the matrix storage space.  By instead inserting blocks of
1608:    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1609:    reduced.

1611:    Example:
1612: $   Suppose m=n=2 and block size(bs) = 2 The array is
1613: $
1614: $   1  2  | 3  4
1615: $   5  6  | 7  8
1616: $   - - - | - - -
1617: $   9  10 | 11 12
1618: $   13 14 | 15 16
1619: $
1620: $   v[] should be passed in like
1621: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1622: $
1623: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1624: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

1626:    Level: intermediate

1628:    Concepts: matrices^putting entries in blocked

1630: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1631: @*/
1632: PetscErrorCode  MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1633: {

1639:   if (!m || !n) return(0); /* no values to insert */
1643:   MatCheckPreallocated(mat,1);
1644:   if (mat->insertmode == NOT_SET_VALUES) {
1645:     mat->insertmode = addv;
1646:   }
1647: #if defined(PETSC_USE_DEBUG)
1648:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1649:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1650:   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1651: #endif

1653:   if (mat->assembled) {
1654:     mat->was_assembled = PETSC_TRUE;
1655:     mat->assembled     = PETSC_FALSE;
1656:   }
1657:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1658:   if (mat->ops->setvaluesblocked) {
1659:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1660:   } else {
1661:     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1662:     PetscInt i,j,bs,cbs;
1663:     MatGetBlockSizes(mat,&bs,&cbs);
1664:     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1665:       iidxm = buf; iidxn = buf + m*bs;
1666:     } else {
1667:       PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1668:       iidxm = bufr; iidxn = bufc;
1669:     }
1670:     for (i=0; i<m; i++) {
1671:       for (j=0; j<bs; j++) {
1672:         iidxm[i*bs+j] = bs*idxm[i] + j;
1673:       }
1674:     }
1675:     for (i=0; i<n; i++) {
1676:       for (j=0; j<cbs; j++) {
1677:         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1678:       }
1679:     }
1680:     MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1681:     PetscFree2(bufr,bufc);
1682:   }
1683:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1684: #if defined(PETSC_HAVE_CUSP)
1685:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1686:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1687:   }
1688: #endif
1689: #if defined(PETSC_HAVE_VIENNACL)
1690:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1691:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1692:   }
1693: #endif
1694:   return(0);
1695: }

1699: /*@
1700:    MatGetValues - Gets a block of values from a matrix.

1702:    Not Collective; currently only returns a local block

1704:    Input Parameters:
1705: +  mat - the matrix
1706: .  v - a logically two-dimensional array for storing the values
1707: .  m, idxm - the number of rows and their global indices
1708: -  n, idxn - the number of columns and their global indices

1710:    Notes:
1711:    The user must allocate space (m*n PetscScalars) for the values, v.
1712:    The values, v, are then returned in a row-oriented format,
1713:    analogous to that used by default in MatSetValues().

1715:    MatGetValues() uses 0-based row and column numbers in
1716:    Fortran as well as in C.

1718:    MatGetValues() requires that the matrix has been assembled
1719:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1720:    MatSetValues() and MatGetValues() CANNOT be made in succession
1721:    without intermediate matrix assembly.

1723:    Negative row or column indices will be ignored and those locations in v[] will be
1724:    left unchanged.

1726:    Level: advanced

1728:    Concepts: matrices^accessing values

1730: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1731: @*/
1732: PetscErrorCode  MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1733: {

1739:   if (!m || !n) return(0);
1743:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1744:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1745:   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1746:   MatCheckPreallocated(mat,1);

1748:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1749:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1750:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1751:   return(0);
1752: }

1756: /*@
1757:   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1758:   the same size. Currently, this can only be called once and creates the given matrix.

1760:   Not Collective

1762:   Input Parameters:
1763: + mat - the matrix
1764: . nb - the number of blocks
1765: . bs - the number of rows (and columns) in each block
1766: . rows - a concatenation of the rows for each block
1767: - v - a concatenation of logically two-dimensional arrays of values

1769:   Notes:
1770:   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.

1772:   Level: advanced

1774:   Concepts: matrices^putting entries in

1776: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1777:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1778: @*/
1779: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1780: {

1788: #if defined(PETSC_USE_DEBUG)
1789:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1790: #endif

1792:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1793:   if (mat->ops->setvaluesbatch) {
1794:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1795:   } else {
1796:     PetscInt b;
1797:     for (b = 0; b < nb; ++b) {
1798:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1799:     }
1800:   }
1801:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1802:   return(0);
1803: }

1807: /*@
1808:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1809:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1810:    using a local (per-processor) numbering.

1812:    Not Collective

1814:    Input Parameters:
1815: +  x - the matrix
1816: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1817: - cmapping - column mapping

1819:    Level: intermediate

1821:    Concepts: matrices^local to global mapping
1822:    Concepts: local to global mapping^for matrices

1824: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1825: @*/
1826: PetscErrorCode  MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1827: {


1836:   if (x->ops->setlocaltoglobalmapping) {
1837:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1838:   } else {
1839:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1840:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1841:   }
1842:   return(0);
1843: }


1848: /*@
1849:    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()

1851:    Not Collective

1853:    Input Parameters:
1854: .  A - the matrix

1856:    Output Parameters:
1857: + rmapping - row mapping
1858: - cmapping - column mapping

1860:    Level: advanced

1862:    Concepts: matrices^local to global mapping
1863:    Concepts: local to global mapping^for matrices

1865: .seealso:  MatSetValuesLocal()
1866: @*/
1867: PetscErrorCode  MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1868: {
1874:   if (rmapping) *rmapping = A->rmap->mapping;
1875:   if (cmapping) *cmapping = A->cmap->mapping;
1876:   return(0);
1877: }

1881: /*@
1882:    MatGetLayouts - Gets the PetscLayout objects for rows and columns

1884:    Not Collective

1886:    Input Parameters:
1887: .  A - the matrix

1889:    Output Parameters:
1890: + rmap - row layout
1891: - cmap - column layout

1893:    Level: advanced

1895: .seealso:  MatGetVecs(), MatGetLocalToGlobalMapping()
1896: @*/
1897: PetscErrorCode  MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1898: {
1904:   if (rmap) *rmap = A->rmap;
1905:   if (cmap) *cmap = A->cmap;
1906:   return(0);
1907: }

1911: /*@
1912:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1913:    using a local ordering of the nodes.

1915:    Not Collective

1917:    Input Parameters:
1918: +  x - the matrix
1919: .  nrow, irow - number of rows and their local indices
1920: .  ncol, icol - number of columns and their local indices
1921: .  y -  a logically two-dimensional array of values
1922: -  addv - either INSERT_VALUES or ADD_VALUES, where
1923:    ADD_VALUES adds values to any existing entries, and
1924:    INSERT_VALUES replaces existing entries with new values

1926:    Notes:
1927:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1928:       MatSetUp() before using this routine

1930:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine

1932:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1933:    options cannot be mixed without intervening calls to the assembly
1934:    routines.

1936:    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1937:    MUST be called after all calls to MatSetValuesLocal() have been completed.

1939:    Level: intermediate

1941:    Concepts: matrices^putting entries in with local numbering

1943: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1944:            MatSetValueLocal()
1945: @*/
1946: PetscErrorCode  MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1947: {

1953:   MatCheckPreallocated(mat,1);
1954:   if (!nrow || !ncol) return(0); /* no values to insert */
1958:   if (mat->insertmode == NOT_SET_VALUES) {
1959:     mat->insertmode = addv;
1960:   }
1961: #if defined(PETSC_USE_DEBUG)
1962:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1963:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1964:   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1965: #endif

1967:   if (mat->assembled) {
1968:     mat->was_assembled = PETSC_TRUE;
1969:     mat->assembled     = PETSC_FALSE;
1970:   }
1971:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1972:   if (mat->ops->setvalueslocal) {
1973:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1974:   } else {
1975:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1976:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1977:       irowm = buf; icolm = buf+nrow;
1978:     } else {
1979:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
1980:       irowm = bufr; icolm = bufc;
1981:     }
1982:     ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
1983:     ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
1984:     MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
1985:     PetscFree2(bufr,bufc);
1986:   }
1987:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1988: #if defined(PETSC_HAVE_CUSP)
1989:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1990:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1991:   }
1992: #endif
1993: #if defined(PETSC_HAVE_VIENNACL)
1994:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1995:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1996:   }
1997: #endif
1998:   return(0);
1999: }

2003: /*@
2004:    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2005:    using a local ordering of the nodes a block at a time.

2007:    Not Collective

2009:    Input Parameters:
2010: +  x - the matrix
2011: .  nrow, irow - number of rows and their local indices
2012: .  ncol, icol - number of columns and their local indices
2013: .  y -  a logically two-dimensional array of values
2014: -  addv - either INSERT_VALUES or ADD_VALUES, where
2015:    ADD_VALUES adds values to any existing entries, and
2016:    INSERT_VALUES replaces existing entries with new values

2018:    Notes:
2019:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2020:       MatSetUp() before using this routine

2022:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2023:       before using this routineBefore calling MatSetValuesLocal(), the user must first set the

2025:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2026:    options cannot be mixed without intervening calls to the assembly
2027:    routines.

2029:    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2030:    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.

2032:    Level: intermediate

2034:    Concepts: matrices^putting blocked values in with local numbering

2036: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2037:            MatSetValuesLocal(),  MatSetValuesBlocked()
2038: @*/
2039: PetscErrorCode  MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2040: {

2046:   MatCheckPreallocated(mat,1);
2047:   if (!nrow || !ncol) return(0); /* no values to insert */
2051:   if (mat->insertmode == NOT_SET_VALUES) {
2052:     mat->insertmode = addv;
2053:   }
2054: #if defined(PETSC_USE_DEBUG)
2055:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2056:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2057:   if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2058: #endif

2060:   if (mat->assembled) {
2061:     mat->was_assembled = PETSC_TRUE;
2062:     mat->assembled     = PETSC_FALSE;
2063:   }
2064:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2065:   if (mat->ops->setvaluesblockedlocal) {
2066:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2067:   } else {
2068:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2069:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2070:       irowm = buf; icolm = buf + nrow;
2071:     } else {
2072:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2073:       irowm = bufr; icolm = bufc;
2074:     }
2075:     ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2076:     ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2077:     MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2078:     PetscFree2(bufr,bufc);
2079:   }
2080:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2081: #if defined(PETSC_HAVE_CUSP)
2082:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2083:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2084:   }
2085: #endif
2086: #if defined(PETSC_HAVE_VIENNACL)
2087:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2088:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2089:   }
2090: #endif
2091:   return(0);
2092: }

2096: /*@
2097:    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal

2099:    Collective on Mat and Vec

2101:    Input Parameters:
2102: +  mat - the matrix
2103: -  x   - the vector to be multiplied

2105:    Output Parameters:
2106: .  y - the result

2108:    Notes:
2109:    The vectors x and y cannot be the same.  I.e., one cannot
2110:    call MatMult(A,y,y).

2112:    Level: developer

2114:    Concepts: matrix-vector product

2116: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2117: @*/
2118: PetscErrorCode  MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2119: {


2128:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2129:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2130:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2131:   MatCheckPreallocated(mat,1);

2133:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2134:   (*mat->ops->multdiagonalblock)(mat,x,y);
2135:   PetscObjectStateIncrease((PetscObject)y);
2136:   return(0);
2137: }

2139: /* --------------------------------------------------------*/
2142: /*@
2143:    MatMult - Computes the matrix-vector product, y = Ax.

2145:    Neighbor-wise Collective on Mat and Vec

2147:    Input Parameters:
2148: +  mat - the matrix
2149: -  x   - the vector to be multiplied

2151:    Output Parameters:
2152: .  y - the result

2154:    Notes:
2155:    The vectors x and y cannot be the same.  I.e., one cannot
2156:    call MatMult(A,y,y).

2158:    Level: beginner

2160:    Concepts: matrix-vector product

2162: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2163: @*/
2164: PetscErrorCode  MatMult(Mat mat,Vec x,Vec y)
2165: {

2173:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2174:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2175:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2176: #if !defined(PETSC_HAVE_CONSTRAINTS)
2177:   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2178:   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2179:   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2180: #endif
2181:   VecValidValues(x,2,PETSC_TRUE);
2182:   MatCheckPreallocated(mat,1);

2184:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2185:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2186:   (*mat->ops->mult)(mat,x,y);
2187:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2188:   VecValidValues(y,3,PETSC_FALSE);
2189:   return(0);
2190: }

2194: /*@
2195:    MatMultTranspose - Computes matrix transpose times a vector.

2197:    Neighbor-wise Collective on Mat and Vec

2199:    Input Parameters:
2200: +  mat - the matrix
2201: -  x   - the vector to be multilplied

2203:    Output Parameters:
2204: .  y - the result

2206:    Notes:
2207:    The vectors x and y cannot be the same.  I.e., one cannot
2208:    call MatMultTranspose(A,y,y).

2210:    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2211:    use MatMultHermitianTranspose()

2213:    Level: beginner

2215:    Concepts: matrix vector product^transpose

2217: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2218: @*/
2219: PetscErrorCode  MatMultTranspose(Mat mat,Vec x,Vec y)
2220: {


2229:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2230:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2231:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2232: #if !defined(PETSC_HAVE_CONSTRAINTS)
2233:   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2234:   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2235: #endif
2236:   VecValidValues(x,2,PETSC_TRUE);
2237:   MatCheckPreallocated(mat,1);

2239:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2240:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2241:   (*mat->ops->multtranspose)(mat,x,y);
2242:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2243:   PetscObjectStateIncrease((PetscObject)y);
2244:   VecValidValues(y,3,PETSC_FALSE);
2245:   return(0);
2246: }

2250: /*@
2251:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2253:    Neighbor-wise Collective on Mat and Vec

2255:    Input Parameters:
2256: +  mat - the matrix
2257: -  x   - the vector to be multilplied

2259:    Output Parameters:
2260: .  y - the result

2262:    Notes:
2263:    The vectors x and y cannot be the same.  I.e., one cannot
2264:    call MatMultHermitianTranspose(A,y,y).

2266:    Also called the conjugate transpose, complex conjugate transpose, or adjoint.

2268:    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.

2270:    Level: beginner

2272:    Concepts: matrix vector product^transpose

2274: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2275: @*/
2276: PetscErrorCode  MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2277: {
2279:   Vec            w;


2287:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2288:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2289:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2290: #if !defined(PETSC_HAVE_CONSTRAINTS)
2291:   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2292:   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2293: #endif
2294:   MatCheckPreallocated(mat,1);

2296:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2297:   if (mat->ops->multhermitiantranspose) {
2298:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2299:   } else {
2300:     VecDuplicate(x,&w);
2301:     VecCopy(x,w);
2302:     VecConjugate(w);
2303:     MatMultTranspose(mat,w,y);
2304:     VecDestroy(&w);
2305:     VecConjugate(y);
2306:   }
2307:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2308:   PetscObjectStateIncrease((PetscObject)y);
2309:   return(0);
2310: }

2314: /*@
2315:     MatMultAdd -  Computes v3 = v2 + A * v1.

2317:     Neighbor-wise Collective on Mat and Vec

2319:     Input Parameters:
2320: +   mat - the matrix
2321: -   v1, v2 - the vectors

2323:     Output Parameters:
2324: .   v3 - the result

2326:     Notes:
2327:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2328:     call MatMultAdd(A,v1,v2,v1).

2330:     Level: beginner

2332:     Concepts: matrix vector product^addition

2334: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2335: @*/
2336: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2337: {


2347:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2348:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2349:   if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2350:   /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2351:      if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2352:   if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2353:   if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2354:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2355:   MatCheckPreallocated(mat,1);

2357:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2358:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2359:   (*mat->ops->multadd)(mat,v1,v2,v3);
2360:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2361:   PetscObjectStateIncrease((PetscObject)v3);
2362:   return(0);
2363: }

2367: /*@
2368:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2370:    Neighbor-wise Collective on Mat and Vec

2372:    Input Parameters:
2373: +  mat - the matrix
2374: -  v1, v2 - the vectors

2376:    Output Parameters:
2377: .  v3 - the result

2379:    Notes:
2380:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2381:    call MatMultTransposeAdd(A,v1,v2,v1).

2383:    Level: beginner

2385:    Concepts: matrix vector product^transpose and addition

2387: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2388: @*/
2389: PetscErrorCode  MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2390: {


2400:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2401:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2402:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2403:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2404:   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2405:   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2406:   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2407:   MatCheckPreallocated(mat,1);

2409:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2410:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2411:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2412:   PetscObjectStateIncrease((PetscObject)v3);
2413:   return(0);
2414: }

2418: /*@
2419:    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.

2421:    Neighbor-wise Collective on Mat and Vec

2423:    Input Parameters:
2424: +  mat - the matrix
2425: -  v1, v2 - the vectors

2427:    Output Parameters:
2428: .  v3 - the result

2430:    Notes:
2431:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2432:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2434:    Level: beginner

2436:    Concepts: matrix vector product^transpose and addition

2438: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2439: @*/
2440: PetscErrorCode  MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2441: {


2451:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2452:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2453:   if (!mat->ops->multhermitiantransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2454:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2455:   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2456:   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2457:   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2458:   MatCheckPreallocated(mat,1);

2460:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2461:   (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2462:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2463:   PetscObjectStateIncrease((PetscObject)v3);
2464:   return(0);
2465: }

2469: /*@
2470:    MatMultConstrained - The inner multiplication routine for a
2471:    constrained matrix P^T A P.

2473:    Neighbor-wise Collective on Mat and Vec

2475:    Input Parameters:
2476: +  mat - the matrix
2477: -  x   - the vector to be multilplied

2479:    Output Parameters:
2480: .  y - the result

2482:    Notes:
2483:    The vectors x and y cannot be the same.  I.e., one cannot
2484:    call MatMult(A,y,y).

2486:    Level: beginner

2488: .keywords: matrix, multiply, matrix-vector product, constraint
2489: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2490: @*/
2491: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
2492: {

2499:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2500:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2501:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2502:   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2503:   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2504:   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);

2506:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2507:   (*mat->ops->multconstrained)(mat,x,y);
2508:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2509:   PetscObjectStateIncrease((PetscObject)y);
2510:   return(0);
2511: }

2515: /*@
2516:    MatMultTransposeConstrained - The inner multiplication routine for a
2517:    constrained matrix P^T A^T P.

2519:    Neighbor-wise Collective on Mat and Vec

2521:    Input Parameters:
2522: +  mat - the matrix
2523: -  x   - the vector to be multilplied

2525:    Output Parameters:
2526: .  y - the result

2528:    Notes:
2529:    The vectors x and y cannot be the same.  I.e., one cannot
2530:    call MatMult(A,y,y).

2532:    Level: beginner

2534: .keywords: matrix, multiply, matrix-vector product, constraint
2535: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2536: @*/
2537: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2538: {

2545:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2546:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2547:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2548:   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2549:   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);

2551:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2552:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2553:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2554:   PetscObjectStateIncrease((PetscObject)y);
2555:   return(0);
2556: }

2560: /*@C
2561:    MatGetFactorType - gets the type of factorization it is

2563:    Note Collective
2564:    as the flag

2566:    Input Parameters:
2567: .  mat - the matrix

2569:    Output Parameters:
2570: .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT

2572:     Level: intermediate

2574: .seealso:    MatFactorType, MatGetFactor()
2575: @*/
2576: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
2577: {
2581:   *t = mat->factortype;
2582:   return(0);
2583: }

2585: /* ------------------------------------------------------------*/
2588: /*@C
2589:    MatGetInfo - Returns information about matrix storage (number of
2590:    nonzeros, memory, etc.).

2592:    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag

2594:    Input Parameters:
2595: .  mat - the matrix

2597:    Output Parameters:
2598: +  flag - flag indicating the type of parameters to be returned
2599:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2600:    MAT_GLOBAL_SUM - sum over all processors)
2601: -  info - matrix information context

2603:    Notes:
2604:    The MatInfo context contains a variety of matrix data, including
2605:    number of nonzeros allocated and used, number of mallocs during
2606:    matrix assembly, etc.  Additional information for factored matrices
2607:    is provided (such as the fill ratio, number of mallocs during
2608:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2609:    when using the runtime options
2610: $       -info -mat_view ::ascii_info

2612:    Example for C/C++ Users:
2613:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2614:    data within the MatInfo context.  For example,
2615: .vb
2616:       MatInfo info;
2617:       Mat     A;
2618:       double  mal, nz_a, nz_u;

2620:       MatGetInfo(A,MAT_LOCAL,&info);
2621:       mal  = info.mallocs;
2622:       nz_a = info.nz_allocated;
2623: .ve

2625:    Example for Fortran Users:
2626:    Fortran users should declare info as a double precision
2627:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2628:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2629:    a complete list of parameter names.
2630: .vb
2631:       double  precision info(MAT_INFO_SIZE)
2632:       double  precision mal, nz_a
2633:       Mat     A
2634:       integer ierr

2636:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2637:       mal = info(MAT_INFO_MALLOCS)
2638:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2639: .ve

2641:     Level: intermediate

2643:     Concepts: matrices^getting information on

2645:     Developer Note: fortran interface is not autogenerated as the f90
2646:     interface defintion cannot be generated correctly [due to MatInfo]

2648: .seealso: MatStashGetInfo()

2650: @*/
2651: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2652: {

2659:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2660:   MatCheckPreallocated(mat,1);
2661:   (*mat->ops->getinfo)(mat,flag,info);
2662:   return(0);
2663: }

2665: /* ----------------------------------------------------------*/

2669: /*@C
2670:    MatLUFactor - Performs in-place LU factorization of matrix.

2672:    Collective on Mat

2674:    Input Parameters:
2675: +  mat - the matrix
2676: .  row - row permutation
2677: .  col - column permutation
2678: -  info - options for factorization, includes
2679: $          fill - expected fill as ratio of original fill.
2680: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2681: $                   Run with the option -info to determine an optimal value to use

2683:    Notes:
2684:    Most users should employ the simplified KSP interface for linear solvers
2685:    instead of working directly with matrix algebra routines such as this.
2686:    See, e.g., KSPCreate().

2688:    This changes the state of the matrix to a factored matrix; it cannot be used
2689:    for example with MatSetValues() unless one first calls MatSetUnfactored().

2691:    Level: developer

2693:    Concepts: matrices^LU factorization

2695: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2696:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

2698:     Developer Note: fortran interface is not autogenerated as the f90
2699:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2701: @*/
2702: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2703: {
2705:   MatFactorInfo  tinfo;

2713:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2714:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2715:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2716:   MatCheckPreallocated(mat,1);
2717:   if (!info) {
2718:     MatFactorInfoInitialize(&tinfo);
2719:     info = &tinfo;
2720:   }

2722:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2723:   (*mat->ops->lufactor)(mat,row,col,info);
2724:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2725:   PetscObjectStateIncrease((PetscObject)mat);
2726:   return(0);
2727: }

2731: /*@C
2732:    MatILUFactor - Performs in-place ILU factorization of matrix.

2734:    Collective on Mat

2736:    Input Parameters:
2737: +  mat - the matrix
2738: .  row - row permutation
2739: .  col - column permutation
2740: -  info - structure containing
2741: $      levels - number of levels of fill.
2742: $      expected fill - as ratio of original fill.
2743: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2744:                 missing diagonal entries)

2746:    Notes:
2747:    Probably really in-place only when level of fill is zero, otherwise allocates
2748:    new space to store factored matrix and deletes previous memory.

2750:    Most users should employ the simplified KSP interface for linear solvers
2751:    instead of working directly with matrix algebra routines such as this.
2752:    See, e.g., KSPCreate().

2754:    Level: developer

2756:    Concepts: matrices^ILU factorization

2758: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

2760:     Developer Note: fortran interface is not autogenerated as the f90
2761:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2763: @*/
2764: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2765: {

2774:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2775:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2776:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2777:   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2778:   MatCheckPreallocated(mat,1);

2780:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2781:   (*mat->ops->ilufactor)(mat,row,col,info);
2782:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2783:   PetscObjectStateIncrease((PetscObject)mat);
2784:   return(0);
2785: }

2789: /*@C
2790:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2791:    Call this routine before calling MatLUFactorNumeric().

2793:    Collective on Mat

2795:    Input Parameters:
2796: +  fact - the factor matrix obtained with MatGetFactor()
2797: .  mat - the matrix
2798: .  row, col - row and column permutations
2799: -  info - options for factorization, includes
2800: $          fill - expected fill as ratio of original fill.
2801: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2802: $                   Run with the option -info to determine an optimal value to use


2805:    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.

2807:    Most users should employ the simplified KSP interface for linear solvers
2808:    instead of working directly with matrix algebra routines such as this.
2809:    See, e.g., KSPCreate().

2811:    Level: developer

2813:    Concepts: matrices^LU symbolic factorization

2815: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

2817:     Developer Note: fortran interface is not autogenerated as the f90
2818:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2820: @*/
2821: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2822: {

2832:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2833:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2834:   if (!(fact)->ops->lufactorsymbolic) {
2835:     const MatSolverPackage spackage;
2836:     MatFactorGetSolverPackage(fact,&spackage);
2837:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2838:   }
2839:   MatCheckPreallocated(mat,2);

2841:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2842:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2843:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2844:   PetscObjectStateIncrease((PetscObject)fact);
2845:   return(0);
2846: }

2850: /*@C
2851:    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2852:    Call this routine after first calling MatLUFactorSymbolic().

2854:    Collective on Mat

2856:    Input Parameters:
2857: +  fact - the factor matrix obtained with MatGetFactor()
2858: .  mat - the matrix
2859: -  info - options for factorization

2861:    Notes:
2862:    See MatLUFactor() for in-place factorization.  See
2863:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

2865:    Most users should employ the simplified KSP interface for linear solvers
2866:    instead of working directly with matrix algebra routines such as this.
2867:    See, e.g., KSPCreate().

2869:    Level: developer

2871:    Concepts: matrices^LU numeric factorization

2873: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()

2875:     Developer Note: fortran interface is not autogenerated as the f90
2876:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2878: @*/
2879: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2880: {

2888:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2889:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);

2891:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2892:   MatCheckPreallocated(mat,2);
2893:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2894:   (fact->ops->lufactornumeric)(fact,mat,info);
2895:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2896:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
2897:   PetscObjectStateIncrease((PetscObject)fact);
2898:   return(0);
2899: }

2903: /*@C
2904:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2905:    symmetric matrix.

2907:    Collective on Mat

2909:    Input Parameters:
2910: +  mat - the matrix
2911: .  perm - row and column permutations
2912: -  f - expected fill as ratio of original fill

2914:    Notes:
2915:    See MatLUFactor() for the nonsymmetric case.  See also
2916:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

2918:    Most users should employ the simplified KSP interface for linear solvers
2919:    instead of working directly with matrix algebra routines such as this.
2920:    See, e.g., KSPCreate().

2922:    Level: developer

2924:    Concepts: matrices^Cholesky factorization

2926: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2927:           MatGetOrdering()

2929:     Developer Note: fortran interface is not autogenerated as the f90
2930:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2932: @*/
2933: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2934: {

2942:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
2943:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2944:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2945:   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2946:   MatCheckPreallocated(mat,1);

2948:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2949:   (*mat->ops->choleskyfactor)(mat,perm,info);
2950:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2951:   PetscObjectStateIncrease((PetscObject)mat);
2952:   return(0);
2953: }

2957: /*@C
2958:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2959:    of a symmetric matrix.

2961:    Collective on Mat

2963:    Input Parameters:
2964: +  fact - the factor matrix obtained with MatGetFactor()
2965: .  mat - the matrix
2966: .  perm - row and column permutations
2967: -  info - options for factorization, includes
2968: $          fill - expected fill as ratio of original fill.
2969: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2970: $                   Run with the option -info to determine an optimal value to use

2972:    Notes:
2973:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2974:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

2976:    Most users should employ the simplified KSP interface for linear solvers
2977:    instead of working directly with matrix algebra routines such as this.
2978:    See, e.g., KSPCreate().

2980:    Level: developer

2982:    Concepts: matrices^Cholesky symbolic factorization

2984: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2985:           MatGetOrdering()

2987:     Developer Note: fortran interface is not autogenerated as the f90
2988:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2990: @*/
2991: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2992: {

3001:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3002:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3003:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3004:   if (!(fact)->ops->choleskyfactorsymbolic) {
3005:     const MatSolverPackage spackage;
3006:     MatFactorGetSolverPackage(fact,&spackage);
3007:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3008:   }
3009:   MatCheckPreallocated(mat,2);

3011:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3012:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3013:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3014:   PetscObjectStateIncrease((PetscObject)fact);
3015:   return(0);
3016: }

3020: /*@C
3021:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3022:    of a symmetric matrix. Call this routine after first calling
3023:    MatCholeskyFactorSymbolic().

3025:    Collective on Mat

3027:    Input Parameters:
3028: +  fact - the factor matrix obtained with MatGetFactor()
3029: .  mat - the initial matrix
3030: .  info - options for factorization
3031: -  fact - the symbolic factor of mat


3034:    Notes:
3035:    Most users should employ the simplified KSP interface for linear solvers
3036:    instead of working directly with matrix algebra routines such as this.
3037:    See, e.g., KSPCreate().

3039:    Level: developer

3041:    Concepts: matrices^Cholesky numeric factorization

3043: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()

3045:     Developer Note: fortran interface is not autogenerated as the f90
3046:     interface defintion cannot be generated correctly [due to MatFactorInfo]

3048: @*/
3049: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3050: {

3058:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3059:   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3060:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3061:   MatCheckPreallocated(mat,2);

3063:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3064:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3065:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3066:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3067:   PetscObjectStateIncrease((PetscObject)fact);
3068:   return(0);
3069: }

3071: /* ----------------------------------------------------------------*/
3074: /*@
3075:    MatSolve - Solves A x = b, given a factored matrix.

3077:    Neighbor-wise Collective on Mat and Vec

3079:    Input Parameters:
3080: +  mat - the factored matrix
3081: -  b - the right-hand-side vector

3083:    Output Parameter:
3084: .  x - the result vector

3086:    Notes:
3087:    The vectors b and x cannot be the same.  I.e., one cannot
3088:    call MatSolve(A,x,x).

3090:    Notes:
3091:    Most users should employ the simplified KSP interface for linear solvers
3092:    instead of working directly with matrix algebra routines such as this.
3093:    See, e.g., KSPCreate().

3095:    Level: developer

3097:    Concepts: matrices^triangular solves

3099: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3100: @*/
3101: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
3102: {

3112:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3113:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3114:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3115:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3116:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3117:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3118:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3119:   MatCheckPreallocated(mat,1);

3121:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3122:   (*mat->ops->solve)(mat,b,x);
3123:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3124:   PetscObjectStateIncrease((PetscObject)x);
3125:   return(0);
3126: }

3130: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
3131: {
3133:   Vec            b,x;
3134:   PetscInt       m,N,i;
3135:   PetscScalar    *bb,*xx;
3136:   PetscBool      flg;

3139:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3140:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3141:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3142:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3144:   MatDenseGetArray(B,&bb);
3145:   MatDenseGetArray(X,&xx);
3146:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3147:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3148:   MatGetVecs(A,&x,&b);
3149:   for (i=0; i<N; i++) {
3150:     VecPlaceArray(b,bb + i*m);
3151:     VecPlaceArray(x,xx + i*m);
3152:     MatSolve(A,b,x);
3153:     VecResetArray(x);
3154:     VecResetArray(b);
3155:   }
3156:   VecDestroy(&b);
3157:   VecDestroy(&x);
3158:   MatDenseRestoreArray(B,&bb);
3159:   MatDenseRestoreArray(X,&xx);
3160:   return(0);
3161: }

3165: /*@
3166:    MatMatSolve - Solves A X = B, given a factored matrix.

3168:    Neighbor-wise Collective on Mat

3170:    Input Parameters:
3171: +  mat - the factored matrix
3172: -  B - the right-hand-side matrix  (dense matrix)

3174:    Output Parameter:
3175: .  X - the result matrix (dense matrix)

3177:    Notes:
3178:    The matrices b and x cannot be the same.  I.e., one cannot
3179:    call MatMatSolve(A,x,x).

3181:    Notes:
3182:    Most users should usually employ the simplified KSP interface for linear solvers
3183:    instead of working directly with matrix algebra routines such as this.
3184:    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3185:    at a time.

3187:    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3188:    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.

3190:    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.

3192:    Level: developer

3194:    Concepts: matrices^triangular solves

3196: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3197: @*/
3198: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
3199: {

3209:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3210:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3211:   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3212:   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3213:   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3214:   if (!A->rmap->N && !A->cmap->N) return(0);
3215:   MatCheckPreallocated(A,1);

3217:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3218:   if (!A->ops->matsolve) {
3219:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3220:     MatMatSolve_Basic(A,B,X);
3221:   } else {
3222:     (*A->ops->matsolve)(A,B,X);
3223:   }
3224:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3225:   PetscObjectStateIncrease((PetscObject)X);
3226:   return(0);
3227: }


3232: /*@
3233:    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3234:                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,

3236:    Neighbor-wise Collective on Mat and Vec

3238:    Input Parameters:
3239: +  mat - the factored matrix
3240: -  b - the right-hand-side vector

3242:    Output Parameter:
3243: .  x - the result vector

3245:    Notes:
3246:    MatSolve() should be used for most applications, as it performs
3247:    a forward solve followed by a backward solve.

3249:    The vectors b and x cannot be the same,  i.e., one cannot
3250:    call MatForwardSolve(A,x,x).

3252:    For matrix in seqsbaij format with block size larger than 1,
3253:    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3254:    MatForwardSolve() solves U^T*D y = b, and
3255:    MatBackwardSolve() solves U x = y.
3256:    Thus they do not provide a symmetric preconditioner.

3258:    Most users should employ the simplified KSP interface for linear solvers
3259:    instead of working directly with matrix algebra routines such as this.
3260:    See, e.g., KSPCreate().

3262:    Level: developer

3264:    Concepts: matrices^forward solves

3266: .seealso: MatSolve(), MatBackwardSolve()
3267: @*/
3268: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
3269: {

3279:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3280:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3281:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3282:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3283:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3284:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3285:   MatCheckPreallocated(mat,1);
3286:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3287:   (*mat->ops->forwardsolve)(mat,b,x);
3288:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3289:   PetscObjectStateIncrease((PetscObject)x);
3290:   return(0);
3291: }

3295: /*@
3296:    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3297:                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,

3299:    Neighbor-wise Collective on Mat and Vec

3301:    Input Parameters:
3302: +  mat - the factored matrix
3303: -  b - the right-hand-side vector

3305:    Output Parameter:
3306: .  x - the result vector

3308:    Notes:
3309:    MatSolve() should be used for most applications, as it performs
3310:    a forward solve followed by a backward solve.

3312:    The vectors b and x cannot be the same.  I.e., one cannot
3313:    call MatBackwardSolve(A,x,x).

3315:    For matrix in seqsbaij format with block size larger than 1,
3316:    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3317:    MatForwardSolve() solves U^T*D y = b, and
3318:    MatBackwardSolve() solves U x = y.
3319:    Thus they do not provide a symmetric preconditioner.

3321:    Most users should employ the simplified KSP interface for linear solvers
3322:    instead of working directly with matrix algebra routines such as this.
3323:    See, e.g., KSPCreate().

3325:    Level: developer

3327:    Concepts: matrices^backward solves

3329: .seealso: MatSolve(), MatForwardSolve()
3330: @*/
3331: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
3332: {

3342:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3343:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3344:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3345:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3346:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3347:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3348:   MatCheckPreallocated(mat,1);

3350:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3351:   (*mat->ops->backwardsolve)(mat,b,x);
3352:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3353:   PetscObjectStateIncrease((PetscObject)x);
3354:   return(0);
3355: }

3359: /*@
3360:    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.

3362:    Neighbor-wise Collective on Mat and Vec

3364:    Input Parameters:
3365: +  mat - the factored matrix
3366: .  b - the right-hand-side vector
3367: -  y - the vector to be added to

3369:    Output Parameter:
3370: .  x - the result vector

3372:    Notes:
3373:    The vectors b and x cannot be the same.  I.e., one cannot
3374:    call MatSolveAdd(A,x,y,x).

3376:    Most users should employ the simplified KSP interface for linear solvers
3377:    instead of working directly with matrix algebra routines such as this.
3378:    See, e.g., KSPCreate().

3380:    Level: developer

3382:    Concepts: matrices^triangular solves

3384: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3385: @*/
3386: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3387: {
3388:   PetscScalar    one = 1.0;
3389:   Vec            tmp;

3401:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3402:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3403:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3404:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3405:   if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3406:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3407:   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3408:   MatCheckPreallocated(mat,1);

3410:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3411:   if (mat->ops->solveadd) {
3412:     (*mat->ops->solveadd)(mat,b,y,x);
3413:   } else {
3414:     /* do the solve then the add manually */
3415:     if (x != y) {
3416:       MatSolve(mat,b,x);
3417:       VecAXPY(x,one,y);
3418:     } else {
3419:       VecDuplicate(x,&tmp);
3420:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3421:       VecCopy(x,tmp);
3422:       MatSolve(mat,b,x);
3423:       VecAXPY(x,one,tmp);
3424:       VecDestroy(&tmp);
3425:     }
3426:   }
3427:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3428:   PetscObjectStateIncrease((PetscObject)x);
3429:   return(0);
3430: }

3434: /*@
3435:    MatSolveTranspose - Solves A' x = b, given a factored matrix.

3437:    Neighbor-wise Collective on Mat and Vec

3439:    Input Parameters:
3440: +  mat - the factored matrix
3441: -  b - the right-hand-side vector

3443:    Output Parameter:
3444: .  x - the result vector

3446:    Notes:
3447:    The vectors b and x cannot be the same.  I.e., one cannot
3448:    call MatSolveTranspose(A,x,x).

3450:    Most users should employ the simplified KSP interface for linear solvers
3451:    instead of working directly with matrix algebra routines such as this.
3452:    See, e.g., KSPCreate().

3454:    Level: developer

3456:    Concepts: matrices^triangular solves

3458: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3459: @*/
3460: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
3461: {

3471:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3472:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3473:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3474:   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3475:   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3476:   MatCheckPreallocated(mat,1);
3477:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3478:   (*mat->ops->solvetranspose)(mat,b,x);
3479:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3480:   PetscObjectStateIncrease((PetscObject)x);
3481:   return(0);
3482: }

3486: /*@
3487:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3488:                       factored matrix.

3490:    Neighbor-wise Collective on Mat and Vec

3492:    Input Parameters:
3493: +  mat - the factored matrix
3494: .  b - the right-hand-side vector
3495: -  y - the vector to be added to

3497:    Output Parameter:
3498: .  x - the result vector

3500:    Notes:
3501:    The vectors b and x cannot be the same.  I.e., one cannot
3502:    call MatSolveTransposeAdd(A,x,y,x).

3504:    Most users should employ the simplified KSP interface for linear solvers
3505:    instead of working directly with matrix algebra routines such as this.
3506:    See, e.g., KSPCreate().

3508:    Level: developer

3510:    Concepts: matrices^triangular solves

3512: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3513: @*/
3514: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3515: {
3516:   PetscScalar    one = 1.0;
3518:   Vec            tmp;

3529:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3530:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3531:   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3532:   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3533:   if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3534:   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3535:   MatCheckPreallocated(mat,1);

3537:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3538:   if (mat->ops->solvetransposeadd) {
3539:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3540:   } else {
3541:     /* do the solve then the add manually */
3542:     if (x != y) {
3543:       MatSolveTranspose(mat,b,x);
3544:       VecAXPY(x,one,y);
3545:     } else {
3546:       VecDuplicate(x,&tmp);
3547:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3548:       VecCopy(x,tmp);
3549:       MatSolveTranspose(mat,b,x);
3550:       VecAXPY(x,one,tmp);
3551:       VecDestroy(&tmp);
3552:     }
3553:   }
3554:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3555:   PetscObjectStateIncrease((PetscObject)x);
3556:   return(0);
3557: }
3558: /* ----------------------------------------------------------------*/

3562: /*@
3563:    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.

3565:    Neighbor-wise Collective on Mat and Vec

3567:    Input Parameters:
3568: +  mat - the matrix
3569: .  b - the right hand side
3570: .  omega - the relaxation factor
3571: .  flag - flag indicating the type of SOR (see below)
3572: .  shift -  diagonal shift
3573: .  its - the number of iterations
3574: -  lits - the number of local iterations

3576:    Output Parameters:
3577: .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)

3579:    SOR Flags:
3580: .     SOR_FORWARD_SWEEP - forward SOR
3581: .     SOR_BACKWARD_SWEEP - backward SOR
3582: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3583: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3584: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3585: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3586: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3587:          upper/lower triangular part of matrix to
3588:          vector (with omega)
3589: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3591:    Notes:
3592:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3593:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3594:    on each processor.

3596:    Application programmers will not generally use MatSOR() directly,
3597:    but instead will employ the KSP/PC interface.

3599:    Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing

3601:    Notes for Advanced Users:
3602:    The flags are implemented as bitwise inclusive or operations.
3603:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3604:    to specify a zero initial guess for SSOR.

3606:    Most users should employ the simplified KSP interface for linear solvers
3607:    instead of working directly with matrix algebra routines such as this.
3608:    See, e.g., KSPCreate().

3610:    Vectors x and b CANNOT be the same

3612:    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes

3614:    Level: developer

3616:    Concepts: matrices^relaxation
3617:    Concepts: matrices^SOR
3618:    Concepts: matrices^Gauss-Seidel

3620: @*/
3621: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3622: {

3632:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3633:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3634:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3635:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3636:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3637:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3638:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3639:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3640:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3642:   MatCheckPreallocated(mat,1);
3643:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3644:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3645:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3646:   PetscObjectStateIncrease((PetscObject)x);
3647:   return(0);
3648: }

3652: /*
3653:       Default matrix copy routine.
3654: */
3655: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3656: {
3657:   PetscErrorCode    ierr;
3658:   PetscInt          i,rstart = 0,rend = 0,nz;
3659:   const PetscInt    *cwork;
3660:   const PetscScalar *vwork;

3663:   if (B->assembled) {
3664:     MatZeroEntries(B);
3665:   }
3666:   MatGetOwnershipRange(A,&rstart,&rend);
3667:   for (i=rstart; i<rend; i++) {
3668:     MatGetRow(A,i,&nz,&cwork,&vwork);
3669:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3670:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3671:   }
3672:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3673:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3674:   PetscObjectStateIncrease((PetscObject)B);
3675:   return(0);
3676: }

3680: /*@
3681:    MatCopy - Copys a matrix to another matrix.

3683:    Collective on Mat

3685:    Input Parameters:
3686: +  A - the matrix
3687: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3689:    Output Parameter:
3690: .  B - where the copy is put

3692:    Notes:
3693:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3694:    same nonzero pattern or the routine will crash.

3696:    MatCopy() copies the matrix entries of a matrix to another existing
3697:    matrix (after first zeroing the second matrix).  A related routine is
3698:    MatConvert(), which first creates a new matrix and then copies the data.

3700:    Level: intermediate

3702:    Concepts: matrices^copying

3704: .seealso: MatConvert(), MatDuplicate()

3706: @*/
3707: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3708: {
3710:   PetscInt       i;

3718:   MatCheckPreallocated(B,2);
3719:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3720:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3721:   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
3722:   MatCheckPreallocated(A,1);

3724:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3725:   if (A->ops->copy) {
3726:     (*A->ops->copy)(A,B,str);
3727:   } else { /* generic conversion */
3728:     MatCopy_Basic(A,B,str);
3729:   }

3731:   B->stencil.dim = A->stencil.dim;
3732:   B->stencil.noc = A->stencil.noc;
3733:   for (i=0; i<=A->stencil.dim; i++) {
3734:     B->stencil.dims[i]   = A->stencil.dims[i];
3735:     B->stencil.starts[i] = A->stencil.starts[i];
3736:   }

3738:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3739:   PetscObjectStateIncrease((PetscObject)B);
3740:   return(0);
3741: }

3745: /*@C
3746:    MatConvert - Converts a matrix to another matrix, either of the same
3747:    or different type.

3749:    Collective on Mat

3751:    Input Parameters:
3752: +  mat - the matrix
3753: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3754:    same type as the original matrix.
3755: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3756:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3757:    MAT_INITIAL_MATRIX.

3759:    Output Parameter:
3760: .  M - pointer to place new matrix

3762:    Notes:
3763:    MatConvert() first creates a new matrix and then copies the data from
3764:    the first matrix.  A related routine is MatCopy(), which copies the matrix
3765:    entries of one matrix to another already existing matrix context.

3767:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3768:    the MPI communicator of the generated matrix is always the same as the communicator
3769:    of the input matrix.

3771:    Level: intermediate

3773:    Concepts: matrices^converting between storage formats

3775: .seealso: MatCopy(), MatDuplicate()
3776: @*/
3777: PetscErrorCode  MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3778: {
3780:   PetscBool      sametype,issame,flg;
3781:   char           convname[256],mtype[256];
3782:   Mat            B;

3788:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3789:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3790:   MatCheckPreallocated(mat,1);
3791:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

3793:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3794:   if (flg) {
3795:     newtype = mtype;
3796:   }
3797:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3798:   PetscStrcmp(newtype,"same",&issame);
3799:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");

3801:   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);

3803:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3804:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3805:   } else {
3806:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3807:     const char     *prefix[3] = {"seq","mpi",""};
3808:     PetscInt       i;
3809:     /*
3810:        Order of precedence:
3811:        1) See if a specialized converter is known to the current matrix.
3812:        2) See if a specialized converter is known to the desired matrix class.
3813:        3) See if a good general converter is registered for the desired class
3814:           (as of 6/27/03 only MATMPIADJ falls into this category).
3815:        4) See if a good general converter is known for the current matrix.
3816:        5) Use a really basic converter.
3817:     */

3819:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3820:     for (i=0; i<3; i++) {
3821:       PetscStrcpy(convname,"MatConvert_");
3822:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3823:       PetscStrcat(convname,"_");
3824:       PetscStrcat(convname,prefix[i]);
3825:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3826:       PetscStrcat(convname,"_C");
3827:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3828:       if (conv) goto foundconv;
3829:     }

3831:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3832:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
3833:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3834:     MatSetType(B,newtype);
3835:     for (i=0; i<3; i++) {
3836:       PetscStrcpy(convname,"MatConvert_");
3837:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3838:       PetscStrcat(convname,"_");
3839:       PetscStrcat(convname,prefix[i]);
3840:       PetscStrcat(convname,newtype);
3841:       PetscStrcat(convname,"_C");
3842:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3843:       if (conv) {
3844:         MatDestroy(&B);
3845:         goto foundconv;
3846:       }
3847:     }

3849:     /* 3) See if a good general converter is registered for the desired class */
3850:     conv = B->ops->convertfrom;
3851:     MatDestroy(&B);
3852:     if (conv) goto foundconv;

3854:     /* 4) See if a good general converter is known for the current matrix */
3855:     if (mat->ops->convert) {
3856:       conv = mat->ops->convert;
3857:     }
3858:     if (conv) goto foundconv;

3860:     /* 5) Use a really basic converter. */
3861:     conv = MatConvert_Basic;

3863: foundconv:
3864:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3865:     (*conv)(mat,newtype,reuse,M);
3866:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3867:   }
3868:   PetscObjectStateIncrease((PetscObject)*M);

3870:   /* Copy Mat options */
3871:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3872:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3873:   return(0);
3874: }

3878: /*@C
3879:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3881:    Not Collective

3883:    Input Parameter:
3884: .  mat - the matrix, must be a factored matrix

3886:    Output Parameter:
3887: .   type - the string name of the package (do not free this string)

3889:    Notes:
3890:       In Fortran you pass in a empty string and the package name will be copied into it.
3891:     (Make sure the string is long enough)

3893:    Level: intermediate

3895: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3896: @*/
3897: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3898: {
3899:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

3904:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3905:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
3906:   if (!conv) {
3907:     *type = MATSOLVERPETSC;
3908:   } else {
3909:     (*conv)(mat,type);
3910:   }
3911:   return(0);
3912: }

3916: /*@C
3917:    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()

3919:    Collective on Mat

3921:    Input Parameters:
3922: +  mat - the matrix
3923: .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
3924: -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,

3926:    Output Parameters:
3927: .  f - the factor matrix used with MatXXFactorSymbolic() calls

3929:    Notes:
3930:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3931:      such as pastix, superlu, mumps etc.

3933:       PETSc must have been ./configure to use the external solver, using the option --download-package

3935:    Level: intermediate

3937: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3938: @*/
3939: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3940: {
3941:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
3942:   char           convname[256];


3948:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3949:   MatCheckPreallocated(mat,1);

3951:   PetscStrcpy(convname,"MatGetFactor_");
3952:   PetscStrcat(convname,type);
3953:   PetscStrcat(convname,"_C");
3954:   PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3955:   if (!conv) {
3956:     PetscBool flag;
3957:     MPI_Comm  comm;

3959:     PetscObjectGetComm((PetscObject)mat,&comm);
3960:     PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3961:     if (flag) SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3962:     else SETERRQ4(comm,PETSC_ERR_SUP,"Matrix format %s does not have a solver package %s for %s. Perhaps you must ./configure with --download-%s",((PetscObject)mat)->type_name,type,MatFactorTypes[ftype],type);
3963:   }
3964:   (*conv)(mat,ftype,f);
3965:   return(0);
3966: }

3970: /*@C
3971:    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type

3973:    Not Collective

3975:    Input Parameters:
3976: +  mat - the matrix
3977: .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
3978: -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,

3980:    Output Parameter:
3981: .    flg - PETSC_TRUE if the factorization is available

3983:    Notes:
3984:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3985:      such as pastix, superlu, mumps etc.

3987:       PETSc must have been ./configure to use the external solver, using the option --download-package

3989:    Level: intermediate

3991: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3992: @*/
3993: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
3994: {
3995:   PetscErrorCode ierr, (*conv)(Mat,MatFactorType,PetscBool*);
3996:   char           convname[256];


4002:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4003:   MatCheckPreallocated(mat,1);

4005:   PetscStrcpy(convname,"MatGetFactorAvailable_");
4006:   PetscStrcat(convname,type);
4007:   PetscStrcat(convname,"_C");
4008:   PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4009:   if (!conv) {
4010:     *flg = PETSC_FALSE;
4011:   } else {
4012:     (*conv)(mat,ftype,flg);
4013:   }
4014:   return(0);
4015: }


4020: /*@
4021:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4023:    Collective on Mat

4025:    Input Parameters:
4026: +  mat - the matrix
4027: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4028:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

4030:    Output Parameter:
4031: .  M - pointer to place new matrix

4033:    Level: intermediate

4035:    Concepts: matrices^duplicating

4037:     Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.

4039: .seealso: MatCopy(), MatConvert()
4040: @*/
4041: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4042: {
4044:   Mat            B;
4045:   PetscInt       i;

4051:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4052:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4053:   MatCheckPreallocated(mat,1);

4055:   *M = 0;
4056:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4057:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4058:   (*mat->ops->duplicate)(mat,op,M);
4059:   B    = *M;

4061:   B->stencil.dim = mat->stencil.dim;
4062:   B->stencil.noc = mat->stencil.noc;
4063:   for (i=0; i<=mat->stencil.dim; i++) {
4064:     B->stencil.dims[i]   = mat->stencil.dims[i];
4065:     B->stencil.starts[i] = mat->stencil.starts[i];
4066:   }

4068:   B->nooffproczerorows = mat->nooffproczerorows;
4069:   B->nooffprocentries  = mat->nooffprocentries;

4071:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4072:   PetscObjectStateIncrease((PetscObject)B);
4073:   return(0);
4074: }

4078: /*@
4079:    MatGetDiagonal - Gets the diagonal of a matrix.

4081:    Logically Collective on Mat and Vec

4083:    Input Parameters:
4084: +  mat - the matrix
4085: -  v - the vector for storing the diagonal

4087:    Output Parameter:
4088: .  v - the diagonal of the matrix

4090:    Level: intermediate

4092:    Note:
4093:    Currently only correct in parallel for square matrices.

4095:    Concepts: matrices^accessing diagonals

4097: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4098: @*/
4099: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
4100: {

4107:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4108:   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4109:   MatCheckPreallocated(mat,1);

4111:   (*mat->ops->getdiagonal)(mat,v);
4112:   PetscObjectStateIncrease((PetscObject)v);
4113:   return(0);
4114: }

4118: /*@
4119:    MatGetRowMin - Gets the minimum value (of the real part) of each
4120:         row of the matrix

4122:    Logically Collective on Mat and Vec

4124:    Input Parameters:
4125: .  mat - the matrix

4127:    Output Parameter:
4128: +  v - the vector for storing the maximums
4129: -  idx - the indices of the column found for each row (optional)

4131:    Level: intermediate

4133:    Notes: The result of this call are the same as if one converted the matrix to dense format
4134:       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).

4136:     This code is only implemented for a couple of matrix formats.

4138:    Concepts: matrices^getting row maximums

4140: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4141:           MatGetRowMax()
4142: @*/
4143: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4144: {

4151:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4152:   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4153:   MatCheckPreallocated(mat,1);

4155:   (*mat->ops->getrowmin)(mat,v,idx);
4156:   PetscObjectStateIncrease((PetscObject)v);
4157:   return(0);
4158: }

4162: /*@
4163:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4164:         row of the matrix

4166:    Logically Collective on Mat and Vec

4168:    Input Parameters:
4169: .  mat - the matrix

4171:    Output Parameter:
4172: +  v - the vector for storing the minimums
4173: -  idx - the indices of the column found for each row (or NULL if not needed)

4175:    Level: intermediate

4177:    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4178:     row is 0 (the first column).

4180:     This code is only implemented for a couple of matrix formats.

4182:    Concepts: matrices^getting row maximums

4184: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4185: @*/
4186: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4187: {

4194:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4195:   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4196:   MatCheckPreallocated(mat,1);
4197:   if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}

4199:   (*mat->ops->getrowminabs)(mat,v,idx);
4200:   PetscObjectStateIncrease((PetscObject)v);
4201:   return(0);
4202: }

4206: /*@
4207:    MatGetRowMax - Gets the maximum value (of the real part) of each
4208:         row of the matrix

4210:    Logically Collective on Mat and Vec

4212:    Input Parameters:
4213: .  mat - the matrix

4215:    Output Parameter:
4216: +  v - the vector for storing the maximums
4217: -  idx - the indices of the column found for each row (optional)

4219:    Level: intermediate

4221:    Notes: The result of this call are the same as if one converted the matrix to dense format
4222:       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).

4224:     This code is only implemented for a couple of matrix formats.

4226:    Concepts: matrices^getting row maximums

4228: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4229: @*/
4230: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4231: {

4238:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4239:   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4240:   MatCheckPreallocated(mat,1);

4242:   (*mat->ops->getrowmax)(mat,v,idx);
4243:   PetscObjectStateIncrease((PetscObject)v);
4244:   return(0);
4245: }

4249: /*@
4250:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4251:         row of the matrix

4253:    Logically Collective on Mat and Vec

4255:    Input Parameters:
4256: .  mat - the matrix

4258:    Output Parameter:
4259: +  v - the vector for storing the maximums
4260: -  idx - the indices of the column found for each row (or NULL if not needed)

4262:    Level: intermediate

4264:    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4265:     row is 0 (the first column).

4267:     This code is only implemented for a couple of matrix formats.

4269:    Concepts: matrices^getting row maximums

4271: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4272: @*/
4273: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4274: {

4281:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4282:   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4283:   MatCheckPreallocated(mat,1);
4284:   if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}

4286:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4287:   PetscObjectStateIncrease((PetscObject)v);
4288:   return(0);
4289: }

4293: /*@
4294:    MatGetRowSum - Gets the sum of each row of the matrix

4296:    Logically Collective on Mat and Vec

4298:    Input Parameters:
4299: .  mat - the matrix

4301:    Output Parameter:
4302: .  v - the vector for storing the sum of rows

4304:    Level: intermediate

4306:    Notes: This code is slow since it is not currently specialized for different formats

4308:    Concepts: matrices^getting row sums

4310: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4311: @*/
4312: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4313: {
4314:   PetscInt       start = 0, end = 0, row;
4315:   PetscScalar    *array;

4322:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4323:   MatCheckPreallocated(mat,1);
4324:   MatGetOwnershipRange(mat, &start, &end);
4325:   VecGetArray(v, &array);
4326:   for (row = start; row < end; ++row) {
4327:     PetscInt          ncols, col;
4328:     const PetscInt    *cols;
4329:     const PetscScalar *vals;

4331:     array[row - start] = 0.0;

4333:     MatGetRow(mat, row, &ncols, &cols, &vals);
4334:     for (col = 0; col < ncols; col++) {
4335:       array[row - start] += vals[col];
4336:     }
4337:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4338:   }
4339:   VecRestoreArray(v, &array);
4340:   PetscObjectStateIncrease((PetscObject) v);
4341:   return(0);
4342: }

4346: /*@
4347:    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.

4349:    Collective on Mat

4351:    Input Parameter:
4352: +  mat - the matrix to transpose
4353: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4355:    Output Parameters:
4356: .  B - the transpose

4358:    Notes:
4359:      If you  pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);

4361:      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.

4363:    Level: intermediate

4365:    Concepts: matrices^transposing

4367: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4368: @*/
4369: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4370: {

4376:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4377:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4378:   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4379:   MatCheckPreallocated(mat,1);

4381:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4382:   (*mat->ops->transpose)(mat,reuse,B);
4383:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4384:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4385:   return(0);
4386: }

4390: /*@
4391:    MatIsTranspose - Test whether a matrix is another one's transpose,
4392:         or its own, in which case it tests symmetry.

4394:    Collective on Mat

4396:    Input Parameter:
4397: +  A - the matrix to test
4398: -  B - the matrix to test against, this can equal the first parameter

4400:    Output Parameters:
4401: .  flg - the result

4403:    Notes:
4404:    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4405:    has a running time of the order of the number of nonzeros; the parallel
4406:    test involves parallel copies of the block-offdiagonal parts of the matrix.

4408:    Level: intermediate

4410:    Concepts: matrices^transposing, matrix^symmetry

4412: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4413: @*/
4414: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4415: {
4416:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4422:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4423:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4424:   *flg = PETSC_FALSE;
4425:   if (f && g) {
4426:     if (f == g) {
4427:       (*f)(A,B,tol,flg);
4428:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4429:   } else {
4430:     MatType mattype;
4431:     if (!f) {
4432:       MatGetType(A,&mattype);
4433:     } else {
4434:       MatGetType(B,&mattype);
4435:     }
4436:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4437:   }
4438:   return(0);
4439: }

4443: /*@
4444:    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.

4446:    Collective on Mat

4448:    Input Parameter:
4449: +  mat - the matrix to transpose and complex conjugate
4450: -  reuse - store the transpose matrix in the provided B

4452:    Output Parameters:
4453: .  B - the Hermitian

4455:    Notes:
4456:      If you  pass in &mat for B the Hermitian will be done in place

4458:    Level: intermediate

4460:    Concepts: matrices^transposing, complex conjugatex

4462: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4463: @*/
4464: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4465: {

4469:   MatTranspose(mat,reuse,B);
4470: #if defined(PETSC_USE_COMPLEX)
4471:   MatConjugate(*B);
4472: #endif
4473:   return(0);
4474: }

4478: /*@
4479:    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,

4481:    Collective on Mat

4483:    Input Parameter:
4484: +  A - the matrix to test
4485: -  B - the matrix to test against, this can equal the first parameter

4487:    Output Parameters:
4488: .  flg - the result

4490:    Notes:
4491:    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4492:    has a running time of the order of the number of nonzeros; the parallel
4493:    test involves parallel copies of the block-offdiagonal parts of the matrix.

4495:    Level: intermediate

4497:    Concepts: matrices^transposing, matrix^symmetry

4499: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4500: @*/
4501: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4502: {
4503:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4509:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4510:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4511:   if (f && g) {
4512:     if (f==g) {
4513:       (*f)(A,B,tol,flg);
4514:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4515:   }
4516:   return(0);
4517: }

4521: /*@
4522:    MatPermute - Creates a new matrix with rows and columns permuted from the
4523:    original.

4525:    Collective on Mat

4527:    Input Parameters:
4528: +  mat - the matrix to permute
4529: .  row - row permutation, each processor supplies only the permutation for its rows
4530: -  col - column permutation, each processor supplies only the permutation for its columns

4532:    Output Parameters:
4533: .  B - the permuted matrix

4535:    Level: advanced

4537:    Note:
4538:    The index sets map from row/col of permuted matrix to row/col of original matrix.
4539:    The index sets should be on the same communicator as Mat and have the same local sizes.

4541:    Concepts: matrices^permuting

4543: .seealso: MatGetOrdering(), ISAllGather()

4545: @*/
4546: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4547: {

4556:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4557:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4558:   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4559:   MatCheckPreallocated(mat,1);

4561:   (*mat->ops->permute)(mat,row,col,B);
4562:   PetscObjectStateIncrease((PetscObject)*B);
4563:   return(0);
4564: }

4568: /*@
4569:    MatEqual - Compares two matrices.

4571:    Collective on Mat

4573:    Input Parameters:
4574: +  A - the first matrix
4575: -  B - the second matrix

4577:    Output Parameter:
4578: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4580:    Level: intermediate

4582:    Concepts: matrices^equality between
4583: @*/
4584: PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4585: {

4595:   MatCheckPreallocated(B,2);
4596:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4597:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4598:   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4599:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4600:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4601:   if (A->ops->equal != B->ops->equal) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4602:   MatCheckPreallocated(A,1);

4604:   (*A->ops->equal)(A,B,flg);
4605:   return(0);
4606: }

4610: /*@
4611:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4612:    matrices that are stored as vectors.  Either of the two scaling
4613:    matrices can be NULL.

4615:    Collective on Mat

4617:    Input Parameters:
4618: +  mat - the matrix to be scaled
4619: .  l - the left scaling vector (or NULL)
4620: -  r - the right scaling vector (or NULL)

4622:    Notes:
4623:    MatDiagonalScale() computes A = LAR, where
4624:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4625:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4627:    Level: intermediate

4629:    Concepts: matrices^diagonal scaling
4630:    Concepts: diagonal scaling of matrices

4632: .seealso: MatScale()
4633: @*/
4634: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4635: {

4641:   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4644:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4645:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4646:   MatCheckPreallocated(mat,1);

4648:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4649:   (*mat->ops->diagonalscale)(mat,l,r);
4650:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4651:   PetscObjectStateIncrease((PetscObject)mat);
4652: #if defined(PETSC_HAVE_CUSP)
4653:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4654:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4655:   }
4656: #endif
4657: #if defined(PETSC_HAVE_VIENNACL)
4658:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4659:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4660:   }
4661: #endif
4662:   return(0);
4663: }

4667: /*@
4668:     MatScale - Scales all elements of a matrix by a given number.

4670:     Logically Collective on Mat

4672:     Input Parameters:
4673: +   mat - the matrix to be scaled
4674: -   a  - the scaling value

4676:     Output Parameter:
4677: .   mat - the scaled matrix

4679:     Level: intermediate

4681:     Concepts: matrices^scaling all entries

4683: .seealso: MatDiagonalScale()
4684: @*/
4685: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4686: {

4692:   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4693:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4694:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4696:   MatCheckPreallocated(mat,1);

4698:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4699:   if (a != (PetscScalar)1.0) {
4700:     (*mat->ops->scale)(mat,a);
4701:     PetscObjectStateIncrease((PetscObject)mat);
4702:   }
4703:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4704: #if defined(PETSC_HAVE_CUSP)
4705:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4706:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4707:   }
4708: #endif
4709: #if defined(PETSC_HAVE_VIENNACL)
4710:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4711:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4712:   }
4713: #endif
4714:   return(0);
4715: }

4719: /*@
4720:    MatNorm - Calculates various norms of a matrix.

4722:    Collective on Mat

4724:    Input Parameters:
4725: +  mat - the matrix
4726: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4728:    Output Parameters:
4729: .  nrm - the resulting norm

4731:    Level: intermediate

4733:    Concepts: matrices^norm
4734:    Concepts: norm^of matrix
4735: @*/
4736: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4737: {


4745:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4746:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4747:   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4748:   MatCheckPreallocated(mat,1);

4750:   (*mat->ops->norm)(mat,type,nrm);
4751:   return(0);
4752: }

4754: /*
4755:      This variable is used to prevent counting of MatAssemblyBegin() that
4756:    are called from within a MatAssemblyEnd().
4757: */
4758: static PetscInt MatAssemblyEnd_InUse = 0;
4761: /*@
4762:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4763:    be called after completing all calls to MatSetValues().

4765:    Collective on Mat

4767:    Input Parameters:
4768: +  mat - the matrix
4769: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4771:    Notes:
4772:    MatSetValues() generally caches the values.  The matrix is ready to
4773:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4774:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4775:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4776:    using the matrix.

4778:    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
4779:    same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is
4780:    a global collective operation requring all processes that share the matrix.

4782:    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4783:    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4784:    before MAT_FINAL_ASSEMBLY so the space is not compressed out.

4786:    Level: beginner

4788:    Concepts: matrices^assembling

4790: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4791: @*/
4792: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4793: {

4799:   MatCheckPreallocated(mat,1);
4800:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4801:   if (mat->assembled) {
4802:     mat->was_assembled = PETSC_TRUE;
4803:     mat->assembled     = PETSC_FALSE;
4804:   }
4805:   if (!MatAssemblyEnd_InUse) {
4806:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4807:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
4808:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4809:   } else if (mat->ops->assemblybegin) {
4810:     (*mat->ops->assemblybegin)(mat,type);
4811:   }
4812:   return(0);
4813: }

4817: /*@
4818:    MatAssembled - Indicates if a matrix has been assembled and is ready for
4819:      use; for example, in matrix-vector product.

4821:    Not Collective

4823:    Input Parameter:
4824: .  mat - the matrix

4826:    Output Parameter:
4827: .  assembled - PETSC_TRUE or PETSC_FALSE

4829:    Level: advanced

4831:    Concepts: matrices^assembled?

4833: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4834: @*/
4835: PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
4836: {
4841:   *assembled = mat->assembled;
4842:   return(0);
4843: }

4847: /*@
4848:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4849:    be called after MatAssemblyBegin().

4851:    Collective on Mat

4853:    Input Parameters:
4854: +  mat - the matrix
4855: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4857:    Options Database Keys:
4858: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
4859: .  -mat_view ::ascii_info_detail - Prints more detailed info
4860: .  -mat_view - Prints matrix in ASCII format
4861: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
4862: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4863: .  -display <name> - Sets display name (default is host)
4864: .  -draw_pause <sec> - Sets number of seconds to pause after display
4865: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 10 Using MATLAB with PETSc )
4866: .  -viewer_socket_machine <machine>
4867: .  -viewer_socket_port <port>
4868: .  -mat_view binary - save matrix to file in binary format
4869: -  -viewer_binary_filename <name>

4871:    Notes:
4872:    MatSetValues() generally caches the values.  The matrix is ready to
4873:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4874:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4875:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4876:    using the matrix.

4878:    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4879:    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4880:    before MAT_FINAL_ASSEMBLY so the space is not compressed out.

4882:    Level: beginner

4884: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4885: @*/
4886: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4887: {
4888:   PetscErrorCode  ierr;
4889:   static PetscInt inassm = 0;
4890:   PetscBool       flg    = PETSC_FALSE;


4896:   inassm++;
4897:   MatAssemblyEnd_InUse++;
4898:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4899:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4900:     if (mat->ops->assemblyend) {
4901:       (*mat->ops->assemblyend)(mat,type);
4902:     }
4903:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4904:   } else if (mat->ops->assemblyend) {
4905:     (*mat->ops->assemblyend)(mat,type);
4906:   }

4908:   /* Flush assembly is not a true assembly */
4909:   if (type != MAT_FLUSH_ASSEMBLY) {
4910:     mat->assembled = PETSC_TRUE; mat->num_ass++;
4911:   }
4912:   mat->insertmode = NOT_SET_VALUES;
4913:   MatAssemblyEnd_InUse--;
4914:   PetscObjectStateIncrease((PetscObject)mat);
4915:   if (!mat->symmetric_eternal) {
4916:     mat->symmetric_set              = PETSC_FALSE;
4917:     mat->hermitian_set              = PETSC_FALSE;
4918:     mat->structurally_symmetric_set = PETSC_FALSE;
4919:   }
4920: #if defined(PETSC_HAVE_CUSP)
4921:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4922:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4923:   }
4924: #endif
4925: #if defined(PETSC_HAVE_VIENNACL)
4926:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4927:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4928:   }
4929: #endif
4930:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4931:     MatViewFromOptions(mat,NULL,"-mat_view");

4933:     if (mat->checksymmetryonassembly) {
4934:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
4935:       if (flg) {
4936:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
4937:       } else {
4938:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
4939:       }
4940:     }
4941:     if (mat->nullsp && mat->checknullspaceonassembly) {
4942:       MatNullSpaceTest(mat->nullsp,mat,NULL);
4943:     }
4944:   }
4945:   inassm--;
4946:   return(0);
4947: }

4951: /*@
4952:    MatSetOption - Sets a parameter option for a matrix. Some options
4953:    may be specific to certain storage formats.  Some options
4954:    determine how values will be inserted (or added). Sorted,
4955:    row-oriented input will generally assemble the fastest. The default
4956:    is row-oriented.

4958:    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption

4960:    Input Parameters:
4961: +  mat - the matrix
4962: .  option - the option, one of those listed below (and possibly others),
4963: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

4965:   Options Describing Matrix Structure:
4966: +    MAT_SPD - symmetric positive definite
4967: -    MAT_SYMMETRIC - symmetric in terms of both structure and value
4968: .    MAT_HERMITIAN - transpose is the complex conjugation
4969: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4970: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4971:                             you set to be kept with all future use of the matrix
4972:                             including after MatAssemblyBegin/End() which could
4973:                             potentially change the symmetry structure, i.e. you
4974:                             KNOW the matrix will ALWAYS have the property you set.


4977:    Options For Use with MatSetValues():
4978:    Insert a logically dense subblock, which can be
4979: .    MAT_ROW_ORIENTED - row-oriented (default)

4981:    Note these options reflect the data you pass in with MatSetValues(); it has
4982:    nothing to do with how the data is stored internally in the matrix
4983:    data structure.

4985:    When (re)assembling a matrix, we can restrict the input for
4986:    efficiency/debugging purposes.  These options include:
4987: +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
4988: .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4989: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4990: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4991: .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4992: +    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
4993:         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
4994:         performance for very large process counts.

4996:    Notes:
4997:    Some options are relevant only for particular matrix types and
4998:    are thus ignored by others.  Other options are not supported by
4999:    certain matrix types and will generate an error message if set.

5001:    If using a Fortran 77 module to compute a matrix, one may need to
5002:    use the column-oriented option (or convert to the row-oriented
5003:    format).

5005:    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5006:    that would generate a new entry in the nonzero structure is instead
5007:    ignored.  Thus, if memory has not alredy been allocated for this particular
5008:    data, then the insertion is ignored. For dense matrices, in which
5009:    the entire array is allocated, no entries are ever ignored.
5010:    Set after the first MatAssemblyEnd()

5012:    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5013:    that would generate a new entry in the nonzero structure instead produces
5014:    an error. (Currently supported for AIJ and BAIJ formats only.)

5016:    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5017:    that would generate a new entry that has not been preallocated will
5018:    instead produce an error. (Currently supported for AIJ and BAIJ formats
5019:    only.) This is a useful flag when debugging matrix memory preallocation.

5021:    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5022:    other processors should be dropped, rather than stashed.
5023:    This is useful if you know that the "owning" processor is also
5024:    always generating the correct matrix entries, so that PETSc need
5025:    not transfer duplicate entries generated on another processor.

5027:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5028:    searches during matrix assembly. When this flag is set, the hash table
5029:    is created during the first Matrix Assembly. This hash table is
5030:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5031:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5032:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5033:    supported by MATMPIBAIJ format only.

5035:    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5036:    are kept in the nonzero structure

5038:    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5039:    a zero location in the matrix

5041:    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5042:    ROWBS matrix types

5044:    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5045:         zero row routines and thus improves performance for very large process counts.

5047:    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5048:         part of the matrix (since they should match the upper triangular part).

5050:    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.

5052:    Level: intermediate

5054:    Concepts: matrices^setting options

5056: .seealso:  MatOption, Mat

5058: @*/
5059: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool flg)
5060: {

5066:   if (op > 0) {
5069:   }

5071:   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5072:   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");

5074:   switch (op) {
5075:   case MAT_NO_OFF_PROC_ENTRIES:
5076:     mat->nooffprocentries = flg;
5077:     return(0);
5078:     break;
5079:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5080:     mat->nooffproczerorows = flg;
5081:     return(0);
5082:     break;
5083:   case MAT_SPD:
5084:     mat->spd_set = PETSC_TRUE;
5085:     mat->spd     = flg;
5086:     if (flg) {
5087:       mat->symmetric                  = PETSC_TRUE;
5088:       mat->structurally_symmetric     = PETSC_TRUE;
5089:       mat->symmetric_set              = PETSC_TRUE;
5090:       mat->structurally_symmetric_set = PETSC_TRUE;
5091:     }
5092:     break;
5093:   case MAT_SYMMETRIC:
5094:     mat->symmetric = flg;
5095:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5096:     mat->symmetric_set              = PETSC_TRUE;
5097:     mat->structurally_symmetric_set = flg;
5098:     break;
5099:   case MAT_HERMITIAN:
5100:     mat->hermitian = flg;
5101:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5102:     mat->hermitian_set              = PETSC_TRUE;
5103:     mat->structurally_symmetric_set = flg;
5104:     break;
5105:   case MAT_STRUCTURALLY_SYMMETRIC:
5106:     mat->structurally_symmetric     = flg;
5107:     mat->structurally_symmetric_set = PETSC_TRUE;
5108:     break;
5109:   case MAT_SYMMETRY_ETERNAL:
5110:     mat->symmetric_eternal = flg;
5111:     break;
5112:   default:
5113:     break;
5114:   }
5115:   if (mat->ops->setoption) {
5116:     (*mat->ops->setoption)(mat,op,flg);
5117:   }
5118:   return(0);
5119: }

5123: /*@
5124:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5125:    this routine retains the old nonzero structure.

5127:    Logically Collective on Mat

5129:    Input Parameters:
5130: .  mat - the matrix

5132:    Level: intermediate

5134:    Notes: If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase.
5135:    See the Performance chapter of the users manual for information on preallocating matrices.

5137:    Concepts: matrices^zeroing

5139: .seealso: MatZeroRows()
5140: @*/
5141: PetscErrorCode  MatZeroEntries(Mat mat)
5142: {

5148:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5149:   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
5150:   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5151:   MatCheckPreallocated(mat,1);

5153:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5154:   (*mat->ops->zeroentries)(mat);
5155:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5156:   PetscObjectStateIncrease((PetscObject)mat);
5157: #if defined(PETSC_HAVE_CUSP)
5158:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5159:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5160:   }
5161: #endif
5162: #if defined(PETSC_HAVE_VIENNACL)
5163:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5164:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5165:   }
5166: #endif
5167:   return(0);
5168: }

5172: /*@C
5173:    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5174:    of a set of rows and columns of a matrix.

5176:    Collective on Mat

5178:    Input Parameters:
5179: +  mat - the matrix
5180: .  numRows - the number of rows to remove
5181: .  rows - the global row indices
5182: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5183: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5184: -  b - optional vector of right hand side, that will be adjusted by provided solution

5186:    Notes:
5187:    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.

5189:    The user can set a value in the diagonal entry (or for the AIJ and
5190:    row formats can optionally remove the main diagonal entry from the
5191:    nonzero structure as well, by passing 0.0 as the final argument).

5193:    For the parallel case, all processes that share the matrix (i.e.,
5194:    those in the communicator used for matrix creation) MUST call this
5195:    routine, regardless of whether any rows being zeroed are owned by
5196:    them.

5198:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5199:    list only rows local to itself).

5201:    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.

5203:    Level: intermediate

5205:    Concepts: matrices^zeroing rows

5207: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5208: @*/
5209: PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5210: {

5217:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5218:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5219:   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5220:   MatCheckPreallocated(mat,1);

5222:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5223:   MatViewFromOptions(mat,NULL,"-mat_view");
5224:   PetscObjectStateIncrease((PetscObject)mat);
5225: #if defined(PETSC_HAVE_CUSP)
5226:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5227:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5228:   }
5229: #endif
5230: #if defined(PETSC_HAVE_VIENNACL)
5231:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5232:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5233:   }
5234: #endif
5235:   return(0);
5236: }

5240: /*@C
5241:    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5242:    of a set of rows and columns of a matrix.

5244:    Collective on Mat

5246:    Input Parameters:
5247: +  mat - the matrix
5248: .  is - the rows to zero
5249: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5250: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5251: -  b - optional vector of right hand side, that will be adjusted by provided solution

5253:    Notes:
5254:    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.

5256:    The user can set a value in the diagonal entry (or for the AIJ and
5257:    row formats can optionally remove the main diagonal entry from the
5258:    nonzero structure as well, by passing 0.0 as the final argument).

5260:    For the parallel case, all processes that share the matrix (i.e.,
5261:    those in the communicator used for matrix creation) MUST call this
5262:    routine, regardless of whether any rows being zeroed are owned by
5263:    them.

5265:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5266:    list only rows local to itself).

5268:    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.

5270:    Level: intermediate

5272:    Concepts: matrices^zeroing rows

5274: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5275: @*/
5276: PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5277: {
5279:   PetscInt       numRows;
5280:   const PetscInt *rows;

5287:   ISGetLocalSize(is,&numRows);
5288:   ISGetIndices(is,&rows);
5289:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5290:   ISRestoreIndices(is,&rows);
5291:   return(0);
5292: }

5296: /*@C
5297:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5298:    of a set of rows of a matrix.

5300:    Collective on Mat

5302:    Input Parameters:
5303: +  mat - the matrix
5304: .  numRows - the number of rows to remove
5305: .  rows - the global row indices
5306: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5307: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5308: -  b - optional vector of right hand side, that will be adjusted by provided solution

5310:    Notes:
5311:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5312:    but does not release memory.  For the dense and block diagonal
5313:    formats this does not alter the nonzero structure.

5315:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5316:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5317:    merely zeroed.

5319:    The user can set a value in the diagonal entry (or for the AIJ and
5320:    row formats can optionally remove the main diagonal entry from the
5321:    nonzero structure as well, by passing 0.0 as the final argument).

5323:    For the parallel case, all processes that share the matrix (i.e.,
5324:    those in the communicator used for matrix creation) MUST call this
5325:    routine, regardless of whether any rows being zeroed are owned by
5326:    them.

5328:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5329:    list only rows local to itself).

5331:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5332:    owns that are to be zeroed. This saves a global synchronization in the implementation.

5334:    Level: intermediate

5336:    Concepts: matrices^zeroing rows

5338: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5339: @*/
5340: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5341: {

5348:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5349:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5350:   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5351:   MatCheckPreallocated(mat,1);

5353:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5354:   MatViewFromOptions(mat,NULL,"-mat_view");
5355:   PetscObjectStateIncrease((PetscObject)mat);
5356: #if defined(PETSC_HAVE_CUSP)
5357:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5358:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5359:   }
5360: #endif
5361: #if defined(PETSC_HAVE_VIENNACL)
5362:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5363:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5364:   }
5365: #endif
5366:   return(0);
5367: }

5371: /*@C
5372:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5373:    of a set of rows of a matrix.

5375:    Collective on Mat

5377:    Input Parameters:
5378: +  mat - the matrix
5379: .  is - index set of rows to remove
5380: .  diag - value put in all diagonals of eliminated rows
5381: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5382: -  b - optional vector of right hand side, that will be adjusted by provided solution

5384:    Notes:
5385:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5386:    but does not release memory.  For the dense and block diagonal
5387:    formats this does not alter the nonzero structure.

5389:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5390:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5391:    merely zeroed.

5393:    The user can set a value in the diagonal entry (or for the AIJ and
5394:    row formats can optionally remove the main diagonal entry from the
5395:    nonzero structure as well, by passing 0.0 as the final argument).

5397:    For the parallel case, all processes that share the matrix (i.e.,
5398:    those in the communicator used for matrix creation) MUST call this
5399:    routine, regardless of whether any rows being zeroed are owned by
5400:    them.

5402:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5403:    list only rows local to itself).

5405:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5406:    owns that are to be zeroed. This saves a global synchronization in the implementation.

5408:    Level: intermediate

5410:    Concepts: matrices^zeroing rows

5412: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5413: @*/
5414: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5415: {
5416:   PetscInt       numRows;
5417:   const PetscInt *rows;

5424:   ISGetLocalSize(is,&numRows);
5425:   ISGetIndices(is,&rows);
5426:   MatZeroRows(mat,numRows,rows,diag,x,b);
5427:   ISRestoreIndices(is,&rows);
5428:   return(0);
5429: }

5433: /*@C
5434:    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5435:    of a set of rows of a matrix. These rows must be local to the process.

5437:    Collective on Mat

5439:    Input Parameters:
5440: +  mat - the matrix
5441: .  numRows - the number of rows to remove
5442: .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5443: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5444: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5445: -  b - optional vector of right hand side, that will be adjusted by provided solution

5447:    Notes:
5448:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5449:    but does not release memory.  For the dense and block diagonal
5450:    formats this does not alter the nonzero structure.

5452:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5453:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5454:    merely zeroed.

5456:    The user can set a value in the diagonal entry (or for the AIJ and
5457:    row formats can optionally remove the main diagonal entry from the
5458:    nonzero structure as well, by passing 0.0 as the final argument).

5460:    For the parallel case, all processes that share the matrix (i.e.,
5461:    those in the communicator used for matrix creation) MUST call this
5462:    routine, regardless of whether any rows being zeroed are owned by
5463:    them.

5465:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5466:    list only rows local to itself).

5468:    The grid coordinates are across the entire grid, not just the local portion

5470:    In Fortran idxm and idxn should be declared as
5471: $     MatStencil idxm(4,m)
5472:    and the values inserted using
5473: $    idxm(MatStencil_i,1) = i
5474: $    idxm(MatStencil_j,1) = j
5475: $    idxm(MatStencil_k,1) = k
5476: $    idxm(MatStencil_c,1) = c
5477:    etc

5479:    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5480:    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5481:    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5482:    DM_BOUNDARY_PERIODIC boundary type.

5484:    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
5485:    a single value per point) you can skip filling those indices.

5487:    Level: intermediate

5489:    Concepts: matrices^zeroing rows

5491: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5492: @*/
5493: PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5494: {
5495:   PetscInt       dim     = mat->stencil.dim;
5496:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5497:   PetscInt       *dims   = mat->stencil.dims+1;
5498:   PetscInt       *starts = mat->stencil.starts;
5499:   PetscInt       *dxm    = (PetscInt*) rows;
5500:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5508:   PetscMalloc1(numRows, &jdxm);
5509:   for (i = 0; i < numRows; ++i) {
5510:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5511:     for (j = 0; j < 3-sdim; ++j) dxm++;
5512:     /* Local index in X dir */
5513:     tmp = *dxm++ - starts[0];
5514:     /* Loop over remaining dimensions */
5515:     for (j = 0; j < dim-1; ++j) {
5516:       /* If nonlocal, set index to be negative */
5517:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5518:       /* Update local index */
5519:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5520:     }
5521:     /* Skip component slot if necessary */
5522:     if (mat->stencil.noc) dxm++;
5523:     /* Local row number */
5524:     if (tmp >= 0) {
5525:       jdxm[numNewRows++] = tmp;
5526:     }
5527:   }
5528:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5529:   PetscFree(jdxm);
5530:   return(0);
5531: }

5535: /*@C
5536:    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5537:    of a set of rows and columns of a matrix.

5539:    Collective on Mat

5541:    Input Parameters:
5542: +  mat - the matrix
5543: .  numRows - the number of rows/columns to remove
5544: .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5545: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5546: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5547: -  b - optional vector of right hand side, that will be adjusted by provided solution

5549:    Notes:
5550:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5551:    but does not release memory.  For the dense and block diagonal
5552:    formats this does not alter the nonzero structure.

5554:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5555:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5556:    merely zeroed.

5558:    The user can set a value in the diagonal entry (or for the AIJ and
5559:    row formats can optionally remove the main diagonal entry from the
5560:    nonzero structure as well, by passing 0.0 as the final argument).

5562:    For the parallel case, all processes that share the matrix (i.e.,
5563:    those in the communicator used for matrix creation) MUST call this
5564:    routine, regardless of whether any rows being zeroed are owned by
5565:    them.

5567:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5568:    list only rows local to itself, but the row/column numbers are given in local numbering).

5570:    The grid coordinates are across the entire grid, not just the local portion

5572:    In Fortran idxm and idxn should be declared as
5573: $     MatStencil idxm(4,m)
5574:    and the values inserted using
5575: $    idxm(MatStencil_i,1) = i
5576: $    idxm(MatStencil_j,1) = j
5577: $    idxm(MatStencil_k,1) = k
5578: $    idxm(MatStencil_c,1) = c
5579:    etc

5581:    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5582:    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5583:    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5584:    DM_BOUNDARY_PERIODIC boundary type.

5586:    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
5587:    a single value per point) you can skip filling those indices.

5589:    Level: intermediate

5591:    Concepts: matrices^zeroing rows

5593: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5594: @*/
5595: PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5596: {
5597:   PetscInt       dim     = mat->stencil.dim;
5598:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5599:   PetscInt       *dims   = mat->stencil.dims+1;
5600:   PetscInt       *starts = mat->stencil.starts;
5601:   PetscInt       *dxm    = (PetscInt*) rows;
5602:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5610:   PetscMalloc1(numRows, &jdxm);
5611:   for (i = 0; i < numRows; ++i) {
5612:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5613:     for (j = 0; j < 3-sdim; ++j) dxm++;
5614:     /* Local index in X dir */
5615:     tmp = *dxm++ - starts[0];
5616:     /* Loop over remaining dimensions */
5617:     for (j = 0; j < dim-1; ++j) {
5618:       /* If nonlocal, set index to be negative */
5619:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5620:       /* Update local index */
5621:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5622:     }
5623:     /* Skip component slot if necessary */
5624:     if (mat->stencil.noc) dxm++;
5625:     /* Local row number */
5626:     if (tmp >= 0) {
5627:       jdxm[numNewRows++] = tmp;
5628:     }
5629:   }
5630:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5631:   PetscFree(jdxm);
5632:   return(0);
5633: }

5637: /*@C
5638:    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5639:    of a set of rows of a matrix; using local numbering of rows.

5641:    Collective on Mat

5643:    Input Parameters:
5644: +  mat - the matrix
5645: .  numRows - the number of rows to remove
5646: .  rows - the global row indices
5647: .  diag - value put in all diagonals of eliminated rows
5648: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5649: -  b - optional vector of right hand side, that will be adjusted by provided solution

5651:    Notes:
5652:    Before calling MatZeroRowsLocal(), the user must first set the
5653:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5655:    For the AIJ matrix formats this removes the old nonzero structure,
5656:    but does not release memory.  For the dense and block diagonal
5657:    formats this does not alter the nonzero structure.

5659:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5660:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5661:    merely zeroed.

5663:    The user can set a value in the diagonal entry (or for the AIJ and
5664:    row formats can optionally remove the main diagonal entry from the
5665:    nonzero structure as well, by passing 0.0 as the final argument).

5667:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5668:    owns that are to be zeroed. This saves a global synchronization in the implementation.

5670:    Level: intermediate

5672:    Concepts: matrices^zeroing

5674: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5675: @*/
5676: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5677: {

5684:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5685:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5686:   MatCheckPreallocated(mat,1);

5688:   if (mat->ops->zerorowslocal) {
5689:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5690:   } else {
5691:     IS             is, newis;
5692:     const PetscInt *newRows;

5694:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5695:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5696:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5697:     ISGetIndices(newis,&newRows);
5698:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5699:     ISRestoreIndices(newis,&newRows);
5700:     ISDestroy(&newis);
5701:     ISDestroy(&is);
5702:   }
5703:   PetscObjectStateIncrease((PetscObject)mat);
5704: #if defined(PETSC_HAVE_CUSP)
5705:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5706:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5707:   }
5708: #endif
5709: #if defined(PETSC_HAVE_VIENNACL)
5710:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5711:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5712:   }
5713: #endif
5714:   return(0);
5715: }

5719: /*@C
5720:    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5721:    of a set of rows of a matrix; using local numbering of rows.

5723:    Collective on Mat

5725:    Input Parameters:
5726: +  mat - the matrix
5727: .  is - index set of rows to remove
5728: .  diag - value put in all diagonals of eliminated rows
5729: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5730: -  b - optional vector of right hand side, that will be adjusted by provided solution

5732:    Notes:
5733:    Before calling MatZeroRowsLocalIS(), the user must first set the
5734:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5736:    For the AIJ matrix formats this removes the old nonzero structure,
5737:    but does not release memory.  For the dense and block diagonal
5738:    formats this does not alter the nonzero structure.

5740:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5741:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5742:    merely zeroed.

5744:    The user can set a value in the diagonal entry (or for the AIJ and
5745:    row formats can optionally remove the main diagonal entry from the
5746:    nonzero structure as well, by passing 0.0 as the final argument).

5748:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5749:    owns that are to be zeroed. This saves a global synchronization in the implementation.

5751:    Level: intermediate

5753:    Concepts: matrices^zeroing

5755: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5756: @*/
5757: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5758: {
5760:   PetscInt       numRows;
5761:   const PetscInt *rows;

5767:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5768:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5769:   MatCheckPreallocated(mat,1);

5771:   ISGetLocalSize(is,&numRows);
5772:   ISGetIndices(is,&rows);
5773:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5774:   ISRestoreIndices(is,&rows);
5775:   return(0);
5776: }

5780: /*@C
5781:    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5782:    of a set of rows and columns of a matrix; using local numbering of rows.

5784:    Collective on Mat

5786:    Input Parameters:
5787: +  mat - the matrix
5788: .  numRows - the number of rows to remove
5789: .  rows - the global row indices
5790: .  diag - value put in all diagonals of eliminated rows
5791: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5792: -  b - optional vector of right hand side, that will be adjusted by provided solution

5794:    Notes:
5795:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5796:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5798:    The user can set a value in the diagonal entry (or for the AIJ and
5799:    row formats can optionally remove the main diagonal entry from the
5800:    nonzero structure as well, by passing 0.0 as the final argument).

5802:    Level: intermediate

5804:    Concepts: matrices^zeroing

5806: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5807: @*/
5808: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5809: {
5811:   IS             is, newis;
5812:   const PetscInt *newRows;

5818:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5819:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5820:   MatCheckPreallocated(mat,1);

5822:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5823:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5824:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5825:   ISGetIndices(newis,&newRows);
5826:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5827:   ISRestoreIndices(newis,&newRows);
5828:   ISDestroy(&newis);
5829:   ISDestroy(&is);
5830:   PetscObjectStateIncrease((PetscObject)mat);
5831: #if defined(PETSC_HAVE_CUSP)
5832:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5833:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5834:   }
5835: #endif
5836: #if defined(PETSC_HAVE_VIENNACL)
5837:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5838:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5839:   }
5840: #endif
5841:   return(0);
5842: }

5846: /*@C
5847:    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5848:    of a set of rows and columns of a matrix; using local numbering of rows.

5850:    Collective on Mat

5852:    Input Parameters:
5853: +  mat - the matrix
5854: .  is - index set of rows to remove
5855: .  diag - value put in all diagonals of eliminated rows
5856: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5857: -  b - optional vector of right hand side, that will be adjusted by provided solution

5859:    Notes:
5860:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5861:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5863:    The user can set a value in the diagonal entry (or for the AIJ and
5864:    row formats can optionally remove the main diagonal entry from the
5865:    nonzero structure as well, by passing 0.0 as the final argument).

5867:    Level: intermediate

5869:    Concepts: matrices^zeroing

5871: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5872: @*/
5873: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5874: {
5876:   PetscInt       numRows;
5877:   const PetscInt *rows;

5883:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5884:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5885:   MatCheckPreallocated(mat,1);

5887:   ISGetLocalSize(is,&numRows);
5888:   ISGetIndices(is,&rows);
5889:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5890:   ISRestoreIndices(is,&rows);
5891:   return(0);
5892: }

5896: /*@
5897:    MatGetSize - Returns the numbers of rows and columns in a matrix.

5899:    Not Collective

5901:    Input Parameter:
5902: .  mat - the matrix

5904:    Output Parameters:
5905: +  m - the number of global rows
5906: -  n - the number of global columns

5908:    Note: both output parameters can be NULL on input.

5910:    Level: beginner

5912:    Concepts: matrices^size

5914: .seealso: MatGetLocalSize()
5915: @*/
5916: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
5917: {
5920:   if (m) *m = mat->rmap->N;
5921:   if (n) *n = mat->cmap->N;
5922:   return(0);
5923: }

5927: /*@
5928:    MatGetLocalSize - Returns the number of rows and columns in a matrix
5929:    stored locally.  This information may be implementation dependent, so
5930:    use with care.

5932:    Not Collective

5934:    Input Parameters:
5935: .  mat - the matrix

5937:    Output Parameters:
5938: +  m - the number of local rows
5939: -  n - the number of local columns

5941:    Note: both output parameters can be NULL on input.

5943:    Level: beginner

5945:    Concepts: matrices^local size

5947: .seealso: MatGetSize()
5948: @*/
5949: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
5950: {
5955:   if (m) *m = mat->rmap->n;
5956:   if (n) *n = mat->cmap->n;
5957:   return(0);
5958: }

5962: /*@
5963:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5964:    this processor. (The columns of the "diagonal block")

5966:    Not Collective, unless matrix has not been allocated, then collective on Mat

5968:    Input Parameters:
5969: .  mat - the matrix

5971:    Output Parameters:
5972: +  m - the global index of the first local column
5973: -  n - one more than the global index of the last local column

5975:    Notes: both output parameters can be NULL on input.

5977:    Level: developer

5979:    Concepts: matrices^column ownership

5981: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

5983: @*/
5984: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
5985: {
5991:   MatCheckPreallocated(mat,1);
5992:   if (m) *m = mat->cmap->rstart;
5993:   if (n) *n = mat->cmap->rend;
5994:   return(0);
5995: }

5999: /*@
6000:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6001:    this processor, assuming that the matrix is laid out with the first
6002:    n1 rows on the first processor, the next n2 rows on the second, etc.
6003:    For certain parallel layouts this range may not be well defined.

6005:    Not Collective

6007:    Input Parameters:
6008: .  mat - the matrix

6010:    Output Parameters:
6011: +  m - the global index of the first local row
6012: -  n - one more than the global index of the last local row

6014:    Note: Both output parameters can be NULL on input.
6015: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6016: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6017: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

6019:    Level: beginner

6021:    Concepts: matrices^row ownership

6023: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

6025: @*/
6026: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6027: {
6033:   MatCheckPreallocated(mat,1);
6034:   if (m) *m = mat->rmap->rstart;
6035:   if (n) *n = mat->rmap->rend;
6036:   return(0);
6037: }

6041: /*@C
6042:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6043:    each process

6045:    Not Collective, unless matrix has not been allocated, then collective on Mat

6047:    Input Parameters:
6048: .  mat - the matrix

6050:    Output Parameters:
6051: .  ranges - start of each processors portion plus one more then the total length at the end

6053:    Level: beginner

6055:    Concepts: matrices^row ownership

6057: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6059: @*/
6060: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6061: {

6067:   MatCheckPreallocated(mat,1);
6068:   PetscLayoutGetRanges(mat->rmap,ranges);
6069:   return(0);
6070: }

6074: /*@C
6075:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6076:    this processor. (The columns of the "diagonal blocks" for each process)

6078:    Not Collective, unless matrix has not been allocated, then collective on Mat

6080:    Input Parameters:
6081: .  mat - the matrix

6083:    Output Parameters:
6084: .  ranges - start of each processors portion plus one more then the total length at the end

6086:    Level: beginner

6088:    Concepts: matrices^column ownership

6090: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6092: @*/
6093: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6094: {

6100:   MatCheckPreallocated(mat,1);
6101:   PetscLayoutGetRanges(mat->cmap,ranges);
6102:   return(0);
6103: }

6107: /*@C
6108:    MatGetOwnershipIS - Get row and column ownership as index sets

6110:    Not Collective

6112:    Input Arguments:
6113: .  A - matrix of type Elemental

6115:    Output Arguments:
6116: +  rows - rows in which this process owns elements
6117: .  cols - columns in which this process owns elements

6119:    Level: intermediate

6121: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6122: @*/
6123: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6124: {
6125:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6128:   MatCheckPreallocated(A,1);
6129:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6130:   if (f) {
6131:     (*f)(A,rows,cols);
6132:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6133:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6134:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6135:   }
6136:   return(0);
6137: }

6141: /*@C
6142:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6143:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6144:    to complete the factorization.

6146:    Collective on Mat

6148:    Input Parameters:
6149: +  mat - the matrix
6150: .  row - row permutation
6151: .  column - column permutation
6152: -  info - structure containing
6153: $      levels - number of levels of fill.
6154: $      expected fill - as ratio of original fill.
6155: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6156:                 missing diagonal entries)

6158:    Output Parameters:
6159: .  fact - new matrix that has been symbolically factored

6161:    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.

6163:    Most users should employ the simplified KSP interface for linear solvers
6164:    instead of working directly with matrix algebra routines such as this.
6165:    See, e.g., KSPCreate().

6167:    Level: developer

6169:   Concepts: matrices^symbolic LU factorization
6170:   Concepts: matrices^factorization
6171:   Concepts: LU^symbolic factorization

6173: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6174:           MatGetOrdering(), MatFactorInfo

6176:     Developer Note: fortran interface is not autogenerated as the f90
6177:     interface defintion cannot be generated correctly [due to MatFactorInfo]

6179: @*/
6180: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6181: {

6191:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6192:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6193:   if (!(fact)->ops->ilufactorsymbolic) {
6194:     const MatSolverPackage spackage;
6195:     MatFactorGetSolverPackage(fact,&spackage);
6196:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6197:   }
6198:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6199:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6200:   MatCheckPreallocated(mat,2);

6202:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6203:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6204:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6205:   return(0);
6206: }

6210: /*@C
6211:    MatICCFactorSymbolic - Performs symbolic incomplete
6212:    Cholesky factorization for a symmetric matrix.  Use
6213:    MatCholeskyFactorNumeric() to complete the factorization.

6215:    Collective on Mat

6217:    Input Parameters:
6218: +  mat - the matrix
6219: .  perm - row and column permutation
6220: -  info - structure containing
6221: $      levels - number of levels of fill.
6222: $      expected fill - as ratio of original fill.

6224:    Output Parameter:
6225: .  fact - the factored matrix

6227:    Notes:
6228:    Most users should employ the KSP interface for linear solvers
6229:    instead of working directly with matrix algebra routines such as this.
6230:    See, e.g., KSPCreate().

6232:    Level: developer

6234:   Concepts: matrices^symbolic incomplete Cholesky factorization
6235:   Concepts: matrices^factorization
6236:   Concepts: Cholsky^symbolic factorization

6238: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

6240:     Developer Note: fortran interface is not autogenerated as the f90
6241:     interface defintion cannot be generated correctly [due to MatFactorInfo]

6243: @*/
6244: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6245: {

6254:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6255:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6256:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6257:   if (!(fact)->ops->iccfactorsymbolic) {
6258:     const MatSolverPackage spackage;
6259:     MatFactorGetSolverPackage(fact,&spackage);
6260:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6261:   }
6262:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6263:   MatCheckPreallocated(mat,2);

6265:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6266:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6267:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6268:   return(0);
6269: }

6273: /*@C
6274:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6275:    points to an array of valid matrices, they may be reused to store the new
6276:    submatrices.

6278:    Collective on Mat

6280:    Input Parameters:
6281: +  mat - the matrix
6282: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6283: .  irow, icol - index sets of rows and columns to extract (must be sorted)
6284: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6286:    Output Parameter:
6287: .  submat - the array of submatrices

6289:    Notes:
6290:    MatGetSubMatrices() can extract ONLY sequential submatrices
6291:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6292:    to extract a parallel submatrix.

6294:    Currently both row and column indices must be sorted to guarantee
6295:    correctness with all matrix types.

6297:    When extracting submatrices from a parallel matrix, each processor can
6298:    form a different submatrix by setting the rows and columns of its
6299:    individual index sets according to the local submatrix desired.

6301:    When finished using the submatrices, the user should destroy
6302:    them with MatDestroyMatrices().

6304:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6305:    original matrix has not changed from that last call to MatGetSubMatrices().

6307:    This routine creates the matrices in submat; you should NOT create them before
6308:    calling it. It also allocates the array of matrix pointers submat.

6310:    For BAIJ matrices the index sets must respect the block structure, that is if they
6311:    request one row/column in a block, they must request all rows/columns that are in
6312:    that block. For example, if the block size is 2 you cannot request just row 0 and
6313:    column 0.

6315:    Fortran Note:
6316:    The Fortran interface is slightly different from that given below; it
6317:    requires one to pass in  as submat a Mat (integer) array of size at least m.

6319:    Level: advanced

6321:    Concepts: matrices^accessing submatrices
6322:    Concepts: submatrices

6324: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6325: @*/
6326: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6327: {
6329:   PetscInt       i;
6330:   PetscBool      eq;

6335:   if (n) {
6340:   }
6342:   if (n && scall == MAT_REUSE_MATRIX) {
6345:   }
6346:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6347:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6348:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6349:   MatCheckPreallocated(mat,1);

6351:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6352:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6353:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6354:   for (i=0; i<n; i++) {
6355:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6356:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6357:       ISEqual(irow[i],icol[i],&eq);
6358:       if (eq) {
6359:         if (mat->symmetric) {
6360:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6361:         } else if (mat->hermitian) {
6362:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6363:         } else if (mat->structurally_symmetric) {
6364:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6365:         }
6366:       }
6367:     }
6368:   }
6369:   return(0);
6370: }

6374: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6375: {
6377:   PetscInt       i;
6378:   PetscBool      eq;

6383:   if (n) {
6388:   }
6390:   if (n && scall == MAT_REUSE_MATRIX) {
6393:   }
6394:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6395:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6396:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6397:   MatCheckPreallocated(mat,1);

6399:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6400:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6401:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6402:   for (i=0; i<n; i++) {
6403:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6404:       ISEqual(irow[i],icol[i],&eq);
6405:       if (eq) {
6406:         if (mat->symmetric) {
6407:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6408:         } else if (mat->hermitian) {
6409:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6410:         } else if (mat->structurally_symmetric) {
6411:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6412:         }
6413:       }
6414:     }
6415:   }
6416:   return(0);
6417: }

6421: /*@C
6422:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().

6424:    Collective on Mat

6426:    Input Parameters:
6427: +  n - the number of local matrices
6428: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6429:                        sequence of MatGetSubMatrices())

6431:    Level: advanced

6433:     Notes: Frees not only the matrices, but also the array that contains the matrices
6434:            In Fortran will not free the array.

6436: .seealso: MatGetSubMatrices()
6437: @*/
6438: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6439: {
6441:   PetscInt       i;

6444:   if (!*mat) return(0);
6445:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6447:   for (i=0; i<n; i++) {
6448:     MatDestroy(&(*mat)[i]);
6449:   }
6450:   /* memory is allocated even if n = 0 */
6451:   PetscFree(*mat);
6452:   *mat = NULL;
6453:   return(0);
6454: }

6458: /*@C
6459:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.

6461:    Collective on Mat

6463:    Input Parameters:
6464: .  mat - the matrix

6466:    Output Parameter:
6467: .  matstruct - the sequential matrix with the nonzero structure of mat

6469:   Level: intermediate

6471: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6472: @*/
6473: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6474: {


6482:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6483:   MatCheckPreallocated(mat,1);

6485:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6486:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6487:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6488:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6489:   return(0);
6490: }

6494: /*@C
6495:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6497:    Collective on Mat

6499:    Input Parameters:
6500: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6501:                        sequence of MatGetSequentialNonzeroStructure())

6503:    Level: advanced

6505:     Notes: Frees not only the matrices, but also the array that contains the matrices

6507: .seealso: MatGetSeqNonzeroStructure()
6508: @*/
6509: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6510: {

6515:   MatDestroy(mat);
6516:   return(0);
6517: }

6521: /*@
6522:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6523:    replaces the index sets by larger ones that represent submatrices with
6524:    additional overlap.

6526:    Collective on Mat

6528:    Input Parameters:
6529: +  mat - the matrix
6530: .  n   - the number of index sets
6531: .  is  - the array of index sets (these index sets will changed during the call)
6532: -  ov  - the additional overlap requested

6534:    Level: developer

6536:    Concepts: overlap
6537:    Concepts: ASM^computing overlap

6539: .seealso: MatGetSubMatrices()
6540: @*/
6541: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6542: {

6548:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6549:   if (n) {
6552:   }
6553:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6554:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6555:   MatCheckPreallocated(mat,1);

6557:   if (!ov) return(0);
6558:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6559:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6560:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6561:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6562:   return(0);
6563: }

6567: /*@
6568:    MatGetBlockSize - Returns the matrix block size; useful especially for the
6569:    block row and block diagonal formats.

6571:    Not Collective

6573:    Input Parameter:
6574: .  mat - the matrix

6576:    Output Parameter:
6577: .  bs - block size

6579:    Notes:
6580:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ.

6582:    If the block size has not been set yet this routine returns -1.

6584:    Level: intermediate

6586:    Concepts: matrices^block size

6588: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6589: @*/
6590: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6591: {
6595:   *bs = PetscAbs(mat->rmap->bs);
6596:   return(0);
6597: }

6601: /*@
6602:    MatGetBlockSizes - Returns the matrix block row and column sizes;
6603:    useful especially for the block row and block diagonal formats.

6605:    Not Collective

6607:    Input Parameter:
6608: .  mat - the matrix

6610:    Output Parameter:
6611: .  rbs - row block size
6612: .  cbs - coumn block size

6614:    Notes:
6615:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ.

6617:    If a block size has not been set yet this routine returns -1.

6619:    Level: intermediate

6621:    Concepts: matrices^block size

6623: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6624: @*/
6625: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6626: {
6631:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
6632:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
6633:   return(0);
6634: }

6638: /*@
6639:    MatSetBlockSize - Sets the matrix block size.

6641:    Logically Collective on Mat

6643:    Input Parameters:
6644: +  mat - the matrix
6645: -  bs - block size

6647:    Notes:
6648:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6650:    Level: intermediate

6652:    Concepts: matrices^block size

6654: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6655: @*/
6656: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6657: {

6663:   PetscLayoutSetBlockSize(mat->rmap,bs);
6664:   PetscLayoutSetBlockSize(mat->cmap,bs);
6665:   return(0);
6666: }

6670: /*@
6671:    MatSetBlockSizes - Sets the matrix block row and column sizes.

6673:    Logically Collective on Mat

6675:    Input Parameters:
6676: +  mat - the matrix
6677: -  rbs - row block size
6678: -  cbs - column block size

6680:    Notes:
6681:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6683:    Level: intermediate

6685:    Concepts: matrices^block size

6687: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6688: @*/
6689: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6690: {

6697:   PetscLayoutSetBlockSize(mat->rmap,rbs);
6698:   PetscLayoutSetBlockSize(mat->cmap,cbs);
6699:   return(0);
6700: }

6704: /*@
6705:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

6707:    Logically Collective on Mat

6709:    Input Parameters:
6710: +  mat - the matrix
6711: .  fromRow - matrix from which to copy row block size
6712: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

6714:    Level: developer

6716:    Concepts: matrices^block size

6718: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
6719: @*/
6720: PetscErrorCode  MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
6721: {

6728:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
6729:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
6730:   return(0);
6731: }

6735: /*@
6736:    MatResidual - Default routine to calculate the residual.

6738:    Collective on Mat and Vec

6740:    Input Parameters:
6741: +  mat - the matrix
6742: .  b   - the right-hand-side
6743: -  x   - the approximate solution

6745:    Output Parameter:
6746: .  r - location to store the residual

6748:    Level: developer

6750: .keywords: MG, default, multigrid, residual

6752: .seealso: PCMGSetResidual()
6753: @*/
6754: PetscErrorCode  MatResidual(Mat mat,Vec b,Vec x,Vec r)
6755: {

6764:   MatCheckPreallocated(mat,1);
6765:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
6766:   if (!mat->ops->residual) {
6767:     MatMult(mat,x,r);
6768:     VecAYPX(r,-1.0,b);
6769:   } else {
6770:     (*mat->ops->residual)(mat,b,x,r);
6771:   }
6772:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
6773:   return(0);
6774: }

6778: /*@C
6779:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.

6781:    Collective on Mat

6783:     Input Parameters:
6784: +   mat - the matrix
6785: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6786: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6787: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6788:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6789:                  always used.

6791:     Output Parameters:
6792: +   n - number of rows in the (possibly compressed) matrix
6793: .   ia - the row pointers [of length n+1]
6794: .   ja - the column indices
6795: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6796:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

6798:     Level: developer

6800:     Notes: You CANNOT change any of the ia[] or ja[] values.

6802:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

6804:     Fortran Node

6806:            In Fortran use
6807: $           PetscInt ia(1), ja(1)
6808: $           PetscOffset iia, jja
6809: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6810: $
6811: $          or
6812: $
6813: $           PetscScalar, pointer :: xx_v(:)
6814: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)


6817:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

6819: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6820: @*/
6821: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6822: {

6832:   MatCheckPreallocated(mat,1);
6833:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6834:   else {
6835:     *done = PETSC_TRUE;
6836:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6837:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6838:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6839:   }
6840:   return(0);
6841: }

6845: /*@C
6846:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.

6848:     Collective on Mat

6850:     Input Parameters:
6851: +   mat - the matrix
6852: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6853: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6854:                 symmetrized
6855: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6856:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6857:                  always used.
6858: .   n - number of columns in the (possibly compressed) matrix
6859: .   ia - the column pointers
6860: -   ja - the row indices

6862:     Output Parameters:
6863: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6865:     Note:
6866:     This routine zeros out n, ia, and ja. This is to prevent accidental
6867:     us of the array after it has been restored. If you pass NULL, it will
6868:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

6870:     Level: developer

6872: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6873: @*/
6874: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6875: {

6885:   MatCheckPreallocated(mat,1);
6886:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6887:   else {
6888:     *done = PETSC_TRUE;
6889:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6890:   }
6891:   return(0);
6892: }

6896: /*@C
6897:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6898:     MatGetRowIJ().

6900:     Collective on Mat

6902:     Input Parameters:
6903: +   mat - the matrix
6904: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6905: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6906:                 symmetrized
6907: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6908:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6909:                  always used.
6910: .   n - size of (possibly compressed) matrix
6911: .   ia - the row pointers
6912: -   ja - the column indices

6914:     Output Parameters:
6915: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6917:     Note:
6918:     This routine zeros out n, ia, and ja. This is to prevent accidental
6919:     us of the array after it has been restored. If you pass NULL, it will
6920:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

6922:     Level: developer

6924: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6925: @*/
6926: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6927: {

6936:   MatCheckPreallocated(mat,1);

6938:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6939:   else {
6940:     *done = PETSC_TRUE;
6941:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6942:     if (n)  *n = 0;
6943:     if (ia) *ia = NULL;
6944:     if (ja) *ja = NULL;
6945:   }
6946:   return(0);
6947: }

6951: /*@C
6952:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6953:     MatGetColumnIJ().

6955:     Collective on Mat

6957:     Input Parameters:
6958: +   mat - the matrix
6959: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6960: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6961:                 symmetrized
6962: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6963:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6964:                  always used.

6966:     Output Parameters:
6967: +   n - size of (possibly compressed) matrix
6968: .   ia - the column pointers
6969: .   ja - the row indices
6970: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6972:     Level: developer

6974: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6975: @*/
6976: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6977: {

6986:   MatCheckPreallocated(mat,1);

6988:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6989:   else {
6990:     *done = PETSC_TRUE;
6991:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6992:     if (n)  *n = 0;
6993:     if (ia) *ia = NULL;
6994:     if (ja) *ja = NULL;
6995:   }
6996:   return(0);
6997: }

7001: /*@C
7002:     MatColoringPatch -Used inside matrix coloring routines that
7003:     use MatGetRowIJ() and/or MatGetColumnIJ().

7005:     Collective on Mat

7007:     Input Parameters:
7008: +   mat - the matrix
7009: .   ncolors - max color value
7010: .   n   - number of entries in colorarray
7011: -   colorarray - array indicating color for each column

7013:     Output Parameters:
7014: .   iscoloring - coloring generated using colorarray information

7016:     Level: developer

7018: .seealso: MatGetRowIJ(), MatGetColumnIJ()

7020: @*/
7021: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7022: {

7030:   MatCheckPreallocated(mat,1);

7032:   if (!mat->ops->coloringpatch) {
7033:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);
7034:   } else {
7035:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7036:   }
7037:   return(0);
7038: }


7043: /*@
7044:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.

7046:    Logically Collective on Mat

7048:    Input Parameter:
7049: .  mat - the factored matrix to be reset

7051:    Notes:
7052:    This routine should be used only with factored matrices formed by in-place
7053:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7054:    format).  This option can save memory, for example, when solving nonlinear
7055:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7056:    ILU(0) preconditioner.

7058:    Note that one can specify in-place ILU(0) factorization by calling
7059: .vb
7060:      PCType(pc,PCILU);
7061:      PCFactorSeUseInPlace(pc);
7062: .ve
7063:    or by using the options -pc_type ilu -pc_factor_in_place

7065:    In-place factorization ILU(0) can also be used as a local
7066:    solver for the blocks within the block Jacobi or additive Schwarz
7067:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7068:    for details on setting local solver options.

7070:    Most users should employ the simplified KSP interface for linear solvers
7071:    instead of working directly with matrix algebra routines such as this.
7072:    See, e.g., KSPCreate().

7074:    Level: developer

7076: .seealso: PCFactorSetUseInPlace()

7078:    Concepts: matrices^unfactored

7080: @*/
7081: PetscErrorCode  MatSetUnfactored(Mat mat)
7082: {

7088:   MatCheckPreallocated(mat,1);
7089:   mat->factortype = MAT_FACTOR_NONE;
7090:   if (!mat->ops->setunfactored) return(0);
7091:   (*mat->ops->setunfactored)(mat);
7092:   return(0);
7093: }

7095: /*MC
7096:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7098:     Synopsis:
7099:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7101:     Not collective

7103:     Input Parameter:
7104: .   x - matrix

7106:     Output Parameters:
7107: +   xx_v - the Fortran90 pointer to the array
7108: -   ierr - error code

7110:     Example of Usage:
7111: .vb
7112:       PetscScalar, pointer xx_v(:,:)
7113:       ....
7114:       call MatDenseGetArrayF90(x,xx_v,ierr)
7115:       a = xx_v(3)
7116:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7117: .ve

7119:     Level: advanced

7121: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()

7123:     Concepts: matrices^accessing array

7125: M*/

7127: /*MC
7128:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7129:     accessed with MatDenseGetArrayF90().

7131:     Synopsis:
7132:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7134:     Not collective

7136:     Input Parameters:
7137: +   x - matrix
7138: -   xx_v - the Fortran90 pointer to the array

7140:     Output Parameter:
7141: .   ierr - error code

7143:     Example of Usage:
7144: .vb
7145:        PetscScalar, pointer xx_v(:)
7146:        ....
7147:        call MatDenseGetArrayF90(x,xx_v,ierr)
7148:        a = xx_v(3)
7149:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7150: .ve

7152:     Level: advanced

7154: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()

7156: M*/


7159: /*MC
7160:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7162:     Synopsis:
7163:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7165:     Not collective

7167:     Input Parameter:
7168: .   x - matrix

7170:     Output Parameters:
7171: +   xx_v - the Fortran90 pointer to the array
7172: -   ierr - error code

7174:     Example of Usage:
7175: .vb
7176:       PetscScalar, pointer xx_v(:,:)
7177:       ....
7178:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7179:       a = xx_v(3)
7180:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7181: .ve

7183:     Level: advanced

7185: .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()

7187:     Concepts: matrices^accessing array

7189: M*/

7191: /*MC
7192:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7193:     accessed with MatSeqAIJGetArrayF90().

7195:     Synopsis:
7196:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7198:     Not collective

7200:     Input Parameters:
7201: +   x - matrix
7202: -   xx_v - the Fortran90 pointer to the array

7204:     Output Parameter:
7205: .   ierr - error code

7207:     Example of Usage:
7208: .vb
7209:        PetscScalar, pointer xx_v(:)
7210:        ....
7211:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7212:        a = xx_v(3)
7213:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7214: .ve

7216:     Level: advanced

7218: .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()

7220: M*/


7225: /*@
7226:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7227:                       as the original matrix.

7229:     Collective on Mat

7231:     Input Parameters:
7232: +   mat - the original matrix
7233: .   isrow - parallel IS containing the rows this processor should obtain
7234: .   iscol - parallel IS containing all columns you wish to keep. Each process should list the columns that will be in IT's "diagonal part" in the new matrix.
7235: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7237:     Output Parameter:
7238: .   newmat - the new submatrix, of the same type as the old

7240:     Level: advanced

7242:     Notes:
7243:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7245:     The rows in isrow will be sorted into the same order as the original matrix on each process.

7247:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7248:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7249:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7250:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7251:    you are finished using it.

7253:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7254:     the input matrix.

7256:     If iscol is NULL then all columns are obtained (not supported in Fortran).

7258:    Example usage:
7259:    Consider the following 8x8 matrix with 34 non-zero values, that is
7260:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7261:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7262:    as follows:

7264: .vb
7265:             1  2  0  |  0  3  0  |  0  4
7266:     Proc0   0  5  6  |  7  0  0  |  8  0
7267:             9  0 10  | 11  0  0  | 12  0
7268:     -------------------------------------
7269:            13  0 14  | 15 16 17  |  0  0
7270:     Proc1   0 18  0  | 19 20 21  |  0  0
7271:             0  0  0  | 22 23  0  | 24  0
7272:     -------------------------------------
7273:     Proc2  25 26 27  |  0  0 28  | 29  0
7274:            30  0  0  | 31 32 33  |  0 34
7275: .ve

7277:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7279: .vb
7280:             2  0  |  0  3  0  |  0
7281:     Proc0   5  6  |  7  0  0  |  8
7282:     -------------------------------
7283:     Proc1  18  0  | 19 20 21  |  0
7284:     -------------------------------
7285:     Proc2  26 27  |  0  0 28  | 29
7286:             0  0  | 31 32 33  |  0
7287: .ve


7290:     Concepts: matrices^submatrices

7292: .seealso: MatGetSubMatrices()
7293: @*/
7294: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7295: {
7297:   PetscMPIInt    size;
7298:   Mat            *local;
7299:   IS             iscoltmp;

7308:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7309:   MatCheckPreallocated(mat,1);
7310:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7312:   if (!iscol) {
7313:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7314:   } else {
7315:     iscoltmp = iscol;
7316:   }

7318:   /* if original matrix is on just one processor then use submatrix generated */
7319:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7320:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7321:     if (!iscol) {ISDestroy(&iscoltmp);}
7322:     return(0);
7323:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7324:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7325:     *newmat = *local;
7326:     PetscFree(local);
7327:     if (!iscol) {ISDestroy(&iscoltmp);}
7328:     return(0);
7329:   } else if (!mat->ops->getsubmatrix) {
7330:     /* Create a new matrix type that implements the operation using the full matrix */
7331:     switch (cll) {
7332:     case MAT_INITIAL_MATRIX:
7333:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7334:       break;
7335:     case MAT_REUSE_MATRIX:
7336:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7337:       break;
7338:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7339:     }
7340:     if (!iscol) {ISDestroy(&iscoltmp);}
7341:     return(0);
7342:   }

7344:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7345:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7346:   if (!iscol) {ISDestroy(&iscoltmp);}
7347:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7348:   return(0);
7349: }

7353: /*@
7354:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7355:    used during the assembly process to store values that belong to
7356:    other processors.

7358:    Not Collective

7360:    Input Parameters:
7361: +  mat   - the matrix
7362: .  size  - the initial size of the stash.
7363: -  bsize - the initial size of the block-stash(if used).

7365:    Options Database Keys:
7366: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7367: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7369:    Level: intermediate

7371:    Notes:
7372:      The block-stash is used for values set with MatSetValuesBlocked() while
7373:      the stash is used for values set with MatSetValues()

7375:      Run with the option -info and look for output of the form
7376:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7377:      to determine the appropriate value, MM, to use for size and
7378:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7379:      to determine the value, BMM to use for bsize

7381:    Concepts: stash^setting matrix size
7382:    Concepts: matrices^stash

7384: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7386: @*/
7387: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7388: {

7394:   MatStashSetInitialSize_Private(&mat->stash,size);
7395:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7396:   return(0);
7397: }

7401: /*@
7402:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7403:      the matrix

7405:    Neighbor-wise Collective on Mat

7407:    Input Parameters:
7408: +  mat   - the matrix
7409: .  x,y - the vectors
7410: -  w - where the result is stored

7412:    Level: intermediate

7414:    Notes:
7415:     w may be the same vector as y.

7417:     This allows one to use either the restriction or interpolation (its transpose)
7418:     matrix to do the interpolation

7420:     Concepts: interpolation

7422: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7424: @*/
7425: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7426: {
7428:   PetscInt       M,N,Ny;

7436:   MatCheckPreallocated(A,1);
7437:   MatGetSize(A,&M,&N);
7438:   VecGetSize(y,&Ny);
7439:   if (M == Ny) {
7440:     MatMultAdd(A,x,y,w);
7441:   } else {
7442:     MatMultTransposeAdd(A,x,y,w);
7443:   }
7444:   return(0);
7445: }

7449: /*@
7450:    MatInterpolate - y = A*x or A'*x depending on the shape of
7451:      the matrix

7453:    Neighbor-wise Collective on Mat

7455:    Input Parameters:
7456: +  mat   - the matrix
7457: -  x,y - the vectors

7459:    Level: intermediate

7461:    Notes:
7462:     This allows one to use either the restriction or interpolation (its transpose)
7463:     matrix to do the interpolation

7465:    Concepts: matrices^interpolation

7467: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7469: @*/
7470: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7471: {
7473:   PetscInt       M,N,Ny;

7480:   MatCheckPreallocated(A,1);
7481:   MatGetSize(A,&M,&N);
7482:   VecGetSize(y,&Ny);
7483:   if (M == Ny) {
7484:     MatMult(A,x,y);
7485:   } else {
7486:     MatMultTranspose(A,x,y);
7487:   }
7488:   return(0);
7489: }

7493: /*@
7494:    MatRestrict - y = A*x or A'*x

7496:    Neighbor-wise Collective on Mat

7498:    Input Parameters:
7499: +  mat   - the matrix
7500: -  x,y - the vectors

7502:    Level: intermediate

7504:    Notes:
7505:     This allows one to use either the restriction or interpolation (its transpose)
7506:     matrix to do the restriction

7508:    Concepts: matrices^restriction

7510: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()

7512: @*/
7513: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7514: {
7516:   PetscInt       M,N,Ny;

7523:   MatCheckPreallocated(A,1);

7525:   MatGetSize(A,&M,&N);
7526:   VecGetSize(y,&Ny);
7527:   if (M == Ny) {
7528:     MatMult(A,x,y);
7529:   } else {
7530:     MatMultTranspose(A,x,y);
7531:   }
7532:   return(0);
7533: }

7537: /*@
7538:    MatGetNullSpace - retrieves the null space to a matrix.

7540:    Logically Collective on Mat and MatNullSpace

7542:    Input Parameters:
7543: +  mat - the matrix
7544: -  nullsp - the null space object

7546:    Level: developer

7548:    Notes:
7549:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7551:    Concepts: null space^attaching to matrix

7553: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7554: @*/
7555: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7556: {
7561:   *nullsp = mat->nullsp;
7562:   return(0);
7563: }

7567: /*@
7568:    MatSetNullSpace - attaches a null space to a matrix.
7569:         This null space will be removed from the resulting vector whenever
7570:         MatMult() is called

7572:    Logically Collective on Mat and MatNullSpace

7574:    Input Parameters:
7575: +  mat - the matrix
7576: -  nullsp - the null space object

7578:    Level: advanced

7580:    Notes:
7581:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7583:    Concepts: null space^attaching to matrix

7585: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7586: @*/
7587: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7588: {

7595:   MatCheckPreallocated(mat,1);
7596:   PetscObjectReference((PetscObject)nullsp);
7597:   MatNullSpaceDestroy(&mat->nullsp);

7599:   mat->nullsp = nullsp;
7600:   return(0);
7601: }

7605: /*@
7606:    MatSetNearNullSpace - attaches a null space to a matrix.
7607:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

7609:    Logically Collective on Mat and MatNullSpace

7611:    Input Parameters:
7612: +  mat - the matrix
7613: -  nullsp - the null space object

7615:    Level: advanced

7617:    Notes:
7618:       Overwrites any previous near null space that may have been attached

7620:    Concepts: null space^attaching to matrix

7622: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7623: @*/
7624: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7625: {

7632:   MatCheckPreallocated(mat,1);
7633:   PetscObjectReference((PetscObject)nullsp);
7634:   MatNullSpaceDestroy(&mat->nearnullsp);

7636:   mat->nearnullsp = nullsp;
7637:   return(0);
7638: }

7642: /*@
7643:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

7645:    Not Collective

7647:    Input Parameters:
7648: .  mat - the matrix

7650:    Output Parameters:
7651: .  nullsp - the null space object, NULL if not set

7653:    Level: developer

7655:    Concepts: null space^attaching to matrix

7657: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7658: @*/
7659: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7660: {
7665:   MatCheckPreallocated(mat,1);
7666:   *nullsp = mat->nearnullsp;
7667:   return(0);
7668: }

7672: /*@C
7673:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

7675:    Collective on Mat

7677:    Input Parameters:
7678: +  mat - the matrix
7679: .  row - row/column permutation
7680: .  fill - expected fill factor >= 1.0
7681: -  level - level of fill, for ICC(k)

7683:    Notes:
7684:    Probably really in-place only when level of fill is zero, otherwise allocates
7685:    new space to store factored matrix and deletes previous memory.

7687:    Most users should employ the simplified KSP interface for linear solvers
7688:    instead of working directly with matrix algebra routines such as this.
7689:    See, e.g., KSPCreate().

7691:    Level: developer

7693:    Concepts: matrices^incomplete Cholesky factorization
7694:    Concepts: Cholesky factorization

7696: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

7698:     Developer Note: fortran interface is not autogenerated as the f90
7699:     interface defintion cannot be generated correctly [due to MatFactorInfo]

7701: @*/
7702: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7703: {

7711:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
7712:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7713:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7714:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7715:   MatCheckPreallocated(mat,1);
7716:   (*mat->ops->iccfactor)(mat,row,info);
7717:   PetscObjectStateIncrease((PetscObject)mat);
7718:   return(0);
7719: }

7723: /*@
7724:    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.

7726:    Not Collective

7728:    Input Parameters:
7729: +  mat - the matrix
7730: .  nl - leading dimension of v
7731: -  v - the values compute with ADIFOR

7733:    Level: developer

7735:    Notes:
7736:      Must call MatSetColoring() before using this routine. Also this matrix must already
7737:      have its nonzero pattern determined.

7739: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7740:           MatSetValues(), MatSetColoring()
7741: @*/
7742: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7743: {


7751:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7752:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7753:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7754:   (*mat->ops->setvaluesadifor)(mat,nl,v);
7755:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7756:   PetscObjectStateIncrease((PetscObject)mat);
7757:   return(0);
7758: }

7762: /*@
7763:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7764:          ghosted ones.

7766:    Not Collective

7768:    Input Parameters:
7769: +  mat - the matrix
7770: -  diag = the diagonal values, including ghost ones

7772:    Level: developer

7774:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

7776: .seealso: MatDiagonalScale()
7777: @*/
7778: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7779: {
7781:   PetscMPIInt    size;


7788:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7789:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7790:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7791:   if (size == 1) {
7792:     PetscInt n,m;
7793:     VecGetSize(diag,&n);
7794:     MatGetSize(mat,0,&m);
7795:     if (m == n) {
7796:       MatDiagonalScale(mat,0,diag);
7797:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7798:   } else {
7799:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7800:   }
7801:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7802:   PetscObjectStateIncrease((PetscObject)mat);
7803:   return(0);
7804: }

7808: /*@
7809:    MatGetInertia - Gets the inertia from a factored matrix

7811:    Collective on Mat

7813:    Input Parameter:
7814: .  mat - the matrix

7816:    Output Parameters:
7817: +   nneg - number of negative eigenvalues
7818: .   nzero - number of zero eigenvalues
7819: -   npos - number of positive eigenvalues

7821:    Level: advanced

7823:    Notes: Matrix must have been factored by MatCholeskyFactor()


7826: @*/
7827: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7828: {

7834:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7835:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7836:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7837:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7838:   return(0);
7839: }

7841: /* ----------------------------------------------------------------*/
7844: /*@C
7845:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

7847:    Neighbor-wise Collective on Mat and Vecs

7849:    Input Parameters:
7850: +  mat - the factored matrix
7851: -  b - the right-hand-side vectors

7853:    Output Parameter:
7854: .  x - the result vectors

7856:    Notes:
7857:    The vectors b and x cannot be the same.  I.e., one cannot
7858:    call MatSolves(A,x,x).

7860:    Notes:
7861:    Most users should employ the simplified KSP interface for linear solvers
7862:    instead of working directly with matrix algebra routines such as this.
7863:    See, e.g., KSPCreate().

7865:    Level: developer

7867:    Concepts: matrices^triangular solves

7869: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7870: @*/
7871: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7872: {

7878:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7879:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7880:   if (!mat->rmap->N && !mat->cmap->N) return(0);

7882:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7883:   MatCheckPreallocated(mat,1);
7884:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7885:   (*mat->ops->solves)(mat,b,x);
7886:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7887:   return(0);
7888: }

7892: /*@
7893:    MatIsSymmetric - Test whether a matrix is symmetric

7895:    Collective on Mat

7897:    Input Parameter:
7898: +  A - the matrix to test
7899: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

7901:    Output Parameters:
7902: .  flg - the result

7904:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

7906:    Level: intermediate

7908:    Concepts: matrix^symmetry

7910: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7911: @*/
7912: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7913: {


7920:   if (!A->symmetric_set) {
7921:     if (!A->ops->issymmetric) {
7922:       MatType mattype;
7923:       MatGetType(A,&mattype);
7924:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7925:     }
7926:     (*A->ops->issymmetric)(A,tol,flg);
7927:     if (!tol) {
7928:       A->symmetric_set = PETSC_TRUE;
7929:       A->symmetric     = *flg;
7930:       if (A->symmetric) {
7931:         A->structurally_symmetric_set = PETSC_TRUE;
7932:         A->structurally_symmetric     = PETSC_TRUE;
7933:       }
7934:     }
7935:   } else if (A->symmetric) {
7936:     *flg = PETSC_TRUE;
7937:   } else if (!tol) {
7938:     *flg = PETSC_FALSE;
7939:   } else {
7940:     if (!A->ops->issymmetric) {
7941:       MatType mattype;
7942:       MatGetType(A,&mattype);
7943:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7944:     }
7945:     (*A->ops->issymmetric)(A,tol,flg);
7946:   }
7947:   return(0);
7948: }

7952: /*@
7953:    MatIsHermitian - Test whether a matrix is Hermitian

7955:    Collective on Mat

7957:    Input Parameter:
7958: +  A - the matrix to test
7959: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

7961:    Output Parameters:
7962: .  flg - the result

7964:    Level: intermediate

7966:    Concepts: matrix^symmetry

7968: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7969:           MatIsSymmetricKnown(), MatIsSymmetric()
7970: @*/
7971: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7972: {


7979:   if (!A->hermitian_set) {
7980:     if (!A->ops->ishermitian) {
7981:       MatType mattype;
7982:       MatGetType(A,&mattype);
7983:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7984:     }
7985:     (*A->ops->ishermitian)(A,tol,flg);
7986:     if (!tol) {
7987:       A->hermitian_set = PETSC_TRUE;
7988:       A->hermitian     = *flg;
7989:       if (A->hermitian) {
7990:         A->structurally_symmetric_set = PETSC_TRUE;
7991:         A->structurally_symmetric     = PETSC_TRUE;
7992:       }
7993:     }
7994:   } else if (A->hermitian) {
7995:     *flg = PETSC_TRUE;
7996:   } else if (!tol) {
7997:     *flg = PETSC_FALSE;
7998:   } else {
7999:     if (!A->ops->ishermitian) {
8000:       MatType mattype;
8001:       MatGetType(A,&mattype);
8002:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8003:     }
8004:     (*A->ops->ishermitian)(A,tol,flg);
8005:   }
8006:   return(0);
8007: }

8011: /*@
8012:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

8014:    Not Collective

8016:    Input Parameter:
8017: .  A - the matrix to check

8019:    Output Parameters:
8020: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8021: -  flg - the result

8023:    Level: advanced

8025:    Concepts: matrix^symmetry

8027:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8028:          if you want it explicitly checked

8030: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8031: @*/
8032: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8033: {
8038:   if (A->symmetric_set) {
8039:     *set = PETSC_TRUE;
8040:     *flg = A->symmetric;
8041:   } else {
8042:     *set = PETSC_FALSE;
8043:   }
8044:   return(0);
8045: }

8049: /*@
8050:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8052:    Not Collective

8054:    Input Parameter:
8055: .  A - the matrix to check

8057:    Output Parameters:
8058: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8059: -  flg - the result

8061:    Level: advanced

8063:    Concepts: matrix^symmetry

8065:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8066:          if you want it explicitly checked

8068: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8069: @*/
8070: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8071: {
8076:   if (A->hermitian_set) {
8077:     *set = PETSC_TRUE;
8078:     *flg = A->hermitian;
8079:   } else {
8080:     *set = PETSC_FALSE;
8081:   }
8082:   return(0);
8083: }

8087: /*@
8088:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8090:    Collective on Mat

8092:    Input Parameter:
8093: .  A - the matrix to test

8095:    Output Parameters:
8096: .  flg - the result

8098:    Level: intermediate

8100:    Concepts: matrix^symmetry

8102: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8103: @*/
8104: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8105: {

8111:   if (!A->structurally_symmetric_set) {
8112:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8113:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);

8115:     A->structurally_symmetric_set = PETSC_TRUE;
8116:   }
8117:   *flg = A->structurally_symmetric;
8118:   return(0);
8119: }

8123: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8124: /*@
8125:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8126:        to be communicated to other processors during the MatAssemblyBegin/End() process

8128:     Not collective

8130:    Input Parameter:
8131: .   vec - the vector

8133:    Output Parameters:
8134: +   nstash   - the size of the stash
8135: .   reallocs - the number of additional mallocs incurred.
8136: .   bnstash   - the size of the block stash
8137: -   breallocs - the number of additional mallocs incurred.in the block stash

8139:    Level: advanced

8141: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()

8143: @*/
8144: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8145: {

8149:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8150:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8151:   return(0);
8152: }

8156: /*@C
8157:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8158:      parallel layout

8160:    Collective on Mat

8162:    Input Parameter:
8163: .  mat - the matrix

8165:    Output Parameter:
8166: +   right - (optional) vector that the matrix can be multiplied against
8167: -   left - (optional) vector that the matrix vector product can be stored in

8169:   Level: advanced

8171: .seealso: MatCreate()
8172: @*/
8173: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8174: {

8180:   MatCheckPreallocated(mat,1);
8181:   if (mat->ops->getvecs) {
8182:     (*mat->ops->getvecs)(mat,right,left);
8183:   } else {
8184:     PetscMPIInt size;
8185:     PetscInt rbs,cbs;
8186:     MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8187:     MatGetBlockSizes(mat,&rbs,&cbs);
8188:     if (right) {
8189:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8190:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8191:       VecSetBlockSize(*right,cbs);
8192:       VecSetType(*right,VECSTANDARD);
8193:       PetscLayoutReference(mat->cmap,&(*right)->map);
8194:     }
8195:     if (left) {
8196:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8197:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8198:       VecSetBlockSize(*left,rbs);
8199:       VecSetType(*left,VECSTANDARD);
8200:       PetscLayoutReference(mat->rmap,&(*left)->map);
8201:     }
8202:   }
8203:   return(0);
8204: }

8208: /*@C
8209:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8210:      with default values.

8212:    Not Collective

8214:    Input Parameters:
8215: .    info - the MatFactorInfo data structure


8218:    Notes: The solvers are generally used through the KSP and PC objects, for example
8219:           PCLU, PCILU, PCCHOLESKY, PCICC

8221:    Level: developer

8223: .seealso: MatFactorInfo

8225:     Developer Note: fortran interface is not autogenerated as the f90
8226:     interface defintion cannot be generated correctly [due to MatFactorInfo]

8228: @*/

8230: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8231: {

8235:   PetscMemzero(info,sizeof(MatFactorInfo));
8236:   return(0);
8237: }

8241: /*@
8242:    MatPtAP - Creates the matrix product C = P^T * A * P

8244:    Neighbor-wise Collective on Mat

8246:    Input Parameters:
8247: +  A - the matrix
8248: .  P - the projection matrix
8249: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8250: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

8252:    Output Parameters:
8253: .  C - the product matrix

8255:    Notes:
8256:    C will be created and must be destroyed by the user with MatDestroy().

8258:    This routine is currently only implemented for pairs of AIJ matrices and classes
8259:    which inherit from AIJ.

8261:    Level: intermediate

8263: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8264: @*/
8265: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8266: {
8268:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8269:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8270:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8271:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

8274:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8275:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

8279:   MatCheckPreallocated(A,1);
8280:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8281:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8284:   MatCheckPreallocated(P,2);
8285:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8286:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8288:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8289:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8291:   if (scall == MAT_REUSE_MATRIX) {
8294:     if (viatranspose || viamatmatmatmult) {
8295:       Mat Pt;
8296:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8297:       if (viamatmatmatmult) {
8298:         MatMatMatMult(Pt,A,P,scall,fill,C);
8299:       } else {
8300:         Mat AP;
8301:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8302:         MatMatMult(Pt,AP,scall,fill,C);
8303:         MatDestroy(&AP);
8304:       }
8305:       MatDestroy(&Pt);
8306:     } else {
8307:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8308:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8309:       (*(*C)->ops->ptapnumeric)(A,P,*C);
8310:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8311:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8312:     }
8313:     return(0);
8314:   }

8316:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8317:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8319:   fA = A->ops->ptap;
8320:   fP = P->ops->ptap;
8321:   if (fP == fA) {
8322:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8323:     ptap = fA;
8324:   } else {
8325:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8326:     char ptapname[256];
8327:     PetscStrcpy(ptapname,"MatPtAP_");
8328:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
8329:     PetscStrcat(ptapname,"_");
8330:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
8331:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8332:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8333:     if (!ptap) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s",((PetscObject)A)->type_name,((PetscObject)P)->type_name);
8334:   }

8336:   if (viatranspose || viamatmatmatmult) {
8337:     Mat Pt;
8338:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8339:     if (viamatmatmatmult) {
8340:       MatMatMatMult(Pt,A,P,scall,fill,C);
8341:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8342:     } else {
8343:       Mat AP;
8344:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8345:       MatMatMult(Pt,AP,scall,fill,C);
8346:       MatDestroy(&AP);
8347:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8348:     }
8349:     MatDestroy(&Pt);
8350:   } else {
8351:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8352:     (*ptap)(A,P,scall,fill,C);
8353:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8354:   }
8355:   return(0);
8356: }

8360: /*@
8361:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

8363:    Neighbor-wise Collective on Mat

8365:    Input Parameters:
8366: +  A - the matrix
8367: -  P - the projection matrix

8369:    Output Parameters:
8370: .  C - the product matrix

8372:    Notes:
8373:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8374:    the user using MatDeatroy().

8376:    This routine is currently only implemented for pairs of AIJ matrices and classes
8377:    which inherit from AIJ.  C will be of type MATAIJ.

8379:    Level: intermediate

8381: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8382: @*/
8383: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8384: {

8390:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8391:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8394:   MatCheckPreallocated(P,2);
8395:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8396:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8399:   MatCheckPreallocated(C,3);
8400:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8401:   if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
8402:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8403:   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8404:   if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
8405:   MatCheckPreallocated(A,1);

8407:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8408:   (*C->ops->ptapnumeric)(A,P,C);
8409:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8410:   return(0);
8411: }

8415: /*@
8416:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

8418:    Neighbor-wise Collective on Mat

8420:    Input Parameters:
8421: +  A - the matrix
8422: -  P - the projection matrix

8424:    Output Parameters:
8425: .  C - the (i,j) structure of the product matrix

8427:    Notes:
8428:    C will be created and must be destroyed by the user with MatDestroy().

8430:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8431:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8432:    this (i,j) structure by calling MatPtAPNumeric().

8434:    Level: intermediate

8436: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8437: @*/
8438: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8439: {

8445:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8446:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8447:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8450:   MatCheckPreallocated(P,2);
8451:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8452:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8455:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8456:   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8457:   MatCheckPreallocated(A,1);
8458:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8459:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8460:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

8462:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8463:   return(0);
8464: }

8468: /*@
8469:    MatRARt - Creates the matrix product C = R * A * R^T

8471:    Neighbor-wise Collective on Mat

8473:    Input Parameters:
8474: +  A - the matrix
8475: .  R - the projection matrix
8476: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8477: -  fill - expected fill as ratio of nnz(C)/nnz(A)

8479:    Output Parameters:
8480: .  C - the product matrix

8482:    Notes:
8483:    C will be created and must be destroyed by the user with MatDestroy().

8485:    This routine is currently only implemented for pairs of AIJ matrices and classes
8486:    which inherit from AIJ.

8488:    Level: intermediate

8490: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8491: @*/
8492: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8493: {

8499:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8500:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8503:   MatCheckPreallocated(R,2);
8504:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8505:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8507:   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8508:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8509:   MatCheckPreallocated(A,1);

8511:   if (!A->ops->rart) {
8512:     MatType mattype;
8513:     MatGetType(A,&mattype);
8514:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8515:   }
8516:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
8517:   (*A->ops->rart)(A,R,scall,fill,C);
8518:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
8519:   return(0);
8520: }

8524: /*@
8525:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

8527:    Neighbor-wise Collective on Mat

8529:    Input Parameters:
8530: +  A - the matrix
8531: -  R - the projection matrix

8533:    Output Parameters:
8534: .  C - the product matrix

8536:    Notes:
8537:    C must have been created by calling MatRARtSymbolic and must be destroyed by
8538:    the user using MatDeatroy().

8540:    This routine is currently only implemented for pairs of AIJ matrices and classes
8541:    which inherit from AIJ.  C will be of type MATAIJ.

8543:    Level: intermediate

8545: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8546: @*/
8547: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8548: {

8554:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8555:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8558:   MatCheckPreallocated(R,2);
8559:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8560:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8563:   MatCheckPreallocated(C,3);
8564:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8565:   if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
8566:   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8567:   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8568:   if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
8569:   MatCheckPreallocated(A,1);

8571:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8572:   (*A->ops->rartnumeric)(A,R,C);
8573:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8574:   return(0);
8575: }

8579: /*@
8580:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

8582:    Neighbor-wise Collective on Mat

8584:    Input Parameters:
8585: +  A - the matrix
8586: -  R - the projection matrix

8588:    Output Parameters:
8589: .  C - the (i,j) structure of the product matrix

8591:    Notes:
8592:    C will be created and must be destroyed by the user with MatDestroy().

8594:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8595:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8596:    this (i,j) structure by calling MatRARtNumeric().

8598:    Level: intermediate

8600: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8601: @*/
8602: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8603: {

8609:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8610:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8611:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8614:   MatCheckPreallocated(R,2);
8615:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8616:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8619:   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8620:   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8621:   MatCheckPreallocated(A,1);
8622:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8623:   (*A->ops->rartsymbolic)(A,R,fill,C);
8624:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

8626:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
8627:   return(0);
8628: }

8632: /*@
8633:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

8635:    Neighbor-wise Collective on Mat

8637:    Input Parameters:
8638: +  A - the left matrix
8639: .  B - the right matrix
8640: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8641: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8642:           if the result is a dense matrix this is irrelevent

8644:    Output Parameters:
8645: .  C - the product matrix

8647:    Notes:
8648:    Unless scall is MAT_REUSE_MATRIX C will be created.

8650:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8652:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8653:    actually needed.

8655:    If you have many matrices with the same non-zero structure to multiply, you
8656:    should either
8657: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8658: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

8660:    Level: intermediate

8662: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8663: @*/
8664: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8665: {
8667:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8668:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8669:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

8674:   MatCheckPreallocated(A,1);
8675:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8676:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8679:   MatCheckPreallocated(B,2);
8680:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8681:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8683:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8684:   if (scall == MAT_REUSE_MATRIX) {
8687:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8688:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8689:     (*(*C)->ops->matmultnumeric)(A,B,*C);
8690:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8691:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8692:     return(0);
8693:   }
8694:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8695:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8697:   fA = A->ops->matmult;
8698:   fB = B->ops->matmult;
8699:   if (fB == fA) {
8700:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8701:     mult = fB;
8702:   } else {
8703:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8704:     char multname[256];
8705:     PetscStrcpy(multname,"MatMatMult_");
8706:     PetscStrcat(multname,((PetscObject)A)->type_name);
8707:     PetscStrcat(multname,"_");
8708:     PetscStrcat(multname,((PetscObject)B)->type_name);
8709:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8710:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
8711:     if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8712:   }
8713:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8714:   (*mult)(A,B,scall,fill,C);
8715:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8716:   return(0);
8717: }

8721: /*@
8722:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8723:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

8725:    Neighbor-wise Collective on Mat

8727:    Input Parameters:
8728: +  A - the left matrix
8729: .  B - the right matrix
8730: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8731:       if C is a dense matrix this is irrelevent

8733:    Output Parameters:
8734: .  C - the product matrix

8736:    Notes:
8737:    Unless scall is MAT_REUSE_MATRIX C will be created.

8739:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8740:    actually needed.

8742:    This routine is currently implemented for
8743:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8744:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8745:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8747:    Level: intermediate

8749:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8750:      We should incorporate them into PETSc.

8752: .seealso: MatMatMult(), MatMatMultNumeric()
8753: @*/
8754: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8755: {
8757:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
8758:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
8759:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

8764:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8765:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8769:   MatCheckPreallocated(B,2);
8770:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8771:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8774:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8775:   if (fill == PETSC_DEFAULT) fill = 2.0;
8776:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8777:   MatCheckPreallocated(A,1);

8779:   Asymbolic = A->ops->matmultsymbolic;
8780:   Bsymbolic = B->ops->matmultsymbolic;
8781:   if (Asymbolic == Bsymbolic) {
8782:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8783:     symbolic = Bsymbolic;
8784:   } else { /* dispatch based on the type of A and B */
8785:     char symbolicname[256];
8786:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8787:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8788:     PetscStrcat(symbolicname,"_");
8789:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8790:     PetscStrcat(symbolicname,"_C");
8791:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
8792:     if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8793:   }
8794:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8795:   (*symbolic)(A,B,fill,C);
8796:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8797:   return(0);
8798: }

8802: /*@
8803:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8804:    Call this routine after first calling MatMatMultSymbolic().

8806:    Neighbor-wise Collective on Mat

8808:    Input Parameters:
8809: +  A - the left matrix
8810: -  B - the right matrix

8812:    Output Parameters:
8813: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

8815:    Notes:
8816:    C must have been created with MatMatMultSymbolic().

8818:    This routine is currently implemented for
8819:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8820:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8821:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8823:    Level: intermediate

8825: .seealso: MatMatMult(), MatMatMultSymbolic()
8826: @*/
8827: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8828: {

8832:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
8833:   return(0);
8834: }

8838: /*@
8839:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

8841:    Neighbor-wise Collective on Mat

8843:    Input Parameters:
8844: +  A - the left matrix
8845: .  B - the right matrix
8846: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8847: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8849:    Output Parameters:
8850: .  C - the product matrix

8852:    Notes:
8853:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8855:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8857:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8858:    actually needed.

8860:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

8862:    Level: intermediate

8864: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8865: @*/
8866: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8867: {
8869:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8870:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

8875:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8876:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8879:   MatCheckPreallocated(B,2);
8880:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8881:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8883:   if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
8884:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8885:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8886:   MatCheckPreallocated(A,1);

8888:   fA = A->ops->mattransposemult;
8889:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8890:   fB = B->ops->mattransposemult;
8891:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8892:   if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);

8894:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
8895:   if (scall == MAT_INITIAL_MATRIX) {
8896:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8897:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8898:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8899:   }
8900:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8901:   (*A->ops->mattransposemultnumeric)(A,B,*C);
8902:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8903:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
8904:   return(0);
8905: }

8909: /*@
8910:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

8912:    Neighbor-wise Collective on Mat

8914:    Input Parameters:
8915: +  A - the left matrix
8916: .  B - the right matrix
8917: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8918: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8920:    Output Parameters:
8921: .  C - the product matrix

8923:    Notes:
8924:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8926:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8928:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8929:    actually needed.

8931:    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
8932:    which inherit from SeqAIJ.  C will be of same type as the input matrices.

8934:    Level: intermediate

8936: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8937: @*/
8938: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8939: {
8941:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8942:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8943:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

8948:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8949:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8952:   MatCheckPreallocated(B,2);
8953:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8954:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8956:   if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
8957:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8958:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8959:   MatCheckPreallocated(A,1);

8961:   fA = A->ops->transposematmult;
8962:   fB = B->ops->transposematmult;
8963:   if (fB==fA) {
8964:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8965:     transposematmult = fA;
8966:   } else {
8967:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8968:     char multname[256];
8969:     PetscStrcpy(multname,"MatTransposeMatMult_");
8970:     PetscStrcat(multname,((PetscObject)A)->type_name);
8971:     PetscStrcat(multname,"_");
8972:     PetscStrcat(multname,((PetscObject)B)->type_name);
8973:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8974:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
8975:     if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8976:   }
8977:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8978:   (*transposematmult)(A,B,scall,fill,C);
8979:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8980:   return(0);
8981: }

8985: /*@
8986:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

8988:    Neighbor-wise Collective on Mat

8990:    Input Parameters:
8991: +  A - the left matrix
8992: .  B - the middle matrix
8993: .  C - the right matrix
8994: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8995: -  fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate
8996:           if the result is a dense matrix this is irrelevent

8998:    Output Parameters:
8999: .  D - the product matrix

9001:    Notes:
9002:    Unless scall is MAT_REUSE_MATRIX D will be created.

9004:    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call

9006:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9007:    actually needed.

9009:    If you have many matrices with the same non-zero structure to multiply, you
9010:    should either
9011: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9012: $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed

9014:    Level: intermediate

9016: .seealso: MatMatMult, MatPtAP()
9017: @*/
9018: PetscErrorCode  MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9019: {
9021:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9022:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9023:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9024:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9029:   MatCheckPreallocated(A,1);
9030:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9031:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9034:   MatCheckPreallocated(B,2);
9035:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9036:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9039:   MatCheckPreallocated(C,3);
9040:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9041:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9042:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9043:   if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
9044:   if (scall == MAT_REUSE_MATRIX) {
9047:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9048:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9049:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9050:     return(0);
9051:   }
9052:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9053:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9055:   fA = A->ops->matmatmult;
9056:   fB = B->ops->matmatmult;
9057:   fC = C->ops->matmatmult;
9058:   if (fA == fB && fA == fC) {
9059:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9060:     mult = fA;
9061:   } else {
9062:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9063:     char multname[256];
9064:     PetscStrcpy(multname,"MatMatMatMult_");
9065:     PetscStrcat(multname,((PetscObject)A)->type_name);
9066:     PetscStrcat(multname,"_");
9067:     PetscStrcat(multname,((PetscObject)B)->type_name);
9068:     PetscStrcat(multname,"_");
9069:     PetscStrcat(multname,((PetscObject)C)->type_name);
9070:     PetscStrcat(multname,"_C");
9071:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9072:     if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9073:   }
9074:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9075:   (*mult)(A,B,C,scall,fill,D);
9076:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9077:   return(0);
9078: }

9082: /*@C
9083:    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

9085:    Collective on Mat

9087:    Input Parameters:
9088: +  mat - the matrix
9089: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9090: .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9091: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9093:    Output Parameter:
9094: .  matredundant - redundant matrix

9096:    Notes:
9097:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9098:    original matrix has not changed from that last call to MatGetRedundantMatrix().

9100:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9101:    calling it.

9103:    Only MPIAIJ matrix is supported.

9105:    Level: advanced

9107:    Concepts: subcommunicator
9108:    Concepts: duplicate matrix

9110: .seealso: MatDestroy()
9111: @*/
9112: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9113: {

9118:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9121:   }
9122:   if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9123:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9124:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9125:   MatCheckPreallocated(mat,1);

9127:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
9128:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,reuse,matredundant);
9129:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
9130:   return(0);
9131: }

9135: /*@C
9136:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9137:    a given 'mat' object. Each submatrix can span multiple procs.

9139:    Collective on Mat

9141:    Input Parameters:
9142: +  mat - the matrix
9143: .  subcomm - the subcommunicator obtained by com_split(comm)
9144: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9146:    Output Parameter:
9147: .  subMat - 'parallel submatrices each spans a given subcomm

9149:   Notes:
9150:   The submatrix partition across processors is dictated by 'subComm' a
9151:   communicator obtained by com_split(comm). The comm_split
9152:   is not restriced to be grouped with consecutive original ranks.

9154:   Due the comm_split() usage, the parallel layout of the submatrices
9155:   map directly to the layout of the original matrix [wrt the local
9156:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9157:   into the 'DiagonalMat' of the subMat, hence it is used directly from
9158:   the subMat. However the offDiagMat looses some columns - and this is
9159:   reconstructed with MatSetValues()

9161:   Level: advanced

9163:   Concepts: subcommunicator
9164:   Concepts: submatrices

9166: .seealso: MatGetSubMatrices()
9167: @*/
9168: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9169: {
9171:   PetscMPIInt    commsize,subCommSize;

9174:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9175:   MPI_Comm_size(subComm,&subCommSize);
9176:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

9178:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9179:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9180:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9181:   return(0);
9182: }

9186: /*@
9187:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

9189:    Not Collective

9191:    Input Arguments:
9192:    mat - matrix to extract local submatrix from
9193:    isrow - local row indices for submatrix
9194:    iscol - local column indices for submatrix

9196:    Output Arguments:
9197:    submat - the submatrix

9199:    Level: intermediate

9201:    Notes:
9202:    The submat should be returned with MatRestoreLocalSubMatrix().

9204:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9205:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

9207:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9208:    MatSetValuesBlockedLocal() will also be implemented.

9210: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9211: @*/
9212: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9213: {


9223:   if (mat->ops->getlocalsubmatrix) {
9224:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9225:   } else {
9226:     MatCreateLocalRef(mat,isrow,iscol,submat);
9227:   }
9228:   return(0);
9229: }

9233: /*@
9234:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

9236:    Not Collective

9238:    Input Arguments:
9239:    mat - matrix to extract local submatrix from
9240:    isrow - local row indices for submatrix
9241:    iscol - local column indices for submatrix
9242:    submat - the submatrix

9244:    Level: intermediate

9246: .seealso: MatGetLocalSubMatrix()
9247: @*/
9248: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9249: {

9258:   if (*submat) {
9260:   }

9262:   if (mat->ops->restorelocalsubmatrix) {
9263:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9264:   } else {
9265:     MatDestroy(submat);
9266:   }
9267:   *submat = NULL;
9268:   return(0);
9269: }

9271: /* --------------------------------------------------------*/
9274: /*@
9275:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

9277:    Collective on Mat

9279:    Input Parameter:
9280: .  mat - the matrix

9282:    Output Parameter:
9283: .  is - if any rows have zero diagonals this contains the list of them

9285:    Level: developer

9287:    Concepts: matrix-vector product

9289: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9290: @*/
9291: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9292: {

9298:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9299:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9301:   if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9302:   (*mat->ops->findzerodiagonals)(mat,is);
9303:   return(0);
9304: }

9308: /*@
9309:    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)

9311:    Collective on Mat

9313:    Input Parameter:
9314: .  mat - the matrix

9316:    Output Parameter:
9317: .  is - contains the list of rows with off block diagonal entries

9319:    Level: developer

9321:    Concepts: matrix-vector product

9323: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9324: @*/
9325: PetscErrorCode  MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
9326: {

9332:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9333:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9335:   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
9336:   (*mat->ops->findoffblockdiagonalentries)(mat,is);
9337:   return(0);
9338: }

9342: /*@C
9343:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

9345:   Collective on Mat

9347:   Input Parameters:
9348: . mat - the matrix

9350:   Output Parameters:
9351: . values - the block inverses in column major order (FORTRAN-like)

9353:    Note:
9354:    This routine is not available from Fortran.

9356:   Level: advanced
9357: @*/
9358: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9359: {

9364:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9365:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9366:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9367:   (*mat->ops->invertblockdiagonal)(mat,values);
9368:   return(0);
9369: }

9373: /*@C
9374:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9375:     via MatTransposeColoringCreate().

9377:     Collective on MatTransposeColoring

9379:     Input Parameter:
9380: .   c - coloring context

9382:     Level: intermediate

9384: .seealso: MatTransposeColoringCreate()
9385: @*/
9386: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9387: {
9388:   PetscErrorCode       ierr;
9389:   MatTransposeColoring matcolor=*c;

9392:   if (!matcolor) return(0);
9393:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

9395:   PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
9396:   PetscFree(matcolor->rows);
9397:   PetscFree(matcolor->den2sp);
9398:   PetscFree(matcolor->colorforcol);
9399:   PetscFree(matcolor->columns);
9400:   if (matcolor->brows>0) {
9401:     PetscFree(matcolor->lstart);
9402:   }
9403:   PetscHeaderDestroy(c);
9404:   return(0);
9405: }

9409: /*@C
9410:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9411:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9412:     MatTransposeColoring to sparse B.

9414:     Collective on MatTransposeColoring

9416:     Input Parameters:
9417: +   B - sparse matrix B
9418: .   Btdense - symbolic dense matrix B^T
9419: -   coloring - coloring context created with MatTransposeColoringCreate()

9421:     Output Parameter:
9422: .   Btdense - dense matrix B^T

9424:     Options Database Keys:
9425: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9426: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9427: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

9429:     Level: intermediate

9431: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

9433: .keywords: coloring
9434: @*/
9435: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9436: {


9444:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9445:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9446:   return(0);
9447: }

9451: /*@C
9452:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9453:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9454:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9455:     Csp from Cden.

9457:     Collective on MatTransposeColoring

9459:     Input Parameters:
9460: +   coloring - coloring context created with MatTransposeColoringCreate()
9461: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

9463:     Output Parameter:
9464: .   Csp - sparse matrix

9466:     Options Database Keys:
9467: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9468: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9469: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

9471:     Level: intermediate

9473: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

9475: .keywords: coloring
9476: @*/
9477: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9478: {


9486:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9487:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9488:   return(0);
9489: }

9493: /*@C
9494:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

9496:    Collective on Mat

9498:    Input Parameters:
9499: +  mat - the matrix product C
9500: -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()

9502:     Output Parameter:
9503: .   color - the new coloring context

9505:     Level: intermediate

9507: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9508:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9509: @*/
9510: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9511: {
9512:   MatTransposeColoring c;
9513:   MPI_Comm             comm;
9514:   PetscErrorCode       ierr;

9517:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9518:   PetscObjectGetComm((PetscObject)mat,&comm);
9519:   PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);

9521:   c->ctype = iscoloring->ctype;
9522:   if (mat->ops->transposecoloringcreate) {
9523:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9524:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

9526:   *color = c;
9527:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9528:   return(0);
9529: }

9533: /*@
9534:       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 
9535:         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 
9536:         same, otherwise it will be larger

9538:      Not Collective

9540:   Input Parameter:
9541: .    A  - the matrix

9543:   Output Parameter:
9544: .    state - the current state

9546:   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 
9547:          different matrices

9549:   Level: intermediate

9551: @*/
9552: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
9553: {
9555:   *state = mat->nonzerostate;
9556:   return(0);
9557: }