Actual source code: matrix.c

petsc-3.5.3 2015-01-31
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->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
153:   MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
154:   PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);
155:   if (f) {
156:     (*f)(A,a);
157:     return(0);
158:   } else if (size == 1) {
159:     *a = A;
160:   } else {
161:     MatType mattype;
162:     MatGetType(A,&mattype);
163:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
164:   }
165:   return(0);
166: }

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

173:    Collective on Mat

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

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

181:    Level: advanced

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

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

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

202:    Logically Collective on Mat

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

207:    Level: advanced


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

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

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

242:    Collective on Mat

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

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

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

253:    Level: advanced

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

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


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

280:    Logically Collective on Mat

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

285:    Level: advanced


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

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

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

320:    Collective on Mat

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

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

329:    Level: advanced


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

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

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

355:    Not Collective

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

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

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

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

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

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

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

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


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

405:    Level: advanced

407:    Concepts: matrices^row access

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

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

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

435:    Logically Collective on Mat

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

440:    Level: advanced

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

451:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
452:   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");
453:   (*mat->ops->conjugate)(mat);
454: #if defined(PETSC_HAVE_CUSP)
455:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
456:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
457:   }
458: #endif
459: #if defined(PETSC_HAVE_VIENNACL)
460:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
461:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
462:   }
463: #endif
464:   return(0);
465: #else
466:   return 0;
467: #endif
468: }

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

475:    Not Collective

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

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

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

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

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

505:    Level: advanced

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

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

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

531:    Not Collective

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

536:    Notes:
537:    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.

539:    Level: advanced

541:    Concepts: matrices^row access

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

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

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

565:    Not Collective

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

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


574:    Level: advanced

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

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

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

596:    Logically Collective on Mat

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

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

606:    Level: advanced

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

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

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

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

628:    Logically Collective on Mat

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

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

638:    Level: advanced

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

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

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

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

660:    Not Collective

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

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

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

671:    Level: advanced

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

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

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

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

692:    Collective on Mat

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

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

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

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

704:    Level: beginner

706: .keywords: Mat, setup

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

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

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

741:    Collective on Mat

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

919:    Collective on PetscViewer

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

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

931:    Level: beginner

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1018:    Collective on Mat

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

1023:    Level: beginner

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

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

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

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

1055:    Not Collective

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

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

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

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

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

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

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

1088:    Level: beginner

1090:    Concepts: matrices^putting entries in

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

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

1118:   for (i=0; i<m; i++) {
1119:     for (j=0; j<n; j++) {
1120:       if (PetscIsInfOrNanScalar(v[i*n+j]))
1121: #if defined(PETSC_USE_COMPLEX)
1122:         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]);
1123: #else
1124:       SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1125: #endif
1126:     }
1127:   }
1128: #endif

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


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

1157:    Not Collective

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

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

1167:    All the nonzeros in the row must be provided

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

1171:    The row must belong to this process

1173:    Level: intermediate

1175:    Concepts: matrices^putting entries in

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

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

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

1210:    Not Collective

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

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

1220:    All the nonzeros in the row must be provided

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

1224:    The row must belong to this process

1226:    Level: advanced

1228:    Concepts: matrices^putting entries in

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

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

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

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

1275:    Not Collective

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

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

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

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

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

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

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

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

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

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

1325:    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
1326:    a single value per point) you can skip filling those indices.

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

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

1335:    Level: beginner

1337:    Concepts: matrices^putting entries in

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

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

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

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

1394:    Not Collective

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

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

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

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

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

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

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

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

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

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

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

1447:    Level: beginner

1449:    Concepts: matrices^putting entries in

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

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

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

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

1517:    Not Collective

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


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

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

1533:    Level: beginner

1535:    Concepts: matrices^putting entries in

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


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

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

1565:    Not Collective

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

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

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

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

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

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

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

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

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

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

1625:    Level: intermediate

1627:    Concepts: matrices^putting entries in blocked

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

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

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

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

1701:    Not Collective; currently only returns a local block

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

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

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

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

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

1725:    Level: advanced

1727:    Concepts: matrices^accessing values

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

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

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

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

1759:   Not Collective

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

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

1771:   Level: advanced

1773:   Concepts: matrices^putting entries in

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

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

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

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

1811:    Not Collective

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

1818:    Level: intermediate

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

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


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


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

1850:    Not Collective

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

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

1859:    Level: advanced

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

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

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

1883:    Not Collective

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

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

1892:    Level: advanced

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

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

1914:    Not Collective

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

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

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

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

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

1938:    Level: intermediate

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

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

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

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

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

2006:    Not Collective

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

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

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

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

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

2031:    Level: intermediate

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

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

2045:   MatCheckPreallocated(mat,1);
2046:   if (!nrow || !ncol) return(0); /* no values to insert */
2050:   if (mat->insertmode == NOT_SET_VALUES) {
2051:     mat->insertmode = addv;
2052:   }
2053: #if defined(PETSC_USE_DEBUG)
2054:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2055:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2056:   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);
2057: #endif

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

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

2098:    Collective on Mat and Vec

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

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

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

2111:    Level: developer

2113:    Concepts: matrix-vector product

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


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

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

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

2144:    Neighbor-wise Collective on Mat and Vec

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

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

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

2157:    Level: beginner

2159:    Concepts: matrix-vector product

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

2172:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2173:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2174:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2175: #if !defined(PETSC_HAVE_CONSTRAINTS)
2176:   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);
2177:   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);
2178:   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);
2179: #endif
2180:   VecValidValues(x,2,PETSC_TRUE);
2181:   MatCheckPreallocated(mat,1);

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

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

2196:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

2212:    Level: beginner

2214:    Concepts: matrix vector product^transpose

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


2228:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2229:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2230:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2231: #if !defined(PETSC_HAVE_CONSTRAINTS)
2232:   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);
2233:   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);
2234: #endif
2235:   VecValidValues(x,2,PETSC_TRUE);
2236:   MatCheckPreallocated(mat,1);

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

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

2252:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

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

2269:    Level: beginner

2271:    Concepts: matrix vector product^transpose

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


2286:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2287:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2288:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2289: #if !defined(PETSC_HAVE_CONSTRAINTS)
2290:   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);
2291:   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);
2292: #endif
2293:   MatCheckPreallocated(mat,1);

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

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

2316:     Neighbor-wise Collective on Mat and Vec

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

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

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

2329:     Level: beginner

2331:     Concepts: matrix vector product^addition

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


2346:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2347:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2348:   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);
2349:   /* 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);
2350:      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); */
2351:   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);
2352:   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);
2353:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2354:   MatCheckPreallocated(mat,1);

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

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

2369:    Neighbor-wise Collective on Mat and Vec

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

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

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

2382:    Level: beginner

2384:    Concepts: matrix vector product^transpose and addition

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


2399:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2400:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2401:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2402:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2403:   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);
2404:   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);
2405:   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);
2406:   MatCheckPreallocated(mat,1);

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

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

2420:    Neighbor-wise Collective on Mat and Vec

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

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

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

2433:    Level: beginner

2435:    Concepts: matrix vector product^transpose and addition

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


2450:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2451:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2452:   if (!mat->ops->multhermitiantransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2453:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2454:   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);
2455:   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);
2456:   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);
2457:   MatCheckPreallocated(mat,1);

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

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

2472:    Neighbor-wise Collective on Mat and Vec

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

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

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

2485:    Level: beginner

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

2498:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2499:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2500:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2501:   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);
2502:   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);
2503:   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);

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

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

2518:    Neighbor-wise Collective on Mat and Vec

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

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

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

2531:    Level: beginner

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

2544:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2545:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2546:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2547:   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);
2548:   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);

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

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

2562:    Note Collective
2563:    as the flag

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

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

2571:     Level: intermediate

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

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

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

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

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

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

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

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

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

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

2640:     Level: intermediate

2642:     Concepts: matrices^getting information on

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

2647: .seealso: MatStashGetInfo()

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

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

2664: /* ----------------------------------------------------------*/

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

2671:    Collective on Mat

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

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

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

2690:    Level: developer

2692:    Concepts: matrices^LU factorization

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

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

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

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

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

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

2733:    Collective on Mat

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

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

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

2753:    Level: developer

2755:    Concepts: matrices^ILU factorization

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

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

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

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

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

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

2792:    Collective on Mat

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


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

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

2810:    Level: developer

2812:    Concepts: matrices^LU symbolic factorization

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

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

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

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

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

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

2853:    Collective on Mat

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

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

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

2868:    Level: developer

2870:    Concepts: matrices^LU numeric factorization

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

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

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

2887:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2888:   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);

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

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

2906:    Collective on Mat

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

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

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

2921:    Level: developer

2923:    Concepts: matrices^Cholesky factorization

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

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

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

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

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

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

2960:    Collective on Mat

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

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

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

2979:    Level: developer

2981:    Concepts: matrices^Cholesky symbolic factorization

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

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

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

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

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

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

3024:    Collective on Mat

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


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

3038:    Level: developer

3040:    Concepts: matrices^Cholesky numeric factorization

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

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

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

3057:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3058:   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3059:   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);
3060:   MatCheckPreallocated(mat,2);

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

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

3076:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

3094:    Level: developer

3096:    Concepts: matrices^triangular solves

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

3111:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3112:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3113:   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);
3114:   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);
3115:   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);
3116:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3117:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3118:   MatCheckPreallocated(mat,1);

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

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

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

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

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

3167:    Neighbor-wise Collective on Mat

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

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

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

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

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

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

3191:    Level: developer

3193:    Concepts: matrices^triangular solves

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

3208:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3209:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3210:   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);
3211:   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);
3212:   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);
3213:   if (!A->rmap->N && !A->cmap->N) return(0);
3214:   MatCheckPreallocated(A,1);

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


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

3235:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

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

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

3261:    Level: developer

3263:    Concepts: matrices^forward solves

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

3278:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3279:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3280:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3281:   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);
3282:   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);
3283:   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);
3284:   MatCheckPreallocated(mat,1);
3285:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3286:   (*mat->ops->forwardsolve)(mat,b,x);
3287:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3288:   PetscObjectStateIncrease((PetscObject)x);
3289:   return(0);
3290: }

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

3298:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

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

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

3324:    Level: developer

3326:    Concepts: matrices^backward solves

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

3341:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3342:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3343:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3344:   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);
3345:   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);
3346:   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);
3347:   MatCheckPreallocated(mat,1);

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

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

3361:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

3379:    Level: developer

3381:    Concepts: matrices^triangular solves

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

3400:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3401:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3402:   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);
3403:   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);
3404:   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);
3405:   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);
3406:   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);
3407:   MatCheckPreallocated(mat,1);

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

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

3436:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

3453:    Level: developer

3455:    Concepts: matrices^triangular solves

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

3470:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3471:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3472:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3473:   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);
3474:   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);
3475:   MatCheckPreallocated(mat,1);
3476:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3477:   (*mat->ops->solvetranspose)(mat,b,x);
3478:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3479:   PetscObjectStateIncrease((PetscObject)x);
3480:   return(0);
3481: }

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

3489:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

3507:    Level: developer

3509:    Concepts: matrices^triangular solves

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

3528:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3529:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3530:   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);
3531:   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);
3532:   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);
3533:   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);
3534:   MatCheckPreallocated(mat,1);

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

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

3564:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

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

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

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

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

3609:    Vectors x and b CANNOT be the same

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

3613:    Level: developer

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

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

3631:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3632:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3633:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3634:   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);
3635:   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);
3636:   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);
3637:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3638:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3639:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

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

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

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

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

3682:    Collective on Mat

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

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

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

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

3699:    Level: intermediate

3701:    Concepts: matrices^copying

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

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

3717:   MatCheckPreallocated(B,2);
3718:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3719:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3720:   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);
3721:   MatCheckPreallocated(A,1);

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

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

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

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

3748:    Collective on Mat

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

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

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

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

3770:    Level: intermediate

3772:    Concepts: matrices^converting between storage formats

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

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

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

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

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

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

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

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

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

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

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

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

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

3880:    Not Collective

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

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

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

3892:    Level: intermediate

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

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

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

3918:    Collective on Mat

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

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

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

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

3934:    Level: intermediate

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


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

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

3958:     PetscObjectGetComm((PetscObject)mat,&comm);
3959:     PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3960:     if (flag) SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3961:     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);
3962:   }
3963:   (*conv)(mat,ftype,f);
3964:   return(0);
3965: }

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

3972:    Not Collective

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

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

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

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

3988:    Level: intermediate

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


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

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


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

4022:    Collective on Mat

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

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

4032:    Level: intermediate

4034:    Concepts: matrices^duplicating

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

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

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

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

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

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

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

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

4080:    Logically Collective on Mat and Vec

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

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

4089:    Level: intermediate

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

4094:    Concepts: matrices^accessing diagonals

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

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

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

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

4121:    Logically Collective on Mat and Vec

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

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

4130:    Level: intermediate

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

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

4137:    Concepts: matrices^getting row maximums

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

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

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

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

4165:    Logically Collective on Mat and Vec

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

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

4174:    Level: intermediate

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

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

4181:    Concepts: matrices^getting row maximums

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

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

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

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

4209:    Logically Collective on Mat and Vec

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

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

4218:    Level: intermediate

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

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

4225:    Concepts: matrices^getting row maximums

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

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

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

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

4252:    Logically Collective on Mat and Vec

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

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

4261:    Level: intermediate

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

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

4268:    Concepts: matrices^getting row maximums

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

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

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

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

4295:    Logically Collective on Mat and Vec

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

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

4303:    Level: intermediate

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

4307:    Concepts: matrices^getting row sums

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

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

4330:     array[row - start] = 0.0;

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

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

4348:    Collective on Mat

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

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

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

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

4362:    Level: intermediate

4364:    Concepts: matrices^transposing

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

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

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

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

4393:    Collective on Mat

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

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

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

4407:    Level: intermediate

4409:    Concepts: matrices^transposing, matrix^symmetry

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

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

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

4445:    Collective on Mat

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

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

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

4457:    Level: intermediate

4459:    Concepts: matrices^transposing, complex conjugatex

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

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

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

4480:    Collective on Mat

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

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

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

4494:    Level: intermediate

4496:    Concepts: matrices^transposing, matrix^symmetry

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

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

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

4524:    Collective on Mat

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

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

4534:    Level: advanced

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

4540:    Concepts: matrices^permuting

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

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

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

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

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

4570:    Collective on Mat

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

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

4579:    Level: intermediate

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

4594:   MatCheckPreallocated(B,2);
4595:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4596:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4597:   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);
4598:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4599:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4600:   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);
4601:   MatCheckPreallocated(A,1);

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

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

4614:    Collective on Mat

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

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

4626:    Level: intermediate

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

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

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

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

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

4669:     Logically Collective on Mat

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

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

4678:     Level: intermediate

4680:     Concepts: matrices^scaling all entries

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

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

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

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

4721:    Collective on Mat

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

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

4730:    Level: intermediate

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


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

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

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

4764:    Collective on Mat

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

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

4777:    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
4778:    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
4779:    a global collective operation requring all processes that share the matrix.

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

4785:    Level: beginner

4787:    Concepts: matrices^assembling

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

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

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

4820:    Not Collective

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

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

4828:    Level: advanced

4830:    Concepts: matrices^assembled?

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

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

4850:    Collective on Mat

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

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

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

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

4881:    Level: beginner

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


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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

5051:    Level: intermediate

5053:    Concepts: matrices^setting options

5055: .seealso:  MatOption, Mat

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

5065:   if (op > 0) {
5068:   }

5070:   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);
5071:   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()");

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

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

5126:    Logically Collective on Mat

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

5131:    Level: intermediate

5133:    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.
5134:    See the Performance chapter of the users manual for information on preallocating matrices.

5136:    Concepts: matrices^zeroing

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

5147:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5148:   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");
5149:   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5150:   MatCheckPreallocated(mat,1);

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

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

5175:    Collective on Mat

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

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

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

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

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

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

5202:    Level: intermediate

5204:    Concepts: matrices^zeroing rows

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

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

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

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

5243:    Collective on Mat

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

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

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

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

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

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

5269:    Level: intermediate

5271:    Concepts: matrices^zeroing rows

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

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

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

5299:    Collective on Mat

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

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

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

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

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

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

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

5333:    Level: intermediate

5335:    Concepts: matrices^zeroing rows

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

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

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

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

5374:    Collective on Mat

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

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

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

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

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

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

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

5407:    Level: intermediate

5409:    Concepts: matrices^zeroing rows

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

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

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

5436:    Collective on Mat

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

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

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

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

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

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

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

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

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

5483:    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
5484:    a single value per point) you can skip filling those indices.

5486:    Level: intermediate

5488:    Concepts: matrices^zeroing rows

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


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

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

5538:    Collective on Mat

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

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

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

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

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

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

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

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

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

5585:    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
5586:    a single value per point) you can skip filling those indices.

5588:    Level: intermediate

5590:    Concepts: matrices^zeroing rows

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


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

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

5640:    Collective on Mat

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

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

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

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

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

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

5669:    Level: intermediate

5671:    Concepts: matrices^zeroing

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

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

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

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

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

5722:    Collective on Mat

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

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

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

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

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

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

5750:    Level: intermediate

5752:    Concepts: matrices^zeroing

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

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

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

5779: /*@C
5780:    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5781:    of a set of rows and columns of a matrix; using local numbering of rows.

5783:    Collective on Mat

5785:    Input Parameters:
5786: +  mat - the matrix
5787: .  numRows - the number of rows to remove
5788: .  rows - the global row indices
5789: .  diag - value put in all diagonals of eliminated rows
5790: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5791: -  b - optional vector of right hand side, that will be adjusted by provided solution

5793:    Notes:
5794:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5795:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5801:    Level: intermediate

5803:    Concepts: matrices^zeroing

5805: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5806: @*/
5807: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5808: {
5810:   IS             is, newis;
5811:   const PetscInt *newRows;

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

5821:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5822:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5823:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5824:   ISGetIndices(newis,&newRows);
5825:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5826:   ISRestoreIndices(newis,&newRows);
5827:   ISDestroy(&newis);
5828:   ISDestroy(&is);
5829:   PetscObjectStateIncrease((PetscObject)mat);
5830: #if defined(PETSC_HAVE_CUSP)
5831:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5832:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5833:   }
5834: #endif
5835: #if defined(PETSC_HAVE_VIENNACL)
5836:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5837:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5838:   }
5839: #endif
5840:   return(0);
5841: }

5845: /*@C
5846:    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5847:    of a set of rows and columns of a matrix; using local numbering of rows.

5849:    Collective on Mat

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

5858:    Notes:
5859:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5860:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5866:    Level: intermediate

5868:    Concepts: matrices^zeroing

5870: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5871: @*/
5872: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5873: {
5875:   PetscInt       numRows;
5876:   const PetscInt *rows;

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

5886:   ISGetLocalSize(is,&numRows);
5887:   ISGetIndices(is,&rows);
5888:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5889:   ISRestoreIndices(is,&rows);
5890:   return(0);
5891: }

5895: /*@
5896:    MatGetSize - Returns the numbers of rows and columns in a matrix.

5898:    Not Collective

5900:    Input Parameter:
5901: .  mat - the matrix

5903:    Output Parameters:
5904: +  m - the number of global rows
5905: -  n - the number of global columns

5907:    Note: both output parameters can be NULL on input.

5909:    Level: beginner

5911:    Concepts: matrices^size

5913: .seealso: MatGetLocalSize()
5914: @*/
5915: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
5916: {
5919:   if (m) *m = mat->rmap->N;
5920:   if (n) *n = mat->cmap->N;
5921:   return(0);
5922: }

5926: /*@
5927:    MatGetLocalSize - Returns the number of rows and columns in a matrix
5928:    stored locally.  This information may be implementation dependent, so
5929:    use with care.

5931:    Not Collective

5933:    Input Parameters:
5934: .  mat - the matrix

5936:    Output Parameters:
5937: +  m - the number of local rows
5938: -  n - the number of local columns

5940:    Note: both output parameters can be NULL on input.

5942:    Level: beginner

5944:    Concepts: matrices^local size

5946: .seealso: MatGetSize()
5947: @*/
5948: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
5949: {
5954:   if (m) *m = mat->rmap->n;
5955:   if (n) *n = mat->cmap->n;
5956:   return(0);
5957: }

5961: /*@
5962:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5963:    this processor. (The columns of the "diagonal block")

5965:    Not Collective, unless matrix has not been allocated, then collective on Mat

5967:    Input Parameters:
5968: .  mat - the matrix

5970:    Output Parameters:
5971: +  m - the global index of the first local column
5972: -  n - one more than the global index of the last local column

5974:    Notes: both output parameters can be NULL on input.

5976:    Level: developer

5978:    Concepts: matrices^column ownership

5980: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

5982: @*/
5983: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
5984: {
5990:   MatCheckPreallocated(mat,1);
5991:   if (m) *m = mat->cmap->rstart;
5992:   if (n) *n = mat->cmap->rend;
5993:   return(0);
5994: }

5998: /*@
5999:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6000:    this processor, assuming that the matrix is laid out with the first
6001:    n1 rows on the first processor, the next n2 rows on the second, etc.
6002:    For certain parallel layouts this range may not be well defined.

6004:    Not Collective

6006:    Input Parameters:
6007: .  mat - the matrix

6009:    Output Parameters:
6010: +  m - the global index of the first local row
6011: -  n - one more than the global index of the last local row

6013:    Note: Both output parameters can be NULL on input.
6014: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6015: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6016: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

6018:    Level: beginner

6020:    Concepts: matrices^row ownership

6022: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

6024: @*/
6025: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6026: {
6032:   MatCheckPreallocated(mat,1);
6033:   if (m) *m = mat->rmap->rstart;
6034:   if (n) *n = mat->rmap->rend;
6035:   return(0);
6036: }

6040: /*@C
6041:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6042:    each process

6044:    Not Collective, unless matrix has not been allocated, then collective on Mat

6046:    Input Parameters:
6047: .  mat - the matrix

6049:    Output Parameters:
6050: .  ranges - start of each processors portion plus one more then the total length at the end

6052:    Level: beginner

6054:    Concepts: matrices^row ownership

6056: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6058: @*/
6059: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6060: {

6066:   MatCheckPreallocated(mat,1);
6067:   PetscLayoutGetRanges(mat->rmap,ranges);
6068:   return(0);
6069: }

6073: /*@C
6074:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6075:    this processor. (The columns of the "diagonal blocks" for each process)

6077:    Not Collective, unless matrix has not been allocated, then collective on Mat

6079:    Input Parameters:
6080: .  mat - the matrix

6082:    Output Parameters:
6083: .  ranges - start of each processors portion plus one more then the total length at the end

6085:    Level: beginner

6087:    Concepts: matrices^column ownership

6089: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6091: @*/
6092: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6093: {

6099:   MatCheckPreallocated(mat,1);
6100:   PetscLayoutGetRanges(mat->cmap,ranges);
6101:   return(0);
6102: }

6106: /*@C
6107:    MatGetOwnershipIS - Get row and column ownership as index sets

6109:    Not Collective

6111:    Input Arguments:
6112: .  A - matrix of type Elemental

6114:    Output Arguments:
6115: +  rows - rows in which this process owns elements
6116: .  cols - columns in which this process owns elements

6118:    Level: intermediate

6120: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6121: @*/
6122: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6123: {
6124:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6127:   MatCheckPreallocated(A,1);
6128:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6129:   if (f) {
6130:     (*f)(A,rows,cols);
6131:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6132:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6133:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6134:   }
6135:   return(0);
6136: }

6140: /*@C
6141:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6142:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6143:    to complete the factorization.

6145:    Collective on Mat

6147:    Input Parameters:
6148: +  mat - the matrix
6149: .  row - row permutation
6150: .  column - column permutation
6151: -  info - structure containing
6152: $      levels - number of levels of fill.
6153: $      expected fill - as ratio of original fill.
6154: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6155:                 missing diagonal entries)

6157:    Output Parameters:
6158: .  fact - new matrix that has been symbolically factored

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

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

6166:    Level: developer

6168:   Concepts: matrices^symbolic LU factorization
6169:   Concepts: matrices^factorization
6170:   Concepts: LU^symbolic factorization

6172: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6173:           MatGetOrdering(), MatFactorInfo

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

6178: @*/
6179: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6180: {

6190:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6191:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6192:   if (!(fact)->ops->ilufactorsymbolic) {
6193:     const MatSolverPackage spackage;
6194:     MatFactorGetSolverPackage(fact,&spackage);
6195:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6196:   }
6197:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6198:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6199:   MatCheckPreallocated(mat,2);

6201:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6202:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6203:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6204:   return(0);
6205: }

6209: /*@C
6210:    MatICCFactorSymbolic - Performs symbolic incomplete
6211:    Cholesky factorization for a symmetric matrix.  Use
6212:    MatCholeskyFactorNumeric() to complete the factorization.

6214:    Collective on Mat

6216:    Input Parameters:
6217: +  mat - the matrix
6218: .  perm - row and column permutation
6219: -  info - structure containing
6220: $      levels - number of levels of fill.
6221: $      expected fill - as ratio of original fill.

6223:    Output Parameter:
6224: .  fact - the factored matrix

6226:    Notes:
6227:    Most users should employ the KSP interface for linear solvers
6228:    instead of working directly with matrix algebra routines such as this.
6229:    See, e.g., KSPCreate().

6231:    Level: developer

6233:   Concepts: matrices^symbolic incomplete Cholesky factorization
6234:   Concepts: matrices^factorization
6235:   Concepts: Cholsky^symbolic factorization

6237: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

6242: @*/
6243: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6244: {

6253:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6254:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6255:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6256:   if (!(fact)->ops->iccfactorsymbolic) {
6257:     const MatSolverPackage spackage;
6258:     MatFactorGetSolverPackage(fact,&spackage);
6259:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6260:   }
6261:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6262:   MatCheckPreallocated(mat,2);

6264:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6265:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6266:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6267:   return(0);
6268: }

6272: /*@C
6273:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6274:    points to an array of valid matrices, they may be reused to store the new
6275:    submatrices.

6277:    Collective on Mat

6279:    Input Parameters:
6280: +  mat - the matrix
6281: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6282: .  irow, icol - index sets of rows and columns to extract (must be sorted)
6283: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6285:    Output Parameter:
6286: .  submat - the array of submatrices

6288:    Notes:
6289:    MatGetSubMatrices() can extract ONLY sequential submatrices
6290:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6291:    to extract a parallel submatrix.

6293:    Currently both row and column indices must be sorted to guarantee
6294:    correctness with all matrix types.

6296:    When extracting submatrices from a parallel matrix, each processor can
6297:    form a different submatrix by setting the rows and columns of its
6298:    individual index sets according to the local submatrix desired.

6300:    When finished using the submatrices, the user should destroy
6301:    them with MatDestroyMatrices().

6303:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6304:    original matrix has not changed from that last call to MatGetSubMatrices().

6306:    This routine creates the matrices in submat; you should NOT create them before
6307:    calling it. It also allocates the array of matrix pointers submat.

6309:    For BAIJ matrices the index sets must respect the block structure, that is if they
6310:    request one row/column in a block, they must request all rows/columns that are in
6311:    that block. For example, if the block size is 2 you cannot request just row 0 and
6312:    column 0.

6314:    Fortran Note:
6315:    The Fortran interface is slightly different from that given below; it
6316:    requires one to pass in  as submat a Mat (integer) array of size at least m.

6318:    Level: advanced

6320:    Concepts: matrices^accessing submatrices
6321:    Concepts: submatrices

6323: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6324: @*/
6325: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6326: {
6328:   PetscInt       i;
6329:   PetscBool      eq;

6334:   if (n) {
6339:   }
6341:   if (n && scall == MAT_REUSE_MATRIX) {
6344:   }
6345:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6346:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6347:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6348:   MatCheckPreallocated(mat,1);

6350:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6351:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6352:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6353:   for (i=0; i<n; i++) {
6354:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6355:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6356:       ISEqual(irow[i],icol[i],&eq);
6357:       if (eq) {
6358:         if (mat->symmetric) {
6359:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6360:         } else if (mat->hermitian) {
6361:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6362:         } else if (mat->structurally_symmetric) {
6363:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6364:         }
6365:       }
6366:     }
6367:   }
6368:   return(0);
6369: }

6373: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6374: {
6376:   PetscInt       i;
6377:   PetscBool      eq;

6382:   if (n) {
6387:   }
6389:   if (n && scall == MAT_REUSE_MATRIX) {
6392:   }
6393:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6394:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6395:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6396:   MatCheckPreallocated(mat,1);

6398:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6399:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6400:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6401:   for (i=0; i<n; i++) {
6402:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6403:       ISEqual(irow[i],icol[i],&eq);
6404:       if (eq) {
6405:         if (mat->symmetric) {
6406:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6407:         } else if (mat->hermitian) {
6408:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6409:         } else if (mat->structurally_symmetric) {
6410:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6411:         }
6412:       }
6413:     }
6414:   }
6415:   return(0);
6416: }

6420: /*@C
6421:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().

6423:    Collective on Mat

6425:    Input Parameters:
6426: +  n - the number of local matrices
6427: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6428:                        sequence of MatGetSubMatrices())

6430:    Level: advanced

6432:     Notes: Frees not only the matrices, but also the array that contains the matrices
6433:            In Fortran will not free the array.

6435: .seealso: MatGetSubMatrices()
6436: @*/
6437: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6438: {
6440:   PetscInt       i;

6443:   if (!*mat) return(0);
6444:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6446:   for (i=0; i<n; i++) {
6447:     MatDestroy(&(*mat)[i]);
6448:   }
6449:   /* memory is allocated even if n = 0 */
6450:   PetscFree(*mat);
6451:   *mat = NULL;
6452:   return(0);
6453: }

6457: /*@C
6458:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.

6460:    Collective on Mat

6462:    Input Parameters:
6463: .  mat - the matrix

6465:    Output Parameter:
6466: .  matstruct - the sequential matrix with the nonzero structure of mat

6468:   Level: intermediate

6470: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6471: @*/
6472: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6473: {


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

6484:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6485:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6486:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6487:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6488:   return(0);
6489: }

6493: /*@C
6494:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6496:    Collective on Mat

6498:    Input Parameters:
6499: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6500:                        sequence of MatGetSequentialNonzeroStructure())

6502:    Level: advanced

6504:     Notes: Frees not only the matrices, but also the array that contains the matrices

6506: .seealso: MatGetSeqNonzeroStructure()
6507: @*/
6508: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6509: {

6514:   MatDestroy(mat);
6515:   return(0);
6516: }

6520: /*@
6521:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6522:    replaces the index sets by larger ones that represent submatrices with
6523:    additional overlap.

6525:    Collective on Mat

6527:    Input Parameters:
6528: +  mat - the matrix
6529: .  n   - the number of index sets
6530: .  is  - the array of index sets (these index sets will changed during the call)
6531: -  ov  - the additional overlap requested

6533:    Level: developer

6535:    Concepts: overlap
6536:    Concepts: ASM^computing overlap

6538: .seealso: MatGetSubMatrices()
6539: @*/
6540: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6541: {

6547:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6548:   if (n) {
6551:   }
6552:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6553:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6554:   MatCheckPreallocated(mat,1);

6556:   if (!ov) return(0);
6557:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6558:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6559:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6560:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6561:   return(0);
6562: }

6566: /*@
6567:    MatGetBlockSize - Returns the matrix block size; useful especially for the
6568:    block row and block diagonal formats.

6570:    Not Collective

6572:    Input Parameter:
6573: .  mat - the matrix

6575:    Output Parameter:
6576: .  bs - block size

6578:    Notes:
6579:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ.

6581:    If the block size has not been set yet this routine returns -1.

6583:    Level: intermediate

6585:    Concepts: matrices^block size

6587: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6588: @*/
6589: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6590: {
6594:   *bs = PetscAbs(mat->rmap->bs);
6595:   return(0);
6596: }

6600: /*@
6601:    MatGetBlockSizes - Returns the matrix block row and column sizes;
6602:    useful especially for the block row and block diagonal formats.

6604:    Not Collective

6606:    Input Parameter:
6607: .  mat - the matrix

6609:    Output Parameter:
6610: .  rbs - row block size
6611: .  cbs - coumn block size

6613:    Notes:
6614:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ.

6616:    If a block size has not been set yet this routine returns -1.

6618:    Level: intermediate

6620:    Concepts: matrices^block size

6622: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6623: @*/
6624: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6625: {
6630:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
6631:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
6632:   return(0);
6633: }

6637: /*@
6638:    MatSetBlockSize - Sets the matrix block size.

6640:    Logically Collective on Mat

6642:    Input Parameters:
6643: +  mat - the matrix
6644: -  bs - block size

6646:    Notes:
6647:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6649:    Level: intermediate

6651:    Concepts: matrices^block size

6653: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6654: @*/
6655: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6656: {

6662:   PetscLayoutSetBlockSize(mat->rmap,bs);
6663:   PetscLayoutSetBlockSize(mat->cmap,bs);
6664:   return(0);
6665: }

6669: /*@
6670:    MatSetBlockSizes - Sets the matrix block row and column sizes.

6672:    Logically Collective on Mat

6674:    Input Parameters:
6675: +  mat - the matrix
6676: -  rbs - row block size
6677: -  cbs - column block size

6679:    Notes:
6680:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6682:    Level: intermediate

6684:    Concepts: matrices^block size

6686: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6687: @*/
6688: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6689: {

6696:   PetscLayoutSetBlockSize(mat->rmap,rbs);
6697:   PetscLayoutSetBlockSize(mat->cmap,cbs);
6698:   return(0);
6699: }

6703: /*@
6704:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

6706:    Logically Collective on Mat

6708:    Input Parameters:
6709: +  mat - the matrix
6710: .  fromRow - matrix from which to copy row block size
6711: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

6713:    Level: developer

6715:    Concepts: matrices^block size

6717: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
6718: @*/
6719: PetscErrorCode  MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
6720: {

6727:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
6728:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
6729:   return(0);
6730: }

6734: /*@
6735:    MatResidual - Default routine to calculate the residual.

6737:    Collective on Mat and Vec

6739:    Input Parameters:
6740: +  mat - the matrix
6741: .  b   - the right-hand-side
6742: -  x   - the approximate solution

6744:    Output Parameter:
6745: .  r - location to store the residual

6747:    Level: developer

6749: .keywords: MG, default, multigrid, residual

6751: .seealso: PCMGSetResidual()
6752: @*/
6753: PetscErrorCode  MatResidual(Mat mat,Vec b,Vec x,Vec r)
6754: {

6763:   MatCheckPreallocated(mat,1);
6764:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
6765:   if (!mat->ops->residual) {
6766:     MatMult(mat,x,r);
6767:     VecAYPX(r,-1.0,b);
6768:   } else {
6769:     (*mat->ops->residual)(mat,b,x,r);
6770:   }
6771:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
6772:   return(0);
6773: }

6777: /*@C
6778:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.

6780:    Collective on Mat

6782:     Input Parameters:
6783: +   mat - the matrix
6784: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6785: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6786: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6787:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6788:                  always used.

6790:     Output Parameters:
6791: +   n - number of rows in the (possibly compressed) matrix
6792: .   ia - the row pointers [of length n+1]
6793: .   ja - the column indices
6794: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6795:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

6797:     Level: developer

6799:     Notes: You CANNOT change any of the ia[] or ja[] values.

6801:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

6803:     Fortran Node

6805:            In Fortran use
6806: $           PetscInt ia(1), ja(1)
6807: $           PetscOffset iia, jja
6808: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6809: $
6810: $          or
6811: $
6812: $           PetscScalar, pointer :: xx_v(:)
6813: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)


6816:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

6818: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6819: @*/
6820: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6821: {

6831:   MatCheckPreallocated(mat,1);
6832:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6833:   else {
6834:     *done = PETSC_TRUE;
6835:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6836:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6837:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6838:   }
6839:   return(0);
6840: }

6844: /*@C
6845:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.

6847:     Collective on Mat

6849:     Input Parameters:
6850: +   mat - the matrix
6851: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6852: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6853:                 symmetrized
6854: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6855:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6856:                  always used.
6857: .   n - number of columns in the (possibly compressed) matrix
6858: .   ia - the column pointers
6859: -   ja - the row indices

6861:     Output Parameters:
6862: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6864:     Note:
6865:     This routine zeros out n, ia, and ja. This is to prevent accidental
6866:     us of the array after it has been restored. If you pass NULL, it will
6867:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

6869:     Level: developer

6871: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6872: @*/
6873: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6874: {

6884:   MatCheckPreallocated(mat,1);
6885:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6886:   else {
6887:     *done = PETSC_TRUE;
6888:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6889:   }
6890:   return(0);
6891: }

6895: /*@C
6896:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6897:     MatGetRowIJ().

6899:     Collective on Mat

6901:     Input Parameters:
6902: +   mat - the matrix
6903: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6904: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6905:                 symmetrized
6906: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6907:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6908:                  always used.
6909: .   n - size of (possibly compressed) matrix
6910: .   ia - the row pointers
6911: -   ja - the column indices

6913:     Output Parameters:
6914: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6916:     Note:
6917:     This routine zeros out n, ia, and ja. This is to prevent accidental
6918:     us of the array after it has been restored. If you pass NULL, it will
6919:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

6921:     Level: developer

6923: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6924: @*/
6925: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6926: {

6935:   MatCheckPreallocated(mat,1);

6937:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6938:   else {
6939:     *done = PETSC_TRUE;
6940:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6941:     if (n)  *n = 0;
6942:     if (ia) *ia = NULL;
6943:     if (ja) *ja = NULL;
6944:   }
6945:   return(0);
6946: }

6950: /*@C
6951:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6952:     MatGetColumnIJ().

6954:     Collective on Mat

6956:     Input Parameters:
6957: +   mat - the matrix
6958: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6959: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6960:                 symmetrized
6961: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6962:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6963:                  always used.

6965:     Output Parameters:
6966: +   n - size of (possibly compressed) matrix
6967: .   ia - the column pointers
6968: .   ja - the row indices
6969: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6971:     Level: developer

6973: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6974: @*/
6975: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6976: {

6985:   MatCheckPreallocated(mat,1);

6987:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6988:   else {
6989:     *done = PETSC_TRUE;
6990:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6991:     if (n)  *n = 0;
6992:     if (ia) *ia = NULL;
6993:     if (ja) *ja = NULL;
6994:   }
6995:   return(0);
6996: }

7000: /*@C
7001:     MatColoringPatch -Used inside matrix coloring routines that
7002:     use MatGetRowIJ() and/or MatGetColumnIJ().

7004:     Collective on Mat

7006:     Input Parameters:
7007: +   mat - the matrix
7008: .   ncolors - max color value
7009: .   n   - number of entries in colorarray
7010: -   colorarray - array indicating color for each column

7012:     Output Parameters:
7013: .   iscoloring - coloring generated using colorarray information

7015:     Level: developer

7017: .seealso: MatGetRowIJ(), MatGetColumnIJ()

7019: @*/
7020: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7021: {

7029:   MatCheckPreallocated(mat,1);

7031:   if (!mat->ops->coloringpatch) {
7032:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);
7033:   } else {
7034:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7035:   }
7036:   return(0);
7037: }


7042: /*@
7043:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.

7045:    Logically Collective on Mat

7047:    Input Parameter:
7048: .  mat - the factored matrix to be reset

7050:    Notes:
7051:    This routine should be used only with factored matrices formed by in-place
7052:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7053:    format).  This option can save memory, for example, when solving nonlinear
7054:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7055:    ILU(0) preconditioner.

7057:    Note that one can specify in-place ILU(0) factorization by calling
7058: .vb
7059:      PCType(pc,PCILU);
7060:      PCFactorSeUseInPlace(pc);
7061: .ve
7062:    or by using the options -pc_type ilu -pc_factor_in_place

7064:    In-place factorization ILU(0) can also be used as a local
7065:    solver for the blocks within the block Jacobi or additive Schwarz
7066:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7067:    for details on setting local solver options.

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

7073:    Level: developer

7075: .seealso: PCFactorSetUseInPlace()

7077:    Concepts: matrices^unfactored

7079: @*/
7080: PetscErrorCode  MatSetUnfactored(Mat mat)
7081: {

7087:   MatCheckPreallocated(mat,1);
7088:   mat->factortype = MAT_FACTOR_NONE;
7089:   if (!mat->ops->setunfactored) return(0);
7090:   (*mat->ops->setunfactored)(mat);
7091:   return(0);
7092: }

7094: /*MC
7095:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7097:     Synopsis:
7098:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7100:     Not collective

7102:     Input Parameter:
7103: .   x - matrix

7105:     Output Parameters:
7106: +   xx_v - the Fortran90 pointer to the array
7107: -   ierr - error code

7109:     Example of Usage:
7110: .vb
7111:       PetscScalar, pointer xx_v(:,:)
7112:       ....
7113:       call MatDenseGetArrayF90(x,xx_v,ierr)
7114:       a = xx_v(3)
7115:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7116: .ve

7118:     Level: advanced

7120: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()

7122:     Concepts: matrices^accessing array

7124: M*/

7126: /*MC
7127:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7128:     accessed with MatDenseGetArrayF90().

7130:     Synopsis:
7131:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7133:     Not collective

7135:     Input Parameters:
7136: +   x - matrix
7137: -   xx_v - the Fortran90 pointer to the array

7139:     Output Parameter:
7140: .   ierr - error code

7142:     Example of Usage:
7143: .vb
7144:        PetscScalar, pointer xx_v(:)
7145:        ....
7146:        call MatDenseGetArrayF90(x,xx_v,ierr)
7147:        a = xx_v(3)
7148:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7149: .ve

7151:     Level: advanced

7153: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()

7155: M*/


7158: /*MC
7159:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7161:     Synopsis:
7162:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7164:     Not collective

7166:     Input Parameter:
7167: .   x - matrix

7169:     Output Parameters:
7170: +   xx_v - the Fortran90 pointer to the array
7171: -   ierr - error code

7173:     Example of Usage:
7174: .vb
7175:       PetscScalar, pointer xx_v(:,:)
7176:       ....
7177:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7178:       a = xx_v(3)
7179:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7180: .ve

7182:     Level: advanced

7184: .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()

7186:     Concepts: matrices^accessing array

7188: M*/

7190: /*MC
7191:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7192:     accessed with MatSeqAIJGetArrayF90().

7194:     Synopsis:
7195:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7197:     Not collective

7199:     Input Parameters:
7200: +   x - matrix
7201: -   xx_v - the Fortran90 pointer to the array

7203:     Output Parameter:
7204: .   ierr - error code

7206:     Example of Usage:
7207: .vb
7208:        PetscScalar, pointer xx_v(:)
7209:        ....
7210:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7211:        a = xx_v(3)
7212:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7213: .ve

7215:     Level: advanced

7217: .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()

7219: M*/


7224: /*@
7225:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7226:                       as the original matrix.

7228:     Collective on Mat

7230:     Input Parameters:
7231: +   mat - the original matrix
7232: .   isrow - parallel IS containing the rows this processor should obtain
7233: .   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.
7234: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7236:     Output Parameter:
7237: .   newmat - the new submatrix, of the same type as the old

7239:     Level: advanced

7241:     Notes:
7242:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7244:     The rows in isrow will be sorted into the same order as the original matrix on each process.

7246:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7247:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7248:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7249:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7250:    you are finished using it.

7252:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7253:     the input matrix.

7255:     If iscol is NULL then all columns are obtained (not supported in Fortran).

7257:    Example usage:
7258:    Consider the following 8x8 matrix with 34 non-zero values, that is
7259:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7260:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7261:    as follows:

7263: .vb
7264:             1  2  0  |  0  3  0  |  0  4
7265:     Proc0   0  5  6  |  7  0  0  |  8  0
7266:             9  0 10  | 11  0  0  | 12  0
7267:     -------------------------------------
7268:            13  0 14  | 15 16 17  |  0  0
7269:     Proc1   0 18  0  | 19 20 21  |  0  0
7270:             0  0  0  | 22 23  0  | 24  0
7271:     -------------------------------------
7272:     Proc2  25 26 27  |  0  0 28  | 29  0
7273:            30  0  0  | 31 32 33  |  0 34
7274: .ve

7276:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7278: .vb
7279:             2  0  |  0  3  0  |  0
7280:     Proc0   5  6  |  7  0  0  |  8
7281:     -------------------------------
7282:     Proc1  18  0  | 19 20 21  |  0
7283:     -------------------------------
7284:     Proc2  26 27  |  0  0 28  | 29
7285:             0  0  | 31 32 33  |  0
7286: .ve


7289:     Concepts: matrices^submatrices

7291: .seealso: MatGetSubMatrices()
7292: @*/
7293: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7294: {
7296:   PetscMPIInt    size;
7297:   Mat            *local;
7298:   IS             iscoltmp;

7307:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7308:   MatCheckPreallocated(mat,1);
7309:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7311:   if (!iscol) {
7312:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7313:   } else {
7314:     iscoltmp = iscol;
7315:   }

7317:   /* if original matrix is on just one processor then use submatrix generated */
7318:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7319:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7320:     if (!iscol) {ISDestroy(&iscoltmp);}
7321:     return(0);
7322:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7323:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7324:     *newmat = *local;
7325:     PetscFree(local);
7326:     if (!iscol) {ISDestroy(&iscoltmp);}
7327:     return(0);
7328:   } else if (!mat->ops->getsubmatrix) {
7329:     /* Create a new matrix type that implements the operation using the full matrix */
7330:     switch (cll) {
7331:     case MAT_INITIAL_MATRIX:
7332:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7333:       break;
7334:     case MAT_REUSE_MATRIX:
7335:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7336:       break;
7337:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7338:     }
7339:     if (!iscol) {ISDestroy(&iscoltmp);}
7340:     return(0);
7341:   }

7343:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7344:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7345:   if (!iscol) {ISDestroy(&iscoltmp);}
7346:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7347:   return(0);
7348: }

7352: /*@
7353:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7354:    used during the assembly process to store values that belong to
7355:    other processors.

7357:    Not Collective

7359:    Input Parameters:
7360: +  mat   - the matrix
7361: .  size  - the initial size of the stash.
7362: -  bsize - the initial size of the block-stash(if used).

7364:    Options Database Keys:
7365: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7366: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7368:    Level: intermediate

7370:    Notes:
7371:      The block-stash is used for values set with MatSetValuesBlocked() while
7372:      the stash is used for values set with MatSetValues()

7374:      Run with the option -info and look for output of the form
7375:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7376:      to determine the appropriate value, MM, to use for size and
7377:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7378:      to determine the value, BMM to use for bsize

7380:    Concepts: stash^setting matrix size
7381:    Concepts: matrices^stash

7383: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7385: @*/
7386: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7387: {

7393:   MatStashSetInitialSize_Private(&mat->stash,size);
7394:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7395:   return(0);
7396: }

7400: /*@
7401:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7402:      the matrix

7404:    Neighbor-wise Collective on Mat

7406:    Input Parameters:
7407: +  mat   - the matrix
7408: .  x,y - the vectors
7409: -  w - where the result is stored

7411:    Level: intermediate

7413:    Notes:
7414:     w may be the same vector as y.

7416:     This allows one to use either the restriction or interpolation (its transpose)
7417:     matrix to do the interpolation

7419:     Concepts: interpolation

7421: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7423: @*/
7424: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7425: {
7427:   PetscInt       M,N,Ny;

7435:   MatCheckPreallocated(A,1);
7436:   MatGetSize(A,&M,&N);
7437:   VecGetSize(y,&Ny);
7438:   if (M == Ny) {
7439:     MatMultAdd(A,x,y,w);
7440:   } else {
7441:     MatMultTransposeAdd(A,x,y,w);
7442:   }
7443:   return(0);
7444: }

7448: /*@
7449:    MatInterpolate - y = A*x or A'*x depending on the shape of
7450:      the matrix

7452:    Neighbor-wise Collective on Mat

7454:    Input Parameters:
7455: +  mat   - the matrix
7456: -  x,y - the vectors

7458:    Level: intermediate

7460:    Notes:
7461:     This allows one to use either the restriction or interpolation (its transpose)
7462:     matrix to do the interpolation

7464:    Concepts: matrices^interpolation

7466: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7468: @*/
7469: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7470: {
7472:   PetscInt       M,N,Ny;

7479:   MatCheckPreallocated(A,1);
7480:   MatGetSize(A,&M,&N);
7481:   VecGetSize(y,&Ny);
7482:   if (M == Ny) {
7483:     MatMult(A,x,y);
7484:   } else {
7485:     MatMultTranspose(A,x,y);
7486:   }
7487:   return(0);
7488: }

7492: /*@
7493:    MatRestrict - y = A*x or A'*x

7495:    Neighbor-wise Collective on Mat

7497:    Input Parameters:
7498: +  mat   - the matrix
7499: -  x,y - the vectors

7501:    Level: intermediate

7503:    Notes:
7504:     This allows one to use either the restriction or interpolation (its transpose)
7505:     matrix to do the restriction

7507:    Concepts: matrices^restriction

7509: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()

7511: @*/
7512: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7513: {
7515:   PetscInt       M,N,Ny;

7522:   MatCheckPreallocated(A,1);

7524:   MatGetSize(A,&M,&N);
7525:   VecGetSize(y,&Ny);
7526:   if (M == Ny) {
7527:     MatMult(A,x,y);
7528:   } else {
7529:     MatMultTranspose(A,x,y);
7530:   }
7531:   return(0);
7532: }

7536: /*@
7537:    MatGetNullSpace - retrieves the null space to a matrix.

7539:    Logically Collective on Mat and MatNullSpace

7541:    Input Parameters:
7542: +  mat - the matrix
7543: -  nullsp - the null space object

7545:    Level: developer

7547:    Notes:
7548:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7550:    Concepts: null space^attaching to matrix

7552: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7553: @*/
7554: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7555: {
7560:   *nullsp = mat->nullsp;
7561:   return(0);
7562: }

7566: /*@
7567:    MatSetNullSpace - attaches a null space to a matrix.
7568:         This null space will be removed from the resulting vector whenever
7569:         MatMult() is called

7571:    Logically Collective on Mat and MatNullSpace

7573:    Input Parameters:
7574: +  mat - the matrix
7575: -  nullsp - the null space object

7577:    Level: advanced

7579:    Notes:
7580:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7582:    Concepts: null space^attaching to matrix

7584: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7585: @*/
7586: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7587: {

7594:   MatCheckPreallocated(mat,1);
7595:   PetscObjectReference((PetscObject)nullsp);
7596:   MatNullSpaceDestroy(&mat->nullsp);

7598:   mat->nullsp = nullsp;
7599:   return(0);
7600: }

7604: /*@
7605:    MatSetNearNullSpace - attaches a null space to a matrix.
7606:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

7608:    Logically Collective on Mat and MatNullSpace

7610:    Input Parameters:
7611: +  mat - the matrix
7612: -  nullsp - the null space object

7614:    Level: advanced

7616:    Notes:
7617:       Overwrites any previous near null space that may have been attached

7619:    Concepts: null space^attaching to matrix

7621: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7622: @*/
7623: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7624: {

7631:   MatCheckPreallocated(mat,1);
7632:   PetscObjectReference((PetscObject)nullsp);
7633:   MatNullSpaceDestroy(&mat->nearnullsp);

7635:   mat->nearnullsp = nullsp;
7636:   return(0);
7637: }

7641: /*@
7642:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

7644:    Not Collective

7646:    Input Parameters:
7647: .  mat - the matrix

7649:    Output Parameters:
7650: .  nullsp - the null space object, NULL if not set

7652:    Level: developer

7654:    Concepts: null space^attaching to matrix

7656: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7657: @*/
7658: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7659: {
7664:   MatCheckPreallocated(mat,1);
7665:   *nullsp = mat->nearnullsp;
7666:   return(0);
7667: }

7671: /*@C
7672:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

7674:    Collective on Mat

7676:    Input Parameters:
7677: +  mat - the matrix
7678: .  row - row/column permutation
7679: .  fill - expected fill factor >= 1.0
7680: -  level - level of fill, for ICC(k)

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

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

7690:    Level: developer

7692:    Concepts: matrices^incomplete Cholesky factorization
7693:    Concepts: Cholesky factorization

7695: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

7700: @*/
7701: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7702: {

7710:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
7711:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7712:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7713:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7714:   MatCheckPreallocated(mat,1);
7715:   (*mat->ops->iccfactor)(mat,row,info);
7716:   PetscObjectStateIncrease((PetscObject)mat);
7717:   return(0);
7718: }

7722: /*@
7723:    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.

7725:    Not Collective

7727:    Input Parameters:
7728: +  mat - the matrix
7729: .  nl - leading dimension of v
7730: -  v - the values compute with ADIFOR

7732:    Level: developer

7734:    Notes:
7735:      Must call MatSetColoring() before using this routine. Also this matrix must already
7736:      have its nonzero pattern determined.

7738: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7739:           MatSetValues(), MatSetColoring()
7740: @*/
7741: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7742: {


7750:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7751:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7752:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7753:   (*mat->ops->setvaluesadifor)(mat,nl,v);
7754:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7755:   PetscObjectStateIncrease((PetscObject)mat);
7756:   return(0);
7757: }

7761: /*@
7762:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7763:          ghosted ones.

7765:    Not Collective

7767:    Input Parameters:
7768: +  mat - the matrix
7769: -  diag = the diagonal values, including ghost ones

7771:    Level: developer

7773:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

7775: .seealso: MatDiagonalScale()
7776: @*/
7777: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7778: {
7780:   PetscMPIInt    size;


7787:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7788:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7789:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7790:   if (size == 1) {
7791:     PetscInt n,m;
7792:     VecGetSize(diag,&n);
7793:     MatGetSize(mat,0,&m);
7794:     if (m == n) {
7795:       MatDiagonalScale(mat,0,diag);
7796:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7797:   } else {
7798:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7799:   }
7800:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7801:   PetscObjectStateIncrease((PetscObject)mat);
7802:   return(0);
7803: }

7807: /*@
7808:    MatGetInertia - Gets the inertia from a factored matrix

7810:    Collective on Mat

7812:    Input Parameter:
7813: .  mat - the matrix

7815:    Output Parameters:
7816: +   nneg - number of negative eigenvalues
7817: .   nzero - number of zero eigenvalues
7818: -   npos - number of positive eigenvalues

7820:    Level: advanced

7822:    Notes: Matrix must have been factored by MatCholeskyFactor()


7825: @*/
7826: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7827: {

7833:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7834:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7835:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7836:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7837:   return(0);
7838: }

7840: /* ----------------------------------------------------------------*/
7843: /*@C
7844:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

7846:    Neighbor-wise Collective on Mat and Vecs

7848:    Input Parameters:
7849: +  mat - the factored matrix
7850: -  b - the right-hand-side vectors

7852:    Output Parameter:
7853: .  x - the result vectors

7855:    Notes:
7856:    The vectors b and x cannot be the same.  I.e., one cannot
7857:    call MatSolves(A,x,x).

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

7864:    Level: developer

7866:    Concepts: matrices^triangular solves

7868: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7869: @*/
7870: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7871: {

7877:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7878:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7879:   if (!mat->rmap->N && !mat->cmap->N) return(0);

7881:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7882:   MatCheckPreallocated(mat,1);
7883:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7884:   (*mat->ops->solves)(mat,b,x);
7885:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7886:   return(0);
7887: }

7891: /*@
7892:    MatIsSymmetric - Test whether a matrix is symmetric

7894:    Collective on Mat

7896:    Input Parameter:
7897: +  A - the matrix to test
7898: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

7900:    Output Parameters:
7901: .  flg - the result

7903:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

7905:    Level: intermediate

7907:    Concepts: matrix^symmetry

7909: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7910: @*/
7911: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7912: {


7919:   if (!A->symmetric_set) {
7920:     if (!A->ops->issymmetric) {
7921:       MatType mattype;
7922:       MatGetType(A,&mattype);
7923:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7924:     }
7925:     (*A->ops->issymmetric)(A,tol,flg);
7926:     if (!tol) {
7927:       A->symmetric_set = PETSC_TRUE;
7928:       A->symmetric     = *flg;
7929:       if (A->symmetric) {
7930:         A->structurally_symmetric_set = PETSC_TRUE;
7931:         A->structurally_symmetric     = PETSC_TRUE;
7932:       }
7933:     }
7934:   } else if (A->symmetric) {
7935:     *flg = PETSC_TRUE;
7936:   } else if (!tol) {
7937:     *flg = PETSC_FALSE;
7938:   } else {
7939:     if (!A->ops->issymmetric) {
7940:       MatType mattype;
7941:       MatGetType(A,&mattype);
7942:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7943:     }
7944:     (*A->ops->issymmetric)(A,tol,flg);
7945:   }
7946:   return(0);
7947: }

7951: /*@
7952:    MatIsHermitian - Test whether a matrix is Hermitian

7954:    Collective on Mat

7956:    Input Parameter:
7957: +  A - the matrix to test
7958: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

7960:    Output Parameters:
7961: .  flg - the result

7963:    Level: intermediate

7965:    Concepts: matrix^symmetry

7967: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7968:           MatIsSymmetricKnown(), MatIsSymmetric()
7969: @*/
7970: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7971: {


7978:   if (!A->hermitian_set) {
7979:     if (!A->ops->ishermitian) {
7980:       MatType mattype;
7981:       MatGetType(A,&mattype);
7982:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7983:     }
7984:     (*A->ops->ishermitian)(A,tol,flg);
7985:     if (!tol) {
7986:       A->hermitian_set = PETSC_TRUE;
7987:       A->hermitian     = *flg;
7988:       if (A->hermitian) {
7989:         A->structurally_symmetric_set = PETSC_TRUE;
7990:         A->structurally_symmetric     = PETSC_TRUE;
7991:       }
7992:     }
7993:   } else if (A->hermitian) {
7994:     *flg = PETSC_TRUE;
7995:   } else if (!tol) {
7996:     *flg = PETSC_FALSE;
7997:   } else {
7998:     if (!A->ops->ishermitian) {
7999:       MatType mattype;
8000:       MatGetType(A,&mattype);
8001:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8002:     }
8003:     (*A->ops->ishermitian)(A,tol,flg);
8004:   }
8005:   return(0);
8006: }

8010: /*@
8011:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

8013:    Not Collective

8015:    Input Parameter:
8016: .  A - the matrix to check

8018:    Output Parameters:
8019: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8020: -  flg - the result

8022:    Level: advanced

8024:    Concepts: matrix^symmetry

8026:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8027:          if you want it explicitly checked

8029: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8030: @*/
8031: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8032: {
8037:   if (A->symmetric_set) {
8038:     *set = PETSC_TRUE;
8039:     *flg = A->symmetric;
8040:   } else {
8041:     *set = PETSC_FALSE;
8042:   }
8043:   return(0);
8044: }

8048: /*@
8049:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8051:    Not Collective

8053:    Input Parameter:
8054: .  A - the matrix to check

8056:    Output Parameters:
8057: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8058: -  flg - the result

8060:    Level: advanced

8062:    Concepts: matrix^symmetry

8064:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8065:          if you want it explicitly checked

8067: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8068: @*/
8069: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8070: {
8075:   if (A->hermitian_set) {
8076:     *set = PETSC_TRUE;
8077:     *flg = A->hermitian;
8078:   } else {
8079:     *set = PETSC_FALSE;
8080:   }
8081:   return(0);
8082: }

8086: /*@
8087:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8089:    Collective on Mat

8091:    Input Parameter:
8092: .  A - the matrix to test

8094:    Output Parameters:
8095: .  flg - the result

8097:    Level: intermediate

8099:    Concepts: matrix^symmetry

8101: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8102: @*/
8103: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8104: {

8110:   if (!A->structurally_symmetric_set) {
8111:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8112:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);

8114:     A->structurally_symmetric_set = PETSC_TRUE;
8115:   }
8116:   *flg = A->structurally_symmetric;
8117:   return(0);
8118: }

8122: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8123: /*@
8124:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8125:        to be communicated to other processors during the MatAssemblyBegin/End() process

8127:     Not collective

8129:    Input Parameter:
8130: .   vec - the vector

8132:    Output Parameters:
8133: +   nstash   - the size of the stash
8134: .   reallocs - the number of additional mallocs incurred.
8135: .   bnstash   - the size of the block stash
8136: -   breallocs - the number of additional mallocs incurred.in the block stash

8138:    Level: advanced

8140: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()

8142: @*/
8143: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8144: {

8148:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8149:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8150:   return(0);
8151: }

8155: /*@C
8156:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8157:      parallel layout

8159:    Collective on Mat

8161:    Input Parameter:
8162: .  mat - the matrix

8164:    Output Parameter:
8165: +   right - (optional) vector that the matrix can be multiplied against
8166: -   left - (optional) vector that the matrix vector product can be stored in

8168:   Level: advanced

8170: .seealso: MatCreate()
8171: @*/
8172: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8173: {

8179:   MatCheckPreallocated(mat,1);
8180:   if (mat->ops->getvecs) {
8181:     (*mat->ops->getvecs)(mat,right,left);
8182:   } else {
8183:     PetscMPIInt size;
8184:     PetscInt rbs,cbs;
8185:     MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8186:     MatGetBlockSizes(mat,&rbs,&cbs);
8187:     if (right) {
8188:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8189:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8190:       VecSetBlockSize(*right,cbs);
8191:       VecSetType(*right,VECSTANDARD);
8192:       PetscLayoutReference(mat->cmap,&(*right)->map);
8193:     }
8194:     if (left) {
8195:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8196:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8197:       VecSetBlockSize(*left,rbs);
8198:       VecSetType(*left,VECSTANDARD);
8199:       PetscLayoutReference(mat->rmap,&(*left)->map);
8200:     }
8201:   }
8202:   return(0);
8203: }

8207: /*@C
8208:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8209:      with default values.

8211:    Not Collective

8213:    Input Parameters:
8214: .    info - the MatFactorInfo data structure


8217:    Notes: The solvers are generally used through the KSP and PC objects, for example
8218:           PCLU, PCILU, PCCHOLESKY, PCICC

8220:    Level: developer

8222: .seealso: MatFactorInfo

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

8227: @*/

8229: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8230: {

8234:   PetscMemzero(info,sizeof(MatFactorInfo));
8235:   return(0);
8236: }

8240: /*@
8241:    MatPtAP - Creates the matrix product C = P^T * A * P

8243:    Neighbor-wise Collective on Mat

8245:    Input Parameters:
8246: +  A - the matrix
8247: .  P - the projection matrix
8248: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8249: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

8251:    Output Parameters:
8252: .  C - the product matrix

8254:    Notes:
8255:    C will be created and must be destroyed by the user with MatDestroy().

8257:    This routine is currently only implemented for pairs of AIJ matrices and classes
8258:    which inherit from AIJ.

8260:    Level: intermediate

8262: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8263: @*/
8264: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8265: {
8267:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8268:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8269:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8270:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

8273:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8274:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

8278:   MatCheckPreallocated(A,1);
8279:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8280:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8283:   MatCheckPreallocated(P,2);
8284:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8285:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8287:   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);
8288:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8290:   if (scall == MAT_REUSE_MATRIX) {
8293:     if (viatranspose || viamatmatmatmult) {
8294:       Mat Pt;
8295:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8296:       if (viamatmatmatmult) {
8297:         MatMatMatMult(Pt,A,P,scall,fill,C);
8298:       } else {
8299:         Mat AP;
8300:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8301:         MatMatMult(Pt,AP,scall,fill,C);
8302:         MatDestroy(&AP);
8303:       }
8304:       MatDestroy(&Pt);
8305:     } else {
8306:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8307:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8308:       (*(*C)->ops->ptapnumeric)(A,P,*C);
8309:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8310:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8311:     }
8312:     return(0);
8313:   }

8315:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8316:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8318:   fA = A->ops->ptap;
8319:   fP = P->ops->ptap;
8320:   if (fP == fA) {
8321:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8322:     ptap = fA;
8323:   } else {
8324:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8325:     char ptapname[256];
8326:     PetscStrcpy(ptapname,"MatPtAP_");
8327:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
8328:     PetscStrcat(ptapname,"_");
8329:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
8330:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8331:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8332:     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);
8333:   }

8335:   if (viatranspose || viamatmatmatmult) {
8336:     Mat Pt;
8337:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8338:     if (viamatmatmatmult) {
8339:       MatMatMatMult(Pt,A,P,scall,fill,C);
8340:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8341:     } else {
8342:       Mat AP;
8343:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8344:       MatMatMult(Pt,AP,scall,fill,C);
8345:       MatDestroy(&AP);
8346:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8347:     }
8348:     MatDestroy(&Pt);
8349:   } else {
8350:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8351:     (*ptap)(A,P,scall,fill,C);
8352:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8353:   }
8354:   return(0);
8355: }

8359: /*@
8360:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

8362:    Neighbor-wise Collective on Mat

8364:    Input Parameters:
8365: +  A - the matrix
8366: -  P - the projection matrix

8368:    Output Parameters:
8369: .  C - the product matrix

8371:    Notes:
8372:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8373:    the user using MatDeatroy().

8375:    This routine is currently only implemented for pairs of AIJ matrices and classes
8376:    which inherit from AIJ.  C will be of type MATAIJ.

8378:    Level: intermediate

8380: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8381: @*/
8382: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8383: {

8389:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8390:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8393:   MatCheckPreallocated(P,2);
8394:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8395:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8398:   MatCheckPreallocated(C,3);
8399:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8400:   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);
8401:   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);
8402:   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);
8403:   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);
8404:   MatCheckPreallocated(A,1);

8406:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8407:   (*C->ops->ptapnumeric)(A,P,C);
8408:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8409:   return(0);
8410: }

8414: /*@
8415:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

8417:    Neighbor-wise Collective on Mat

8419:    Input Parameters:
8420: +  A - the matrix
8421: -  P - the projection matrix

8423:    Output Parameters:
8424: .  C - the (i,j) structure of the product matrix

8426:    Notes:
8427:    C will be created and must be destroyed by the user with MatDestroy().

8429:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8430:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8431:    this (i,j) structure by calling MatPtAPNumeric().

8433:    Level: intermediate

8435: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8436: @*/
8437: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8438: {

8444:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8445:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8446:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8449:   MatCheckPreallocated(P,2);
8450:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8451:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8454:   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);
8455:   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);
8456:   MatCheckPreallocated(A,1);
8457:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8458:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8459:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

8461:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8462:   return(0);
8463: }

8467: /*@
8468:    MatRARt - Creates the matrix product C = R * A * R^T

8470:    Neighbor-wise Collective on Mat

8472:    Input Parameters:
8473: +  A - the matrix
8474: .  R - the projection matrix
8475: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8476: -  fill - expected fill as ratio of nnz(C)/nnz(A)

8478:    Output Parameters:
8479: .  C - the product matrix

8481:    Notes:
8482:    C will be created and must be destroyed by the user with MatDestroy().

8484:    This routine is currently only implemented for pairs of AIJ matrices and classes
8485:    which inherit from AIJ.

8487:    Level: intermediate

8489: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8490: @*/
8491: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8492: {

8498:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8499:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8502:   MatCheckPreallocated(R,2);
8503:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8504:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8506:   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);
8507:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8508:   MatCheckPreallocated(A,1);

8510:   if (!A->ops->rart) {
8511:     MatType mattype;
8512:     MatGetType(A,&mattype);
8513:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8514:   }
8515:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
8516:   (*A->ops->rart)(A,R,scall,fill,C);
8517:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
8518:   return(0);
8519: }

8523: /*@
8524:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

8526:    Neighbor-wise Collective on Mat

8528:    Input Parameters:
8529: +  A - the matrix
8530: -  R - the projection matrix

8532:    Output Parameters:
8533: .  C - the product matrix

8535:    Notes:
8536:    C must have been created by calling MatRARtSymbolic and must be destroyed by
8537:    the user using MatDeatroy().

8539:    This routine is currently only implemented for pairs of AIJ matrices and classes
8540:    which inherit from AIJ.  C will be of type MATAIJ.

8542:    Level: intermediate

8544: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8545: @*/
8546: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8547: {

8553:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8554:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8557:   MatCheckPreallocated(R,2);
8558:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8559:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8562:   MatCheckPreallocated(C,3);
8563:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8564:   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);
8565:   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);
8566:   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);
8567:   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);
8568:   MatCheckPreallocated(A,1);

8570:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8571:   (*A->ops->rartnumeric)(A,R,C);
8572:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8573:   return(0);
8574: }

8578: /*@
8579:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

8581:    Neighbor-wise Collective on Mat

8583:    Input Parameters:
8584: +  A - the matrix
8585: -  R - the projection matrix

8587:    Output Parameters:
8588: .  C - the (i,j) structure of the product matrix

8590:    Notes:
8591:    C will be created and must be destroyed by the user with MatDestroy().

8593:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8594:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8595:    this (i,j) structure by calling MatRARtNumeric().

8597:    Level: intermediate

8599: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8600: @*/
8601: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8602: {

8608:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8609:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8610:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8613:   MatCheckPreallocated(R,2);
8614:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8615:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8618:   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);
8619:   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);
8620:   MatCheckPreallocated(A,1);
8621:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8622:   (*A->ops->rartsymbolic)(A,R,fill,C);
8623:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

8625:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
8626:   return(0);
8627: }

8631: /*@
8632:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

8634:    Neighbor-wise Collective on Mat

8636:    Input Parameters:
8637: +  A - the left matrix
8638: .  B - the right matrix
8639: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8640: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8641:           if the result is a dense matrix this is irrelevent

8643:    Output Parameters:
8644: .  C - the product matrix

8646:    Notes:
8647:    Unless scall is MAT_REUSE_MATRIX C will be created.

8649:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8651:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8652:    actually needed.

8654:    If you have many matrices with the same non-zero structure to multiply, you
8655:    should either
8656: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8657: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

8659:    Level: intermediate

8661: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8662: @*/
8663: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8664: {
8666:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8667:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8668:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

8673:   MatCheckPreallocated(A,1);
8674:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8675:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8678:   MatCheckPreallocated(B,2);
8679:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8680:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8682:   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);
8683:   if (scall == MAT_REUSE_MATRIX) {
8686:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8687:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8688:     (*(*C)->ops->matmultnumeric)(A,B,*C);
8689:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8690:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8691:     return(0);
8692:   }
8693:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8694:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8696:   fA = A->ops->matmult;
8697:   fB = B->ops->matmult;
8698:   if (fB == fA) {
8699:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8700:     mult = fB;
8701:   } else {
8702:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8703:     char multname[256];
8704:     PetscStrcpy(multname,"MatMatMult_");
8705:     PetscStrcat(multname,((PetscObject)A)->type_name);
8706:     PetscStrcat(multname,"_");
8707:     PetscStrcat(multname,((PetscObject)B)->type_name);
8708:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8709:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
8710:     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);
8711:   }
8712:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8713:   (*mult)(A,B,scall,fill,C);
8714:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8715:   return(0);
8716: }

8720: /*@
8721:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8722:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

8724:    Neighbor-wise Collective on Mat

8726:    Input Parameters:
8727: +  A - the left matrix
8728: .  B - the right matrix
8729: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8730:       if C is a dense matrix this is irrelevent

8732:    Output Parameters:
8733: .  C - the product matrix

8735:    Notes:
8736:    Unless scall is MAT_REUSE_MATRIX C will be created.

8738:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8739:    actually needed.

8741:    This routine is currently implemented for
8742:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8743:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8744:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8746:    Level: intermediate

8748:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8749:      We should incorporate them into PETSc.

8751: .seealso: MatMatMult(), MatMatMultNumeric()
8752: @*/
8753: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8754: {
8756:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
8757:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
8758:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

8763:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8764:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8768:   MatCheckPreallocated(B,2);
8769:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8770:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8773:   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);
8774:   if (fill == PETSC_DEFAULT) fill = 2.0;
8775:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8776:   MatCheckPreallocated(A,1);

8778:   Asymbolic = A->ops->matmultsymbolic;
8779:   Bsymbolic = B->ops->matmultsymbolic;
8780:   if (Asymbolic == Bsymbolic) {
8781:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8782:     symbolic = Bsymbolic;
8783:   } else { /* dispatch based on the type of A and B */
8784:     char symbolicname[256];
8785:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8786:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8787:     PetscStrcat(symbolicname,"_");
8788:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8789:     PetscStrcat(symbolicname,"_C");
8790:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
8791:     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);
8792:   }
8793:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8794:   (*symbolic)(A,B,fill,C);
8795:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8796:   return(0);
8797: }

8801: /*@
8802:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8803:    Call this routine after first calling MatMatMultSymbolic().

8805:    Neighbor-wise Collective on Mat

8807:    Input Parameters:
8808: +  A - the left matrix
8809: -  B - the right matrix

8811:    Output Parameters:
8812: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

8814:    Notes:
8815:    C must have been created with MatMatMultSymbolic().

8817:    This routine is currently implemented for
8818:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8819:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8820:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8822:    Level: intermediate

8824: .seealso: MatMatMult(), MatMatMultSymbolic()
8825: @*/
8826: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8827: {

8831:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
8832:   return(0);
8833: }

8837: /*@
8838:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

8840:    Neighbor-wise Collective on Mat

8842:    Input Parameters:
8843: +  A - the left matrix
8844: .  B - the right matrix
8845: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8846: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8848:    Output Parameters:
8849: .  C - the product matrix

8851:    Notes:
8852:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8854:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8856:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8857:    actually needed.

8859:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

8861:    Level: intermediate

8863: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8864: @*/
8865: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8866: {
8868:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8869:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

8874:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8875:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8878:   MatCheckPreallocated(B,2);
8879:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8880:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8882:   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);
8883:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8884:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8885:   MatCheckPreallocated(A,1);

8887:   fA = A->ops->mattransposemult;
8888:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8889:   fB = B->ops->mattransposemult;
8890:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8891:   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);

8893:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
8894:   if (scall == MAT_INITIAL_MATRIX) {
8895:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8896:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8897:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8898:   }
8899:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8900:   (*A->ops->mattransposemultnumeric)(A,B,*C);
8901:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8902:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
8903:   return(0);
8904: }

8908: /*@
8909:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

8911:    Neighbor-wise Collective on Mat

8913:    Input Parameters:
8914: +  A - the left matrix
8915: .  B - the right matrix
8916: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8917: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8919:    Output Parameters:
8920: .  C - the product matrix

8922:    Notes:
8923:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8925:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8927:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8928:    actually needed.

8930:    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
8931:    which inherit from SeqAIJ.  C will be of same type as the input matrices.

8933:    Level: intermediate

8935: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8936: @*/
8937: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8938: {
8940:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8941:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8942:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

8947:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8948:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8951:   MatCheckPreallocated(B,2);
8952:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8953:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8955:   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);
8956:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8957:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8958:   MatCheckPreallocated(A,1);

8960:   fA = A->ops->transposematmult;
8961:   fB = B->ops->transposematmult;
8962:   if (fB==fA) {
8963:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8964:     transposematmult = fA;
8965:   } else {
8966:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8967:     char multname[256];
8968:     PetscStrcpy(multname,"MatTransposeMatMult_");
8969:     PetscStrcat(multname,((PetscObject)A)->type_name);
8970:     PetscStrcat(multname,"_");
8971:     PetscStrcat(multname,((PetscObject)B)->type_name);
8972:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8973:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
8974:     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);
8975:   }
8976:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8977:   (*transposematmult)(A,B,scall,fill,C);
8978:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8979:   return(0);
8980: }

8984: /*@
8985:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

8987:    Neighbor-wise Collective on Mat

8989:    Input Parameters:
8990: +  A - the left matrix
8991: .  B - the middle matrix
8992: .  C - the right matrix
8993: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8994: -  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
8995:           if the result is a dense matrix this is irrelevent

8997:    Output Parameters:
8998: .  D - the product matrix

9000:    Notes:
9001:    Unless scall is MAT_REUSE_MATRIX D will be created.

9003:    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call

9005:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9006:    actually needed.

9008:    If you have many matrices with the same non-zero structure to multiply, you
9009:    should either
9010: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9011: $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed

9013:    Level: intermediate

9015: .seealso: MatMatMult, MatPtAP()
9016: @*/
9017: PetscErrorCode  MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9018: {
9020:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9021:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9022:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9023:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9028:   MatCheckPreallocated(A,1);
9029:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9030:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9033:   MatCheckPreallocated(B,2);
9034:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9035:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9038:   MatCheckPreallocated(C,3);
9039:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9040:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9041:   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);
9042:   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);
9043:   if (scall == MAT_REUSE_MATRIX) {
9046:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9047:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9048:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9049:     return(0);
9050:   }
9051:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9052:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9054:   fA = A->ops->matmatmult;
9055:   fB = B->ops->matmatmult;
9056:   fC = C->ops->matmatmult;
9057:   if (fA == fB && fA == fC) {
9058:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9059:     mult = fA;
9060:   } else {
9061:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9062:     char multname[256];
9063:     PetscStrcpy(multname,"MatMatMatMult_");
9064:     PetscStrcat(multname,((PetscObject)A)->type_name);
9065:     PetscStrcat(multname,"_");
9066:     PetscStrcat(multname,((PetscObject)B)->type_name);
9067:     PetscStrcat(multname,"_");
9068:     PetscStrcat(multname,((PetscObject)C)->type_name);
9069:     PetscStrcat(multname,"_C");
9070:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9071:     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);
9072:   }
9073:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9074:   (*mult)(A,B,C,scall,fill,D);
9075:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9076:   return(0);
9077: }

9081: /*@C
9082:    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

9084:    Collective on Mat

9086:    Input Parameters:
9087: +  mat - the matrix
9088: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9089: .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9090: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9092:    Output Parameter:
9093: .  matredundant - redundant matrix

9095:    Notes:
9096:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9097:    original matrix has not changed from that last call to MatGetRedundantMatrix().

9099:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9100:    calling it.

9102:    Only MPIAIJ matrix is supported.

9104:    Level: advanced

9106:    Concepts: subcommunicator
9107:    Concepts: duplicate matrix

9109: .seealso: MatDestroy()
9110: @*/
9111: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9112: {

9117:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9120:   }
9121:   if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9122:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9123:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9124:   MatCheckPreallocated(mat,1);

9126:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
9127:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,reuse,matredundant);
9128:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
9129:   return(0);
9130: }

9134: /*@C
9135:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9136:    a given 'mat' object. Each submatrix can span multiple procs.

9138:    Collective on Mat

9140:    Input Parameters:
9141: +  mat - the matrix
9142: .  subcomm - the subcommunicator obtained by com_split(comm)
9143: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9145:    Output Parameter:
9146: .  subMat - 'parallel submatrices each spans a given subcomm

9148:   Notes:
9149:   The submatrix partition across processors is dictated by 'subComm' a
9150:   communicator obtained by com_split(comm). The comm_split
9151:   is not restriced to be grouped with consecutive original ranks.

9153:   Due the comm_split() usage, the parallel layout of the submatrices
9154:   map directly to the layout of the original matrix [wrt the local
9155:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9156:   into the 'DiagonalMat' of the subMat, hence it is used directly from
9157:   the subMat. However the offDiagMat looses some columns - and this is
9158:   reconstructed with MatSetValues()

9160:   Level: advanced

9162:   Concepts: subcommunicator
9163:   Concepts: submatrices

9165: .seealso: MatGetSubMatrices()
9166: @*/
9167: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9168: {
9170:   PetscMPIInt    commsize,subCommSize;

9173:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9174:   MPI_Comm_size(subComm,&subCommSize);
9175:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

9177:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9178:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9179:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9180:   return(0);
9181: }

9185: /*@
9186:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

9188:    Not Collective

9190:    Input Arguments:
9191:    mat - matrix to extract local submatrix from
9192:    isrow - local row indices for submatrix
9193:    iscol - local column indices for submatrix

9195:    Output Arguments:
9196:    submat - the submatrix

9198:    Level: intermediate

9200:    Notes:
9201:    The submat should be returned with MatRestoreLocalSubMatrix().

9203:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9204:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

9206:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9207:    MatSetValuesBlockedLocal() will also be implemented.

9209: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9210: @*/
9211: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9212: {


9222:   if (mat->ops->getlocalsubmatrix) {
9223:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9224:   } else {
9225:     MatCreateLocalRef(mat,isrow,iscol,submat);
9226:   }
9227:   return(0);
9228: }

9232: /*@
9233:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

9235:    Not Collective

9237:    Input Arguments:
9238:    mat - matrix to extract local submatrix from
9239:    isrow - local row indices for submatrix
9240:    iscol - local column indices for submatrix
9241:    submat - the submatrix

9243:    Level: intermediate

9245: .seealso: MatGetLocalSubMatrix()
9246: @*/
9247: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9248: {

9257:   if (*submat) {
9259:   }

9261:   if (mat->ops->restorelocalsubmatrix) {
9262:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9263:   } else {
9264:     MatDestroy(submat);
9265:   }
9266:   *submat = NULL;
9267:   return(0);
9268: }

9270: /* --------------------------------------------------------*/
9273: /*@
9274:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

9276:    Collective on Mat

9278:    Input Parameter:
9279: .  mat - the matrix

9281:    Output Parameter:
9282: .  is - if any rows have zero diagonals this contains the list of them

9284:    Level: developer

9286:    Concepts: matrix-vector product

9288: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9289: @*/
9290: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9291: {

9297:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9298:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9300:   if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9301:   (*mat->ops->findzerodiagonals)(mat,is);
9302:   return(0);
9303: }

9307: /*@
9308:    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)

9310:    Collective on Mat

9312:    Input Parameter:
9313: .  mat - the matrix

9315:    Output Parameter:
9316: .  is - contains the list of rows with off block diagonal entries

9318:    Level: developer

9320:    Concepts: matrix-vector product

9322: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9323: @*/
9324: PetscErrorCode  MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
9325: {

9331:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9332:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9334:   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
9335:   (*mat->ops->findoffblockdiagonalentries)(mat,is);
9336:   return(0);
9337: }

9341: /*@C
9342:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

9344:   Collective on Mat

9346:   Input Parameters:
9347: . mat - the matrix

9349:   Output Parameters:
9350: . values - the block inverses in column major order (FORTRAN-like)

9352:    Note:
9353:    This routine is not available from Fortran.

9355:   Level: advanced
9356: @*/
9357: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9358: {

9363:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9364:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9365:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9366:   (*mat->ops->invertblockdiagonal)(mat,values);
9367:   return(0);
9368: }

9372: /*@C
9373:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9374:     via MatTransposeColoringCreate().

9376:     Collective on MatTransposeColoring

9378:     Input Parameter:
9379: .   c - coloring context

9381:     Level: intermediate

9383: .seealso: MatTransposeColoringCreate()
9384: @*/
9385: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9386: {
9387:   PetscErrorCode       ierr;
9388:   MatTransposeColoring matcolor=*c;

9391:   if (!matcolor) return(0);
9392:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

9394:   PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
9395:   PetscFree(matcolor->rows);
9396:   PetscFree(matcolor->den2sp);
9397:   PetscFree(matcolor->colorforcol);
9398:   PetscFree(matcolor->columns);
9399:   if (matcolor->brows>0) {
9400:     PetscFree(matcolor->lstart);
9401:   }
9402:   PetscHeaderDestroy(c);
9403:   return(0);
9404: }

9408: /*@C
9409:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9410:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9411:     MatTransposeColoring to sparse B.

9413:     Collective on MatTransposeColoring

9415:     Input Parameters:
9416: +   B - sparse matrix B
9417: .   Btdense - symbolic dense matrix B^T
9418: -   coloring - coloring context created with MatTransposeColoringCreate()

9420:     Output Parameter:
9421: .   Btdense - dense matrix B^T

9423:     Options Database Keys:
9424: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9425: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9426: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

9428:     Level: intermediate

9430: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

9432: .keywords: coloring
9433: @*/
9434: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9435: {


9443:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9444:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9445:   return(0);
9446: }

9450: /*@C
9451:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9452:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9453:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9454:     Csp from Cden.

9456:     Collective on MatTransposeColoring

9458:     Input Parameters:
9459: +   coloring - coloring context created with MatTransposeColoringCreate()
9460: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

9462:     Output Parameter:
9463: .   Csp - sparse matrix

9465:     Options Database Keys:
9466: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9467: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9468: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

9470:     Level: intermediate

9472: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

9474: .keywords: coloring
9475: @*/
9476: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9477: {


9485:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9486:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9487:   return(0);
9488: }

9492: /*@C
9493:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

9495:    Collective on Mat

9497:    Input Parameters:
9498: +  mat - the matrix product C
9499: -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()

9501:     Output Parameter:
9502: .   color - the new coloring context

9504:     Level: intermediate

9506: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9507:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9508: @*/
9509: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9510: {
9511:   MatTransposeColoring c;
9512:   MPI_Comm             comm;
9513:   PetscErrorCode       ierr;

9516:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9517:   PetscObjectGetComm((PetscObject)mat,&comm);
9518:   PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);

9520:   c->ctype = iscoloring->ctype;
9521:   if (mat->ops->transposecoloringcreate) {
9522:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9523:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

9525:   *color = c;
9526:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9527:   return(0);
9528: }

9532: /*@
9533:       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 
9534:         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 
9535:         same, otherwise it will be larger

9537:      Not Collective

9539:   Input Parameter:
9540: .    A  - the matrix

9542:   Output Parameter:
9543: .    state - the current state

9545:   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 
9546:          different matrices

9548:   Level: intermediate

9550: @*/
9551: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
9552: {
9554:   *state = mat->nonzerostate;
9555:   return(0);
9556: }