Actual source code: matrix.c

petsc-dev 2014-04-19
Report Typos and Errors
  2: /*
  3:    This is where the abstract matrix operations are defined
  4: */

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

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

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

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

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

 46:    Logically Collective on Vec

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

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

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

 63:    Level: intermediate

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

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


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

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

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


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

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

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

109:   Level: intermediate

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

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

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

130:    Not Collective

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

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

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

140:    Level: advanced

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

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

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

174:    Collective on Mat

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

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

182:    Level: advanced

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

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

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

203:    Logically Collective on Mat

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

208:    Level: advanced


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

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

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

243:    Collective on Mat

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

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

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

254:    Level: advanced

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

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


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

281:    Logically Collective on Mat

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

286:    Level: advanced


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

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

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

321:    Collective on Mat

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

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

330:    Level: advanced


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

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

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

356:    Not Collective

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

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

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

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

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

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

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

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


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

406:    Level: advanced

408:    Concepts: matrices^row access

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

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

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

436:    Logically Collective on Mat

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

441:    Level: advanced

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

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

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

476:    Not Collective

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

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

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

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

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

506:    Level: advanced

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

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

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

532:    Not Collective

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

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

540:    Level: advanced

542:    Concepts: matrices^row access

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

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

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

566:    Not Collective

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

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


575:    Level: advanced

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

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

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

597:    Logically Collective on Mat

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

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

607:    Level: advanced

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

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

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

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

629:    Logically Collective on Mat

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

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

639:    Level: advanced

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

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

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

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

661:    Not Collective

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

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

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

672:    Level: advanced

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

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

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

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

693:    Collective on Mat

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

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

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

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

705:    Level: beginner

707: .keywords: Mat, setup

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

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

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

742:    Collective on Mat

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

920:    Collective on PetscViewer

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

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

932:    Level: beginner

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1019:    Collective on Mat

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

1024:    Level: beginner

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

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

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

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

1056:    Not Collective

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

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

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

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

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

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

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

1089:    Level: beginner

1091:    Concepts: matrices^putting entries in

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

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

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

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


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

1158:    Not Collective

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

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

1168:    All the nonzeros in the row must be provided

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

1172:    The row must belong to this process

1174:    Level: intermediate

1176:    Concepts: matrices^putting entries in

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

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

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

1211:    Not Collective

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

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

1221:    All the nonzeros in the row must be provided

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

1225:    The row must belong to this process

1227:    Level: advanced

1229:    Concepts: matrices^putting entries in

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

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

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

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

1276:    Not Collective

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

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

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

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

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

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

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

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

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

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

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

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

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

1336:    Level: beginner

1338:    Concepts: matrices^putting entries in

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

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

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

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

1395:    Not Collective

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

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

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

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

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

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

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

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

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

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

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

1448:    Level: beginner

1450:    Concepts: matrices^putting entries in

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

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

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

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

1518:    Not Collective

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


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

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

1534:    Level: beginner

1536:    Concepts: matrices^putting entries in

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


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

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

1566:    Not Collective

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

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

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

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

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

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

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

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

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

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

1626:    Level: intermediate

1628:    Concepts: matrices^putting entries in blocked

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

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

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

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

1702:    Not Collective; currently only returns a local block

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

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

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

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

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

1726:    Level: advanced

1728:    Concepts: matrices^accessing values

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

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

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

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

1760:   Not Collective

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

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

1772:   Level: advanced

1774:   Concepts: matrices^putting entries in

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

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

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

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

1812:    Not Collective

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

1820:    Level: intermediate

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

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


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

1848: /*@
1849:    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1850:    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1851:    entries using a local (per-processor) numbering.

1853:    Not Collective

1855:    Input Parameters:
1856: +  x - the matrix
1857: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or
1858:              ISLocalToGlobalMappingCreateIS()
1859: - cmapping - column mapping

1861:    Level: intermediate

1863:    Concepts: matrices^local to global mapping blocked
1864:    Concepts: local to global mapping^for matrices, blocked

1866: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1867:            MatSetValuesBlocked(), MatSetValuesLocal()
1868: @*/
1869: PetscErrorCode  MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1870: {


1879:   PetscLayoutSetISLocalToGlobalMappingBlock(x->rmap,rmapping);
1880:   PetscLayoutSetISLocalToGlobalMappingBlock(x->cmap,cmapping);
1881:   return(0);
1882: }

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

1889:    Not Collective

1891:    Input Parameters:
1892: .  A - the matrix

1894:    Output Parameters:
1895: + rmapping - row mapping
1896: - cmapping - column mapping

1898:    Level: advanced

1900:    Concepts: matrices^local to global mapping
1901:    Concepts: local to global mapping^for matrices

1903: .seealso:  MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock()
1904: @*/
1905: PetscErrorCode  MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1906: {
1912:   if (rmapping) *rmapping = A->rmap->mapping;
1913:   if (cmapping) *cmapping = A->cmap->mapping;
1914:   return(0);
1915: }

1919: /*@
1920:    MatGetLocalToGlobalMappingBlock - Gets the local-to-global numbering set by MatSetLocalToGlobalMappingBlock()

1922:    Not Collective

1924:    Input Parameters:
1925: .  A - the matrix

1927:    Output Parameters:
1928: + rmapping - row mapping
1929: - cmapping - column mapping

1931:    Level: advanced

1933:    Concepts: matrices^local to global mapping blocked
1934:    Concepts: local to global mapping^for matrices, blocked

1936: .seealso:  MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping()
1937: @*/
1938: PetscErrorCode  MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1939: {
1945:   if (rmapping) *rmapping = A->rmap->bmapping;
1946:   if (cmapping) *cmapping = A->cmap->bmapping;
1947:   return(0);
1948: }

1952: /*@
1953:    MatGetLayouts - Gets the PetscLayout objects for rows and columns

1955:    Not Collective

1957:    Input Parameters:
1958: .  A - the matrix

1960:    Output Parameters:
1961: + rmap - row layout
1962: - cmap - column layout

1964:    Level: advanced

1966: .seealso:  MatGetVecs(), MatGetLocalToGlobalMapping()
1967: @*/
1968: PetscErrorCode  MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1969: {
1975:   if (rmap) *rmap = A->rmap;
1976:   if (cmap) *cmap = A->cmap;
1977:   return(0);
1978: }

1982: /*@
1983:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1984:    using a local ordering of the nodes.

1986:    Not Collective

1988:    Input Parameters:
1989: +  x - the matrix
1990: .  nrow, irow - number of rows and their local indices
1991: .  ncol, icol - number of columns and their local indices
1992: .  y -  a logically two-dimensional array of values
1993: -  addv - either INSERT_VALUES or ADD_VALUES, where
1994:    ADD_VALUES adds values to any existing entries, and
1995:    INSERT_VALUES replaces existing entries with new values

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

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

2003:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2004:    options cannot be mixed without intervening calls to the assembly
2005:    routines.

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

2010:    Level: intermediate

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

2014: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2015:            MatSetValueLocal()
2016: @*/
2017: PetscErrorCode  MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2018: {

2024:   MatCheckPreallocated(mat,1);
2025:   if (!nrow || !ncol) return(0); /* no values to insert */
2029:   if (mat->insertmode == NOT_SET_VALUES) {
2030:     mat->insertmode = addv;
2031:   }
2032: #if defined(PETSC_USE_DEBUG)
2033:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2034:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2035:   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2036: #endif

2038:   if (mat->assembled) {
2039:     mat->was_assembled = PETSC_TRUE;
2040:     mat->assembled     = PETSC_FALSE;
2041:   }
2042:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2043:   if (mat->ops->setvalueslocal) {
2044:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
2045:   } else {
2046:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2047:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2048:       irowm = buf; icolm = buf+nrow;
2049:     } else {
2050:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2051:       irowm = bufr; icolm = bufc;
2052:     }
2053:     ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
2054:     ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
2055:     MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
2056:     PetscFree2(bufr,bufc);
2057:   }
2058:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2059: #if defined(PETSC_HAVE_CUSP)
2060:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2061:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2062:   }
2063: #endif
2064: #if defined(PETSC_HAVE_VIENNACL)
2065:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2066:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2067:   }
2068: #endif
2069:   return(0);
2070: }

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

2078:    Not Collective

2080:    Input Parameters:
2081: +  x - the matrix
2082: .  nrow, irow - number of rows and their local indices
2083: .  ncol, icol - number of columns and their local indices
2084: .  y -  a logically two-dimensional array of values
2085: -  addv - either INSERT_VALUES or ADD_VALUES, where
2086:    ADD_VALUES adds values to any existing entries, and
2087:    INSERT_VALUES replaces existing entries with new values

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

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

2096:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2097:    options cannot be mixed without intervening calls to the assembly
2098:    routines.

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

2103:    Level: intermediate

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

2107: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
2108:            MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
2109: @*/
2110: PetscErrorCode  MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2111: {

2117:   MatCheckPreallocated(mat,1);
2118:   if (!nrow || !ncol) return(0); /* no values to insert */
2122:   if (mat->insertmode == NOT_SET_VALUES) {
2123:     mat->insertmode = addv;
2124:   }
2125: #if defined(PETSC_USE_DEBUG)
2126:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2127:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2128:   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);
2129: #endif

2131:   if (mat->assembled) {
2132:     mat->was_assembled = PETSC_TRUE;
2133:     mat->assembled     = PETSC_FALSE;
2134:   }
2135:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2136:   if (mat->ops->setvaluesblockedlocal) {
2137:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2138:   } else {
2139:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2140:     if (mat->rmap->bmapping && mat->cmap->bmapping) {
2141:       if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2142:         irowm = buf; icolm = buf + nrow;
2143:       } else {
2144:         PetscMalloc2(nrow,&bufr,ncol,&bufc);
2145:         irowm = bufr; icolm = bufc;
2146:       }
2147:       ISLocalToGlobalMappingApply(mat->rmap->bmapping,nrow,irow,irowm);
2148:       ISLocalToGlobalMappingApply(mat->cmap->bmapping,ncol,icol,icolm);
2149:       MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2150:       PetscFree2(bufr,bufc);
2151:     } else {
2152:       PetscInt i,j,bs,cbs;
2153:       MatGetBlockSizes(mat,&bs,&cbs);
2154:       if (nrow*bs+ncol*cbs <=(PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2155:         irowm = buf; icolm = buf + nrow;
2156:       } else {
2157:         PetscMalloc2(nrow*bs,&bufr,ncol*cbs,&bufc);
2158:         irowm = bufr; icolm = bufc;
2159:       }
2160:       for (i=0; i<nrow; i++) {
2161:         for (j=0; j<bs; j++) irowm[i*bs+j] = irow[i]*bs+j;
2162:       }
2163:       for (i=0; i<ncol; i++) {
2164:         for (j=0; j<cbs; j++) icolm[i*cbs+j] = icol[i]*cbs+j;
2165:       }
2166:       MatSetValuesLocal(mat,nrow*bs,irowm,ncol*cbs,icolm,y,addv);
2167:       PetscFree2(bufr,bufc);
2168:     }
2169:   }
2170:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2171: #if defined(PETSC_HAVE_CUSP)
2172:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2173:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2174:   }
2175: #endif
2176: #if defined(PETSC_HAVE_VIENNACL)
2177:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2178:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2179:   }
2180: #endif
2181:   return(0);
2182: }

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

2189:    Collective on Mat and Vec

2191:    Input Parameters:
2192: +  mat - the matrix
2193: -  x   - the vector to be multiplied

2195:    Output Parameters:
2196: .  y - the result

2198:    Notes:
2199:    The vectors x and y cannot be the same.  I.e., one cannot
2200:    call MatMult(A,y,y).

2202:    Level: developer

2204:    Concepts: matrix-vector product

2206: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2207: @*/
2208: PetscErrorCode  MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2209: {


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

2223:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2224:   (*mat->ops->multdiagonalblock)(mat,x,y);
2225:   PetscObjectStateIncrease((PetscObject)y);
2226:   return(0);
2227: }

2229: /* --------------------------------------------------------*/
2232: /*@
2233:    MatMult - Computes the matrix-vector product, y = Ax.

2235:    Neighbor-wise Collective on Mat and Vec

2237:    Input Parameters:
2238: +  mat - the matrix
2239: -  x   - the vector to be multiplied

2241:    Output Parameters:
2242: .  y - the result

2244:    Notes:
2245:    The vectors x and y cannot be the same.  I.e., one cannot
2246:    call MatMult(A,y,y).

2248:    Level: beginner

2250:    Concepts: matrix-vector product

2252: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2253: @*/
2254: PetscErrorCode  MatMult(Mat mat,Vec x,Vec y)
2255: {

2263:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2264:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2265:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2266: #if !defined(PETSC_HAVE_CONSTRAINTS)
2267:   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);
2268:   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);
2269:   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);
2270: #endif
2271:   VecValidValues(x,2,PETSC_TRUE);
2272:   MatCheckPreallocated(mat,1);

2274:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2275:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2276:   (*mat->ops->mult)(mat,x,y);
2277:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2278:   VecValidValues(y,3,PETSC_FALSE);
2279:   return(0);
2280: }

2284: /*@
2285:    MatMultTranspose - Computes matrix transpose times a vector.

2287:    Neighbor-wise Collective on Mat and Vec

2289:    Input Parameters:
2290: +  mat - the matrix
2291: -  x   - the vector to be multilplied

2293:    Output Parameters:
2294: .  y - the result

2296:    Notes:
2297:    The vectors x and y cannot be the same.  I.e., one cannot
2298:    call MatMultTranspose(A,y,y).

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

2303:    Level: beginner

2305:    Concepts: matrix vector product^transpose

2307: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2308: @*/
2309: PetscErrorCode  MatMultTranspose(Mat mat,Vec x,Vec y)
2310: {


2319:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2320:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2321:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2322: #if !defined(PETSC_HAVE_CONSTRAINTS)
2323:   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);
2324:   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);
2325: #endif
2326:   VecValidValues(x,2,PETSC_TRUE);
2327:   MatCheckPreallocated(mat,1);

2329:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2330:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2331:   (*mat->ops->multtranspose)(mat,x,y);
2332:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2333:   PetscObjectStateIncrease((PetscObject)y);
2334:   VecValidValues(y,3,PETSC_FALSE);
2335:   return(0);
2336: }

2340: /*@
2341:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2343:    Neighbor-wise Collective on Mat and Vec

2345:    Input Parameters:
2346: +  mat - the matrix
2347: -  x   - the vector to be multilplied

2349:    Output Parameters:
2350: .  y - the result

2352:    Notes:
2353:    The vectors x and y cannot be the same.  I.e., one cannot
2354:    call MatMultHermitianTranspose(A,y,y).

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

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

2360:    Level: beginner

2362:    Concepts: matrix vector product^transpose

2364: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2365: @*/
2366: PetscErrorCode  MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2367: {
2369:   Vec            w;


2377:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2378:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2379:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2380: #if !defined(PETSC_HAVE_CONSTRAINTS)
2381:   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);
2382:   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);
2383: #endif
2384:   MatCheckPreallocated(mat,1);

2386:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2387:   if (mat->ops->multhermitiantranspose) {
2388:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2389:   } else {
2390:     VecDuplicate(x,&w);
2391:     VecCopy(x,w);
2392:     VecConjugate(w);
2393:     MatMultTranspose(mat,w,y);
2394:     VecDestroy(&w);
2395:     VecConjugate(y);
2396:   }
2397:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2398:   PetscObjectStateIncrease((PetscObject)y);
2399:   return(0);
2400: }

2404: /*@
2405:     MatMultAdd -  Computes v3 = v2 + A * v1.

2407:     Neighbor-wise Collective on Mat and Vec

2409:     Input Parameters:
2410: +   mat - the matrix
2411: -   v1, v2 - the vectors

2413:     Output Parameters:
2414: .   v3 - the result

2416:     Notes:
2417:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2418:     call MatMultAdd(A,v1,v2,v1).

2420:     Level: beginner

2422:     Concepts: matrix vector product^addition

2424: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2425: @*/
2426: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2427: {


2437:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2438:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2439:   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);
2440:   /* 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);
2441:      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); */
2442:   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);
2443:   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);
2444:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2445:   MatCheckPreallocated(mat,1);

2447:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2448:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2449:   (*mat->ops->multadd)(mat,v1,v2,v3);
2450:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2451:   PetscObjectStateIncrease((PetscObject)v3);
2452:   return(0);
2453: }

2457: /*@
2458:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2460:    Neighbor-wise Collective on Mat and Vec

2462:    Input Parameters:
2463: +  mat - the matrix
2464: -  v1, v2 - the vectors

2466:    Output Parameters:
2467: .  v3 - the result

2469:    Notes:
2470:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2471:    call MatMultTransposeAdd(A,v1,v2,v1).

2473:    Level: beginner

2475:    Concepts: matrix vector product^transpose and addition

2477: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2478: @*/
2479: PetscErrorCode  MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2480: {


2490:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2491:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2492:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2493:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2494:   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);
2495:   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);
2496:   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);
2497:   MatCheckPreallocated(mat,1);

2499:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2500:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2501:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2502:   PetscObjectStateIncrease((PetscObject)v3);
2503:   return(0);
2504: }

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

2511:    Neighbor-wise Collective on Mat and Vec

2513:    Input Parameters:
2514: +  mat - the matrix
2515: -  v1, v2 - the vectors

2517:    Output Parameters:
2518: .  v3 - the result

2520:    Notes:
2521:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2522:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2524:    Level: beginner

2526:    Concepts: matrix vector product^transpose and addition

2528: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2529: @*/
2530: PetscErrorCode  MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2531: {


2541:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2542:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2543:   if (!mat->ops->multhermitiantransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2544:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2545:   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);
2546:   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);
2547:   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);
2548:   MatCheckPreallocated(mat,1);

2550:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2551:   (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2552:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2553:   PetscObjectStateIncrease((PetscObject)v3);
2554:   return(0);
2555: }

2559: /*@
2560:    MatMultConstrained - The inner multiplication routine for a
2561:    constrained matrix P^T A P.

2563:    Neighbor-wise Collective on Mat and Vec

2565:    Input Parameters:
2566: +  mat - the matrix
2567: -  x   - the vector to be multilplied

2569:    Output Parameters:
2570: .  y - the result

2572:    Notes:
2573:    The vectors x and y cannot be the same.  I.e., one cannot
2574:    call MatMult(A,y,y).

2576:    Level: beginner

2578: .keywords: matrix, multiply, matrix-vector product, constraint
2579: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2580: @*/
2581: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
2582: {

2589:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2590:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2591:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2592:   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);
2593:   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);
2594:   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);

2596:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2597:   (*mat->ops->multconstrained)(mat,x,y);
2598:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2599:   PetscObjectStateIncrease((PetscObject)y);
2600:   return(0);
2601: }

2605: /*@
2606:    MatMultTransposeConstrained - The inner multiplication routine for a
2607:    constrained matrix P^T A^T P.

2609:    Neighbor-wise Collective on Mat and Vec

2611:    Input Parameters:
2612: +  mat - the matrix
2613: -  x   - the vector to be multilplied

2615:    Output Parameters:
2616: .  y - the result

2618:    Notes:
2619:    The vectors x and y cannot be the same.  I.e., one cannot
2620:    call MatMult(A,y,y).

2622:    Level: beginner

2624: .keywords: matrix, multiply, matrix-vector product, constraint
2625: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2626: @*/
2627: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2628: {

2635:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2636:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2637:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2638:   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);
2639:   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);

2641:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2642:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2643:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2644:   PetscObjectStateIncrease((PetscObject)y);
2645:   return(0);
2646: }

2650: /*@C
2651:    MatGetFactorType - gets the type of factorization it is

2653:    Note Collective
2654:    as the flag

2656:    Input Parameters:
2657: .  mat - the matrix

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

2662:     Level: intermediate

2664: .seealso:    MatFactorType, MatGetFactor()
2665: @*/
2666: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
2667: {
2671:   *t = mat->factortype;
2672:   return(0);
2673: }

2675: /* ------------------------------------------------------------*/
2678: /*@C
2679:    MatGetInfo - Returns information about matrix storage (number of
2680:    nonzeros, memory, etc.).

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

2684:    Input Parameters:
2685: .  mat - the matrix

2687:    Output Parameters:
2688: +  flag - flag indicating the type of parameters to be returned
2689:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2690:    MAT_GLOBAL_SUM - sum over all processors)
2691: -  info - matrix information context

2693:    Notes:
2694:    The MatInfo context contains a variety of matrix data, including
2695:    number of nonzeros allocated and used, number of mallocs during
2696:    matrix assembly, etc.  Additional information for factored matrices
2697:    is provided (such as the fill ratio, number of mallocs during
2698:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2699:    when using the runtime options
2700: $       -info -mat_view ::ascii_info

2702:    Example for C/C++ Users:
2703:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2704:    data within the MatInfo context.  For example,
2705: .vb
2706:       MatInfo info;
2707:       Mat     A;
2708:       double  mal, nz_a, nz_u;

2710:       MatGetInfo(A,MAT_LOCAL,&info);
2711:       mal  = info.mallocs;
2712:       nz_a = info.nz_allocated;
2713: .ve

2715:    Example for Fortran Users:
2716:    Fortran users should declare info as a double precision
2717:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2718:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2719:    a complete list of parameter names.
2720: .vb
2721:       double  precision info(MAT_INFO_SIZE)
2722:       double  precision mal, nz_a
2723:       Mat     A
2724:       integer ierr

2726:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2727:       mal = info(MAT_INFO_MALLOCS)
2728:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2729: .ve

2731:     Level: intermediate

2733:     Concepts: matrices^getting information on

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

2738: .seealso: MatStashGetInfo()

2740: @*/
2741: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2742: {

2749:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2750:   MatCheckPreallocated(mat,1);
2751:   (*mat->ops->getinfo)(mat,flag,info);
2752:   return(0);
2753: }

2755: /* ----------------------------------------------------------*/

2759: /*@C
2760:    MatLUFactor - Performs in-place LU factorization of matrix.

2762:    Collective on Mat

2764:    Input Parameters:
2765: +  mat - the matrix
2766: .  row - row permutation
2767: .  col - column permutation
2768: -  info - options for factorization, includes
2769: $          fill - expected fill as ratio of original fill.
2770: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2771: $                   Run with the option -info to determine an optimal value to use

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

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

2781:    Level: developer

2783:    Concepts: matrices^LU factorization

2785: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2786:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2791: @*/
2792: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2793: {
2795:   MatFactorInfo  tinfo;

2803:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2804:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2805:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2806:   MatCheckPreallocated(mat,1);
2807:   if (!info) {
2808:     MatFactorInfoInitialize(&tinfo);
2809:     info = &tinfo;
2810:   }

2812:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2813:   (*mat->ops->lufactor)(mat,row,col,info);
2814:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2815:   PetscObjectStateIncrease((PetscObject)mat);
2816:   return(0);
2817: }

2821: /*@C
2822:    MatILUFactor - Performs in-place ILU factorization of matrix.

2824:    Collective on Mat

2826:    Input Parameters:
2827: +  mat - the matrix
2828: .  row - row permutation
2829: .  col - column permutation
2830: -  info - structure containing
2831: $      levels - number of levels of fill.
2832: $      expected fill - as ratio of original fill.
2833: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2834:                 missing diagonal entries)

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

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

2844:    Level: developer

2846:    Concepts: matrices^ILU factorization

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

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

2853: @*/
2854: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2855: {

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

2870:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2871:   (*mat->ops->ilufactor)(mat,row,col,info);
2872:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2873:   PetscObjectStateIncrease((PetscObject)mat);
2874:   return(0);
2875: }

2879: /*@C
2880:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2881:    Call this routine before calling MatLUFactorNumeric().

2883:    Collective on Mat

2885:    Input Parameters:
2886: +  fact - the factor matrix obtained with MatGetFactor()
2887: .  mat - the matrix
2888: .  row, col - row and column permutations
2889: -  info - options for factorization, includes
2890: $          fill - expected fill as ratio of original fill.
2891: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2892: $                   Run with the option -info to determine an optimal value to use


2895:    Notes:
2896:    See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
2897:    choosing the fill factor for better efficiency.

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

2903:    Level: developer

2905:    Concepts: matrices^LU symbolic factorization

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

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

2912: @*/
2913: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2914: {

2924:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2925:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2926:   if (!(fact)->ops->lufactorsymbolic) {
2927:     const MatSolverPackage spackage;
2928:     MatFactorGetSolverPackage(fact,&spackage);
2929:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2930:   }
2931:   MatCheckPreallocated(mat,2);

2933:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2934:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2935:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2936:   PetscObjectStateIncrease((PetscObject)fact);
2937:   return(0);
2938: }

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

2946:    Collective on Mat

2948:    Input Parameters:
2949: +  fact - the factor matrix obtained with MatGetFactor()
2950: .  mat - the matrix
2951: -  info - options for factorization

2953:    Notes:
2954:    See MatLUFactor() for in-place factorization.  See
2955:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

2961:    Level: developer

2963:    Concepts: matrices^LU numeric factorization

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

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

2970: @*/
2971: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2972: {

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

2983:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2984:   MatCheckPreallocated(mat,2);
2985:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2986:   (fact->ops->lufactornumeric)(fact,mat,info);
2987:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2988:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
2989:   PetscObjectStateIncrease((PetscObject)fact);
2990:   return(0);
2991: }

2995: /*@C
2996:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2997:    symmetric matrix.

2999:    Collective on Mat

3001:    Input Parameters:
3002: +  mat - the matrix
3003: .  perm - row and column permutations
3004: -  f - expected fill as ratio of original fill

3006:    Notes:
3007:    See MatLUFactor() for the nonsymmetric case.  See also
3008:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

3014:    Level: developer

3016:    Concepts: matrices^Cholesky factorization

3018: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3019:           MatGetOrdering()

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

3024: @*/
3025: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3026: {

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

3040:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3041:   (*mat->ops->choleskyfactor)(mat,perm,info);
3042:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3043:   PetscObjectStateIncrease((PetscObject)mat);
3044:   return(0);
3045: }

3049: /*@C
3050:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3051:    of a symmetric matrix.

3053:    Collective on Mat

3055:    Input Parameters:
3056: +  fact - the factor matrix obtained with MatGetFactor()
3057: .  mat - the matrix
3058: .  perm - row and column permutations
3059: -  info - options for factorization, includes
3060: $          fill - expected fill as ratio of original fill.
3061: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3062: $                   Run with the option -info to determine an optimal value to use

3064:    Notes:
3065:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3066:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

3072:    Level: developer

3074:    Concepts: matrices^Cholesky symbolic factorization

3076: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3077:           MatGetOrdering()

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

3082: @*/
3083: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3084: {

3093:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3094:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3095:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3096:   if (!(fact)->ops->choleskyfactorsymbolic) {
3097:     const MatSolverPackage spackage;
3098:     MatFactorGetSolverPackage(fact,&spackage);
3099:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3100:   }
3101:   MatCheckPreallocated(mat,2);

3103:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3104:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3105:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3106:   PetscObjectStateIncrease((PetscObject)fact);
3107:   return(0);
3108: }

3112: /*@C
3113:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3114:    of a symmetric matrix. Call this routine after first calling
3115:    MatCholeskyFactorSymbolic().

3117:    Collective on Mat

3119:    Input Parameters:
3120: +  fact - the factor matrix obtained with MatGetFactor()
3121: .  mat - the initial matrix
3122: .  info - options for factorization
3123: -  fact - the symbolic factor of mat


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

3131:    Level: developer

3133:    Concepts: matrices^Cholesky numeric factorization

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

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

3140: @*/
3141: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3142: {

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

3155:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3156:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3157:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3158:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3159:   PetscObjectStateIncrease((PetscObject)fact);
3160:   return(0);
3161: }

3163: /* ----------------------------------------------------------------*/
3166: /*@
3167:    MatSolve - Solves A x = b, given a factored matrix.

3169:    Neighbor-wise Collective on Mat and Vec

3171:    Input Parameters:
3172: +  mat - the factored matrix
3173: -  b - the right-hand-side vector

3175:    Output Parameter:
3176: .  x - the result vector

3178:    Notes:
3179:    The vectors b and x cannot be the same.  I.e., one cannot
3180:    call MatSolve(A,x,x).

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

3187:    Level: developer

3189:    Concepts: matrices^triangular solves

3191: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3192: @*/
3193: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
3194: {

3204:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3205:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3206:   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);
3207:   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);
3208:   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);
3209:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3210:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3211:   MatCheckPreallocated(mat,1);

3213:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3214:   (*mat->ops->solve)(mat,b,x);
3215:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3216:   PetscObjectStateIncrease((PetscObject)x);
3217:   return(0);
3218: }

3222: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
3223: {
3225:   Vec            b,x;
3226:   PetscInt       m,N,i;
3227:   PetscScalar    *bb,*xx;
3228:   PetscBool      flg;

3231:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3232:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3233:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3234:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3236:   MatDenseGetArray(B,&bb);
3237:   MatDenseGetArray(X,&xx);
3238:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3239:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3240:   MatGetVecs(A,&x,&b);
3241:   for (i=0; i<N; i++) {
3242:     VecPlaceArray(b,bb + i*m);
3243:     VecPlaceArray(x,xx + i*m);
3244:     MatSolve(A,b,x);
3245:     VecResetArray(x);
3246:     VecResetArray(b);
3247:   }
3248:   VecDestroy(&b);
3249:   VecDestroy(&x);
3250:   MatDenseRestoreArray(B,&bb);
3251:   MatDenseRestoreArray(X,&xx);
3252:   return(0);
3253: }

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

3260:    Neighbor-wise Collective on Mat

3262:    Input Parameters:
3263: +  mat - the factored matrix
3264: -  B - the right-hand-side matrix  (dense matrix)

3266:    Output Parameter:
3267: .  X - the result matrix (dense matrix)

3269:    Notes:
3270:    The matrices b and x cannot be the same.  I.e., one cannot
3271:    call MatMatSolve(A,x,x).

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

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

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

3284:    Level: developer

3286:    Concepts: matrices^triangular solves

3288: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3289: @*/
3290: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
3291: {

3301:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3302:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3303:   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);
3304:   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);
3305:   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);
3306:   if (!A->rmap->N && !A->cmap->N) return(0);
3307:   MatCheckPreallocated(A,1);

3309:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3310:   if (!A->ops->matsolve) {
3311:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3312:     MatMatSolve_Basic(A,B,X);
3313:   } else {
3314:     (*A->ops->matsolve)(A,B,X);
3315:   }
3316:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3317:   PetscObjectStateIncrease((PetscObject)X);
3318:   return(0);
3319: }


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

3328:    Neighbor-wise Collective on Mat and Vec

3330:    Input Parameters:
3331: +  mat - the factored matrix
3332: -  b - the right-hand-side vector

3334:    Output Parameter:
3335: .  x - the result vector

3337:    Notes:
3338:    MatSolve() should be used for most applications, as it performs
3339:    a forward solve followed by a backward solve.

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

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

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

3354:    Level: developer

3356:    Concepts: matrices^forward solves

3358: .seealso: MatSolve(), MatBackwardSolve()
3359: @*/
3360: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
3361: {

3371:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3372:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3373:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3374:   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);
3375:   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);
3376:   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);
3377:   MatCheckPreallocated(mat,1);
3378:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3379:   (*mat->ops->forwardsolve)(mat,b,x);
3380:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3381:   PetscObjectStateIncrease((PetscObject)x);
3382:   return(0);
3383: }

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

3391:    Neighbor-wise Collective on Mat and Vec

3393:    Input Parameters:
3394: +  mat - the factored matrix
3395: -  b - the right-hand-side vector

3397:    Output Parameter:
3398: .  x - the result vector

3400:    Notes:
3401:    MatSolve() should be used for most applications, as it performs
3402:    a forward solve followed by a backward solve.

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

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

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

3417:    Level: developer

3419:    Concepts: matrices^backward solves

3421: .seealso: MatSolve(), MatForwardSolve()
3422: @*/
3423: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
3424: {

3434:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3435:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3436:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3437:   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);
3438:   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);
3439:   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);
3440:   MatCheckPreallocated(mat,1);

3442:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3443:   (*mat->ops->backwardsolve)(mat,b,x);
3444:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3445:   PetscObjectStateIncrease((PetscObject)x);
3446:   return(0);
3447: }

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

3454:    Neighbor-wise Collective on Mat and Vec

3456:    Input Parameters:
3457: +  mat - the factored matrix
3458: .  b - the right-hand-side vector
3459: -  y - the vector to be added to

3461:    Output Parameter:
3462: .  x - the result vector

3464:    Notes:
3465:    The vectors b and x cannot be the same.  I.e., one cannot
3466:    call MatSolveAdd(A,x,y,x).

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

3472:    Level: developer

3474:    Concepts: matrices^triangular solves

3476: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3477: @*/
3478: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3479: {
3480:   PetscScalar    one = 1.0;
3481:   Vec            tmp;

3493:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3494:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3495:   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);
3496:   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);
3497:   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);
3498:   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);
3499:   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);
3500:   MatCheckPreallocated(mat,1);

3502:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3503:   if (mat->ops->solveadd) {
3504:     (*mat->ops->solveadd)(mat,b,y,x);
3505:   } else {
3506:     /* do the solve then the add manually */
3507:     if (x != y) {
3508:       MatSolve(mat,b,x);
3509:       VecAXPY(x,one,y);
3510:     } else {
3511:       VecDuplicate(x,&tmp);
3512:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3513:       VecCopy(x,tmp);
3514:       MatSolve(mat,b,x);
3515:       VecAXPY(x,one,tmp);
3516:       VecDestroy(&tmp);
3517:     }
3518:   }
3519:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3520:   PetscObjectStateIncrease((PetscObject)x);
3521:   return(0);
3522: }

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

3529:    Neighbor-wise Collective on Mat and Vec

3531:    Input Parameters:
3532: +  mat - the factored matrix
3533: -  b - the right-hand-side vector

3535:    Output Parameter:
3536: .  x - the result vector

3538:    Notes:
3539:    The vectors b and x cannot be the same.  I.e., one cannot
3540:    call MatSolveTranspose(A,x,x).

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

3546:    Level: developer

3548:    Concepts: matrices^triangular solves

3550: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3551: @*/
3552: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
3553: {

3563:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3564:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3565:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3566:   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);
3567:   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);
3568:   MatCheckPreallocated(mat,1);
3569:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3570:   (*mat->ops->solvetranspose)(mat,b,x);
3571:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3572:   PetscObjectStateIncrease((PetscObject)x);
3573:   return(0);
3574: }

3578: /*@
3579:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3580:                       factored matrix.

3582:    Neighbor-wise Collective on Mat and Vec

3584:    Input Parameters:
3585: +  mat - the factored matrix
3586: .  b - the right-hand-side vector
3587: -  y - the vector to be added to

3589:    Output Parameter:
3590: .  x - the result vector

3592:    Notes:
3593:    The vectors b and x cannot be the same.  I.e., one cannot
3594:    call MatSolveTransposeAdd(A,x,y,x).

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

3600:    Level: developer

3602:    Concepts: matrices^triangular solves

3604: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3605: @*/
3606: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3607: {
3608:   PetscScalar    one = 1.0;
3610:   Vec            tmp;

3621:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3622:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3623:   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);
3624:   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);
3625:   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);
3626:   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);
3627:   MatCheckPreallocated(mat,1);

3629:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3630:   if (mat->ops->solvetransposeadd) {
3631:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3632:   } else {
3633:     /* do the solve then the add manually */
3634:     if (x != y) {
3635:       MatSolveTranspose(mat,b,x);
3636:       VecAXPY(x,one,y);
3637:     } else {
3638:       VecDuplicate(x,&tmp);
3639:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3640:       VecCopy(x,tmp);
3641:       MatSolveTranspose(mat,b,x);
3642:       VecAXPY(x,one,tmp);
3643:       VecDestroy(&tmp);
3644:     }
3645:   }
3646:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3647:   PetscObjectStateIncrease((PetscObject)x);
3648:   return(0);
3649: }
3650: /* ----------------------------------------------------------------*/

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

3657:    Neighbor-wise Collective on Mat and Vec

3659:    Input Parameters:
3660: +  mat - the matrix
3661: .  b - the right hand side
3662: .  omega - the relaxation factor
3663: .  flag - flag indicating the type of SOR (see below)
3664: .  shift -  diagonal shift
3665: .  its - the number of iterations
3666: -  lits - the number of local iterations

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

3671:    SOR Flags:
3672: .     SOR_FORWARD_SWEEP - forward SOR
3673: .     SOR_BACKWARD_SWEEP - backward SOR
3674: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3675: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3676: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3677: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3678: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3679:          upper/lower triangular part of matrix to
3680:          vector (with omega)
3681: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3683:    Notes:
3684:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3685:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3686:    on each processor.

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

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

3693:    Notes for Advanced Users:
3694:    The flags are implemented as bitwise inclusive or operations.
3695:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3696:    to specify a zero initial guess for SSOR.

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

3702:    Vectors x and b CANNOT be the same

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

3706:    Level: developer

3708:    Concepts: matrices^relaxation
3709:    Concepts: matrices^SOR
3710:    Concepts: matrices^Gauss-Seidel

3712: @*/
3713: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3714: {

3724:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3725:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3726:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3727:   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);
3728:   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);
3729:   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);
3730:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3731:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3732:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3734:   MatCheckPreallocated(mat,1);
3735:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3736:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3737:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3738:   PetscObjectStateIncrease((PetscObject)x);
3739:   return(0);
3740: }

3744: /*
3745:       Default matrix copy routine.
3746: */
3747: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3748: {
3749:   PetscErrorCode    ierr;
3750:   PetscInt          i,rstart = 0,rend = 0,nz;
3751:   const PetscInt    *cwork;
3752:   const PetscScalar *vwork;

3755:   if (B->assembled) {
3756:     MatZeroEntries(B);
3757:   }
3758:   MatGetOwnershipRange(A,&rstart,&rend);
3759:   for (i=rstart; i<rend; i++) {
3760:     MatGetRow(A,i,&nz,&cwork,&vwork);
3761:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3762:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3763:   }
3764:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3765:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3766:   PetscObjectStateIncrease((PetscObject)B);
3767:   return(0);
3768: }

3772: /*@
3773:    MatCopy - Copys a matrix to another matrix.

3775:    Collective on Mat

3777:    Input Parameters:
3778: +  A - the matrix
3779: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3781:    Output Parameter:
3782: .  B - where the copy is put

3784:    Notes:
3785:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3786:    same nonzero pattern or the routine will crash.

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

3792:    Level: intermediate

3794:    Concepts: matrices^copying

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

3798: @*/
3799: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3800: {
3802:   PetscInt       i;

3810:   MatCheckPreallocated(B,2);
3811:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3812:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3813:   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);
3814:   MatCheckPreallocated(A,1);

3816:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3817:   if (A->ops->copy) {
3818:     (*A->ops->copy)(A,B,str);
3819:   } else { /* generic conversion */
3820:     MatCopy_Basic(A,B,str);
3821:   }

3823:   B->stencil.dim = A->stencil.dim;
3824:   B->stencil.noc = A->stencil.noc;
3825:   for (i=0; i<=A->stencil.dim; i++) {
3826:     B->stencil.dims[i]   = A->stencil.dims[i];
3827:     B->stencil.starts[i] = A->stencil.starts[i];
3828:   }

3830:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3831:   PetscObjectStateIncrease((PetscObject)B);
3832:   return(0);
3833: }

3837: /*@C
3838:    MatConvert - Converts a matrix to another matrix, either of the same
3839:    or different type.

3841:    Collective on Mat

3843:    Input Parameters:
3844: +  mat - the matrix
3845: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3846:    same type as the original matrix.
3847: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3848:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3849:    MAT_INITIAL_MATRIX.

3851:    Output Parameter:
3852: .  M - pointer to place new matrix

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

3859:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3860:    the MPI communicator of the generated matrix is always the same as the communicator
3861:    of the input matrix.

3863:    Level: intermediate

3865:    Concepts: matrices^converting between storage formats

3867: .seealso: MatCopy(), MatDuplicate()
3868: @*/
3869: PetscErrorCode  MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3870: {
3872:   PetscBool      sametype,issame,flg;
3873:   char           convname[256],mtype[256];
3874:   Mat            B;

3880:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3881:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3882:   MatCheckPreallocated(mat,1);
3883:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

3885:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3886:   if (flg) {
3887:     newtype = mtype;
3888:   }
3889:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3890:   PetscStrcmp(newtype,"same",&issame);
3891:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");

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

3895:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3896:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3897:   } else {
3898:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3899:     const char     *prefix[3] = {"seq","mpi",""};
3900:     PetscInt       i;
3901:     /*
3902:        Order of precedence:
3903:        1) See if a specialized converter is known to the current matrix.
3904:        2) See if a specialized converter is known to the desired matrix class.
3905:        3) See if a good general converter is registered for the desired class
3906:           (as of 6/27/03 only MATMPIADJ falls into this category).
3907:        4) See if a good general converter is known for the current matrix.
3908:        5) Use a really basic converter.
3909:     */

3911:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3912:     for (i=0; i<3; i++) {
3913:       PetscStrcpy(convname,"MatConvert_");
3914:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3915:       PetscStrcat(convname,"_");
3916:       PetscStrcat(convname,prefix[i]);
3917:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3918:       PetscStrcat(convname,"_C");
3919:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3920:       if (conv) goto foundconv;
3921:     }

3923:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3924:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
3925:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3926:     MatSetType(B,newtype);
3927:     for (i=0; i<3; i++) {
3928:       PetscStrcpy(convname,"MatConvert_");
3929:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3930:       PetscStrcat(convname,"_");
3931:       PetscStrcat(convname,prefix[i]);
3932:       PetscStrcat(convname,newtype);
3933:       PetscStrcat(convname,"_C");
3934:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3935:       if (conv) {
3936:         MatDestroy(&B);
3937:         goto foundconv;
3938:       }
3939:     }

3941:     /* 3) See if a good general converter is registered for the desired class */
3942:     conv = B->ops->convertfrom;
3943:     MatDestroy(&B);
3944:     if (conv) goto foundconv;

3946:     /* 4) See if a good general converter is known for the current matrix */
3947:     if (mat->ops->convert) {
3948:       conv = mat->ops->convert;
3949:     }
3950:     if (conv) goto foundconv;

3952:     /* 5) Use a really basic converter. */
3953:     conv = MatConvert_Basic;

3955: foundconv:
3956:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3957:     (*conv)(mat,newtype,reuse,M);
3958:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3959:   }
3960:   PetscObjectStateIncrease((PetscObject)*M);

3962:   /* Copy Mat options */
3963:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3964:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3965:   return(0);
3966: }

3970: /*@C
3971:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3973:    Not Collective

3975:    Input Parameter:
3976: .  mat - the matrix, must be a factored matrix

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

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

3985:    Level: intermediate

3987: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3988: @*/
3989: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3990: {
3991:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

3996:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3997:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
3998:   if (!conv) {
3999:     *type = MATSOLVERPETSC;
4000:   } else {
4001:     (*conv)(mat,type);
4002:   }
4003:   return(0);
4004: }

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

4011:    Collective on Mat

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

4018:    Output Parameters:
4019: .  f - the factor matrix used with MatXXFactorSymbolic() calls

4021:    Notes:
4022:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4023:      such as pastix, superlu, mumps etc.

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

4027:    Level: intermediate

4029: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4030: @*/
4031: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4032: {
4033:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4034:   char           convname[256];


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

4043:   PetscStrcpy(convname,"MatGetFactor_");
4044:   PetscStrcat(convname,type);
4045:   PetscStrcat(convname,"_C");
4046:   PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4047:   if (!conv) {
4048:     PetscBool flag;
4049:     MPI_Comm  comm;

4051:     PetscObjectGetComm((PetscObject)mat,&comm);
4052:     PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
4053:     if (flag) SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
4054:     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);
4055:   }
4056:   (*conv)(mat,ftype,f);
4057:   return(0);
4058: }

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

4065:    Not Collective

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

4072:    Output Parameter:
4073: .    flg - PETSC_TRUE if the factorization is available

4075:    Notes:
4076:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4077:      such as pastix, superlu, mumps etc.

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

4081:    Level: intermediate

4083: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4084: @*/
4085: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4086: {
4087:   PetscErrorCode ierr, (*conv)(Mat,MatFactorType,PetscBool*);
4088:   char           convname[256];


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

4097:   PetscStrcpy(convname,"MatGetFactorAvailable_");
4098:   PetscStrcat(convname,type);
4099:   PetscStrcat(convname,"_C");
4100:   PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4101:   if (!conv) {
4102:     *flg = PETSC_FALSE;
4103:   } else {
4104:     (*conv)(mat,ftype,flg);
4105:   }
4106:   return(0);
4107: }


4112: /*@
4113:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4115:    Collective on Mat

4117:    Input Parameters:
4118: +  mat - the matrix
4119: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4120:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

4122:    Output Parameter:
4123: .  M - pointer to place new matrix

4125:    Level: intermediate

4127:    Concepts: matrices^duplicating

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

4131: .seealso: MatCopy(), MatConvert()
4132: @*/
4133: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4134: {
4136:   Mat            B;
4137:   PetscInt       i;

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

4147:   *M = 0;
4148:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4149:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4150:   (*mat->ops->duplicate)(mat,op,M);
4151:   B    = *M;

4153:   B->stencil.dim = mat->stencil.dim;
4154:   B->stencil.noc = mat->stencil.noc;
4155:   for (i=0; i<=mat->stencil.dim; i++) {
4156:     B->stencil.dims[i]   = mat->stencil.dims[i];
4157:     B->stencil.starts[i] = mat->stencil.starts[i];
4158:   }

4160:   B->nooffproczerorows = mat->nooffproczerorows;
4161:   B->nooffprocentries  = mat->nooffprocentries;

4163:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4164:   PetscObjectStateIncrease((PetscObject)B);
4165:   return(0);
4166: }

4170: /*@
4171:    MatGetDiagonal - Gets the diagonal of a matrix.

4173:    Logically Collective on Mat and Vec

4175:    Input Parameters:
4176: +  mat - the matrix
4177: -  v - the vector for storing the diagonal

4179:    Output Parameter:
4180: .  v - the diagonal of the matrix

4182:    Level: intermediate

4184:    Note:
4185:    Currently only correct in parallel for square matrices.

4187:    Concepts: matrices^accessing diagonals

4189: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4190: @*/
4191: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
4192: {

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

4203:   (*mat->ops->getdiagonal)(mat,v);
4204:   PetscObjectStateIncrease((PetscObject)v);
4205:   return(0);
4206: }

4210: /*@
4211:    MatGetRowMin - Gets the minimum value (of the real part) of each
4212:         row of the matrix

4214:    Logically Collective on Mat and Vec

4216:    Input Parameters:
4217: .  mat - the matrix

4219:    Output Parameter:
4220: +  v - the vector for storing the maximums
4221: -  idx - the indices of the column found for each row (optional)

4223:    Level: intermediate

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

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

4230:    Concepts: matrices^getting row maximums

4232: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4233:           MatGetRowMax()
4234: @*/
4235: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4236: {

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

4247:   (*mat->ops->getrowmin)(mat,v,idx);
4248:   PetscObjectStateIncrease((PetscObject)v);
4249:   return(0);
4250: }

4254: /*@
4255:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4256:         row of the matrix

4258:    Logically Collective on Mat and Vec

4260:    Input Parameters:
4261: .  mat - the matrix

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

4267:    Level: intermediate

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

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

4274:    Concepts: matrices^getting row maximums

4276: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4277: @*/
4278: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4279: {

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

4291:   (*mat->ops->getrowminabs)(mat,v,idx);
4292:   PetscObjectStateIncrease((PetscObject)v);
4293:   return(0);
4294: }

4298: /*@
4299:    MatGetRowMax - Gets the maximum value (of the real part) of each
4300:         row of the matrix

4302:    Logically Collective on Mat and Vec

4304:    Input Parameters:
4305: .  mat - the matrix

4307:    Output Parameter:
4308: +  v - the vector for storing the maximums
4309: -  idx - the indices of the column found for each row (optional)

4311:    Level: intermediate

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

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

4318:    Concepts: matrices^getting row maximums

4320: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4321: @*/
4322: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4323: {

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

4334:   (*mat->ops->getrowmax)(mat,v,idx);
4335:   PetscObjectStateIncrease((PetscObject)v);
4336:   return(0);
4337: }

4341: /*@
4342:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4343:         row of the matrix

4345:    Logically Collective on Mat and Vec

4347:    Input Parameters:
4348: .  mat - the matrix

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

4354:    Level: intermediate

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

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

4361:    Concepts: matrices^getting row maximums

4363: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4364: @*/
4365: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4366: {

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

4378:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4379:   PetscObjectStateIncrease((PetscObject)v);
4380:   return(0);
4381: }

4385: /*@
4386:    MatGetRowSum - Gets the sum of each row of the matrix

4388:    Logically Collective on Mat and Vec

4390:    Input Parameters:
4391: .  mat - the matrix

4393:    Output Parameter:
4394: .  v - the vector for storing the sum of rows

4396:    Level: intermediate

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

4400:    Concepts: matrices^getting row sums

4402: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4403: @*/
4404: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4405: {
4406:   PetscInt       start = 0, end = 0, row;
4407:   PetscScalar    *array;

4414:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4415:   MatCheckPreallocated(mat,1);
4416:   MatGetOwnershipRange(mat, &start, &end);
4417:   VecGetArray(v, &array);
4418:   for (row = start; row < end; ++row) {
4419:     PetscInt          ncols, col;
4420:     const PetscInt    *cols;
4421:     const PetscScalar *vals;

4423:     array[row - start] = 0.0;

4425:     MatGetRow(mat, row, &ncols, &cols, &vals);
4426:     for (col = 0; col < ncols; col++) {
4427:       array[row - start] += vals[col];
4428:     }
4429:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4430:   }
4431:   VecRestoreArray(v, &array);
4432:   PetscObjectStateIncrease((PetscObject) v);
4433:   return(0);
4434: }

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

4441:    Collective on Mat

4443:    Input Parameter:
4444: +  mat - the matrix to transpose
4445: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4447:    Output Parameters:
4448: .  B - the transpose

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

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

4455:    Level: intermediate

4457:    Concepts: matrices^transposing

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

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

4473:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4474:   (*mat->ops->transpose)(mat,reuse,B);
4475:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4476:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4477:   return(0);
4478: }

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

4486:    Collective on Mat

4488:    Input Parameter:
4489: +  A - the matrix to test
4490: -  B - the matrix to test against, this can equal the first parameter

4492:    Output Parameters:
4493: .  flg - the result

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

4500:    Level: intermediate

4502:    Concepts: matrices^transposing, matrix^symmetry

4504: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4505: @*/
4506: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4507: {
4508:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4514:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4515:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4516:   *flg = PETSC_FALSE;
4517:   if (f && g) {
4518:     if (f == g) {
4519:       (*f)(A,B,tol,flg);
4520:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4521:   } else {
4522:     MatType mattype;
4523:     if (!f) {
4524:       MatGetType(A,&mattype);
4525:     } else {
4526:       MatGetType(B,&mattype);
4527:     }
4528:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4529:   }
4530:   return(0);
4531: }

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

4538:    Collective on Mat

4540:    Input Parameter:
4541: +  mat - the matrix to transpose and complex conjugate
4542: -  reuse - store the transpose matrix in the provided B

4544:    Output Parameters:
4545: .  B - the Hermitian

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

4550:    Level: intermediate

4552:    Concepts: matrices^transposing, complex conjugatex

4554: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4555: @*/
4556: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4557: {

4561:   MatTranspose(mat,reuse,B);
4562: #if defined(PETSC_USE_COMPLEX)
4563:   MatConjugate(*B);
4564: #endif
4565:   return(0);
4566: }

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

4573:    Collective on Mat

4575:    Input Parameter:
4576: +  A - the matrix to test
4577: -  B - the matrix to test against, this can equal the first parameter

4579:    Output Parameters:
4580: .  flg - the result

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

4587:    Level: intermediate

4589:    Concepts: matrices^transposing, matrix^symmetry

4591: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4592: @*/
4593: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4594: {
4595:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4601:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4602:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4603:   if (f && g) {
4604:     if (f==g) {
4605:       (*f)(A,B,tol,flg);
4606:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4607:   }
4608:   return(0);
4609: }

4613: /*@
4614:    MatPermute - Creates a new matrix with rows and columns permuted from the
4615:    original.

4617:    Collective on Mat

4619:    Input Parameters:
4620: +  mat - the matrix to permute
4621: .  row - row permutation, each processor supplies only the permutation for its rows
4622: -  col - column permutation, each processor supplies only the permutation for its columns

4624:    Output Parameters:
4625: .  B - the permuted matrix

4627:    Level: advanced

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

4633:    Concepts: matrices^permuting

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

4637: @*/
4638: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4639: {

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

4653:   (*mat->ops->permute)(mat,row,col,B);
4654:   PetscObjectStateIncrease((PetscObject)*B);
4655:   return(0);
4656: }

4660: /*@
4661:    MatEqual - Compares two matrices.

4663:    Collective on Mat

4665:    Input Parameters:
4666: +  A - the first matrix
4667: -  B - the second matrix

4669:    Output Parameter:
4670: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4672:    Level: intermediate

4674:    Concepts: matrices^equality between
4675: @*/
4676: PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4677: {

4687:   MatCheckPreallocated(B,2);
4688:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4689:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4690:   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);
4691:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4692:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4693:   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);
4694:   MatCheckPreallocated(A,1);

4696:   (*A->ops->equal)(A,B,flg);
4697:   return(0);
4698: }

4702: /*@
4703:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4704:    matrices that are stored as vectors.  Either of the two scaling
4705:    matrices can be NULL.

4707:    Collective on Mat

4709:    Input Parameters:
4710: +  mat - the matrix to be scaled
4711: .  l - the left scaling vector (or NULL)
4712: -  r - the right scaling vector (or NULL)

4714:    Notes:
4715:    MatDiagonalScale() computes A = LAR, where
4716:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4717:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4719:    Level: intermediate

4721:    Concepts: matrices^diagonal scaling
4722:    Concepts: diagonal scaling of matrices

4724: .seealso: MatScale()
4725: @*/
4726: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4727: {

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

4740:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4741:   (*mat->ops->diagonalscale)(mat,l,r);
4742:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4743:   PetscObjectStateIncrease((PetscObject)mat);
4744: #if defined(PETSC_HAVE_CUSP)
4745:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4746:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4747:   }
4748: #endif
4749: #if defined(PETSC_HAVE_VIENNACL)
4750:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4751:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4752:   }
4753: #endif
4754:   return(0);
4755: }

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

4762:     Logically Collective on Mat

4764:     Input Parameters:
4765: +   mat - the matrix to be scaled
4766: -   a  - the scaling value

4768:     Output Parameter:
4769: .   mat - the scaled matrix

4771:     Level: intermediate

4773:     Concepts: matrices^scaling all entries

4775: .seealso: MatDiagonalScale()
4776: @*/
4777: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4778: {

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

4790:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4791:   if (a != (PetscScalar)1.0) {
4792:     (*mat->ops->scale)(mat,a);
4793:     PetscObjectStateIncrease((PetscObject)mat);
4794:   }
4795:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4796: #if defined(PETSC_HAVE_CUSP)
4797:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4798:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4799:   }
4800: #endif
4801: #if defined(PETSC_HAVE_VIENNACL)
4802:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4803:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4804:   }
4805: #endif
4806:   return(0);
4807: }

4811: /*@
4812:    MatNorm - Calculates various norms of a matrix.

4814:    Collective on Mat

4816:    Input Parameters:
4817: +  mat - the matrix
4818: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4820:    Output Parameters:
4821: .  nrm - the resulting norm

4823:    Level: intermediate

4825:    Concepts: matrices^norm
4826:    Concepts: norm^of matrix
4827: @*/
4828: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4829: {


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

4842:   (*mat->ops->norm)(mat,type,nrm);
4843:   return(0);
4844: }

4846: /*
4847:      This variable is used to prevent counting of MatAssemblyBegin() that
4848:    are called from within a MatAssemblyEnd().
4849: */
4850: static PetscInt MatAssemblyEnd_InUse = 0;
4853: /*@
4854:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4855:    be called after completing all calls to MatSetValues().

4857:    Collective on Mat

4859:    Input Parameters:
4860: +  mat - the matrix
4861: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4863:    Notes:
4864:    MatSetValues() generally caches the values.  The matrix is ready to
4865:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4866:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4867:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4868:    using the matrix.

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

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

4878:    Level: beginner

4880:    Concepts: matrices^assembling

4882: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4883: @*/
4884: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4885: {

4891:   MatCheckPreallocated(mat,1);
4892:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4893:   if (mat->assembled) {
4894:     mat->was_assembled = PETSC_TRUE;
4895:     mat->assembled     = PETSC_FALSE;
4896:   }
4897:   if (!MatAssemblyEnd_InUse) {
4898:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4899:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
4900:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4901:   } else if (mat->ops->assemblybegin) {
4902:     (*mat->ops->assemblybegin)(mat,type);
4903:   }
4904:   return(0);
4905: }

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

4913:    Not Collective

4915:    Input Parameter:
4916: .  mat - the matrix

4918:    Output Parameter:
4919: .  assembled - PETSC_TRUE or PETSC_FALSE

4921:    Level: advanced

4923:    Concepts: matrices^assembled?

4925: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4926: @*/
4927: PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
4928: {
4933:   *assembled = mat->assembled;
4934:   return(0);
4935: }

4939: /*@
4940:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4941:    be called after MatAssemblyBegin().

4943:    Collective on Mat

4945:    Input Parameters:
4946: +  mat - the matrix
4947: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4949:    Options Database Keys:
4950: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
4951: .  -mat_view ::ascii_info_detail - Prints more detailed info
4952: .  -mat_view - Prints matrix in ASCII format
4953: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
4954: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4955: .  -display <name> - Sets display name (default is host)
4956: .  -draw_pause <sec> - Sets number of seconds to pause after display
4957: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4958: .  -viewer_socket_machine <machine>
4959: .  -viewer_socket_port <port>
4960: .  -mat_view binary - save matrix to file in binary format
4961: -  -viewer_binary_filename <name>

4963:    Notes:
4964:    MatSetValues() generally caches the values.  The matrix is ready to
4965:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4966:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4967:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4968:    using the matrix.

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

4974:    Level: beginner

4976: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4977: @*/
4978: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4979: {
4980:   PetscErrorCode  ierr;
4981:   static PetscInt inassm = 0;
4982:   PetscBool       flg    = PETSC_FALSE;


4988:   inassm++;
4989:   MatAssemblyEnd_InUse++;
4990:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4991:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4992:     if (mat->ops->assemblyend) {
4993:       (*mat->ops->assemblyend)(mat,type);
4994:     }
4995:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4996:   } else if (mat->ops->assemblyend) {
4997:     (*mat->ops->assemblyend)(mat,type);
4998:   }

5000:   /* Flush assembly is not a true assembly */
5001:   if (type != MAT_FLUSH_ASSEMBLY) {
5002:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5003:   }
5004:   mat->insertmode = NOT_SET_VALUES;
5005:   MatAssemblyEnd_InUse--;
5006:   PetscObjectStateIncrease((PetscObject)mat);
5007:   if (!mat->symmetric_eternal) {
5008:     mat->symmetric_set              = PETSC_FALSE;
5009:     mat->hermitian_set              = PETSC_FALSE;
5010:     mat->structurally_symmetric_set = PETSC_FALSE;
5011:   }
5012: #if defined(PETSC_HAVE_CUSP)
5013:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5014:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5015:   }
5016: #endif
5017: #if defined(PETSC_HAVE_VIENNACL)
5018:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5019:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5020:   }
5021: #endif
5022:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5023:     MatViewFromOptions(mat,NULL,"-mat_view");

5025:     if (mat->checksymmetryonassembly) {
5026:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5027:       if (flg) {
5028:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5029:       } else {
5030:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5031:       }
5032:     }
5033:     if (mat->nullsp && mat->checknullspaceonassembly) {
5034:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5035:     }
5036:   }
5037:   inassm--;
5038:   return(0);
5039: }

5043: /*@
5044:    MatSetOption - Sets a parameter option for a matrix. Some options
5045:    may be specific to certain storage formats.  Some options
5046:    determine how values will be inserted (or added). Sorted,
5047:    row-oriented input will generally assemble the fastest. The default
5048:    is row-oriented.

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

5052:    Input Parameters:
5053: +  mat - the matrix
5054: .  option - the option, one of those listed below (and possibly others),
5055: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5057:   Options Describing Matrix Structure:
5058: +    MAT_SPD - symmetric positive definite
5059: -    MAT_SYMMETRIC - symmetric in terms of both structure and value
5060: .    MAT_HERMITIAN - transpose is the complex conjugation
5061: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5062: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5063:                             you set to be kept with all future use of the matrix
5064:                             including after MatAssemblyBegin/End() which could
5065:                             potentially change the symmetry structure, i.e. you
5066:                             KNOW the matrix will ALWAYS have the property you set.


5069:    Options For Use with MatSetValues():
5070:    Insert a logically dense subblock, which can be
5071: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

5088:    Notes:
5089:    Some options are relevant only for particular matrix types and
5090:    are thus ignored by others.  Other options are not supported by
5091:    certain matrix types and will generate an error message if set.

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

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

5104:    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5105:    that would generate a new entry in the nonzero structure instead produces
5106:    an error. (Currently supported for AIJ and BAIJ formats only.)
5107:    This is a useful flag when using SAME_NONZERO_PATTERN in calling
5108:    KSPSetOperators() to ensure that the nonzero pattern truely does
5109:    remain unchanged. Set after the first MatAssemblyEnd()

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

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

5122:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5123:    searches during matrix assembly. When this flag is set, the hash table
5124:    is created during the first Matrix Assembly. This hash table is
5125:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5126:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5127:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5128:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5147:    Level: intermediate

5149:    Concepts: matrices^setting options

5151: .seealso:  MatOption, Mat

5153: @*/
5154: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool flg)
5155: {

5161:   if (op > 0) {
5164:   }

5166:   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);
5167:   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()");

5169:   switch (op) {
5170:   case MAT_NO_OFF_PROC_ENTRIES:
5171:     mat->nooffprocentries = flg;
5172:     return(0);
5173:     break;
5174:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5175:     mat->nooffproczerorows = flg;
5176:     return(0);
5177:     break;
5178:   case MAT_SPD:
5179:     mat->spd_set = PETSC_TRUE;
5180:     mat->spd     = flg;
5181:     if (flg) {
5182:       mat->symmetric                  = PETSC_TRUE;
5183:       mat->structurally_symmetric     = PETSC_TRUE;
5184:       mat->symmetric_set              = PETSC_TRUE;
5185:       mat->structurally_symmetric_set = PETSC_TRUE;
5186:     }
5187:     break;
5188:   case MAT_SYMMETRIC:
5189:     mat->symmetric = flg;
5190:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5191:     mat->symmetric_set              = PETSC_TRUE;
5192:     mat->structurally_symmetric_set = flg;
5193:     break;
5194:   case MAT_HERMITIAN:
5195:     mat->hermitian = flg;
5196:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5197:     mat->hermitian_set              = PETSC_TRUE;
5198:     mat->structurally_symmetric_set = flg;
5199:     break;
5200:   case MAT_STRUCTURALLY_SYMMETRIC:
5201:     mat->structurally_symmetric     = flg;
5202:     mat->structurally_symmetric_set = PETSC_TRUE;
5203:     break;
5204:   case MAT_SYMMETRY_ETERNAL:
5205:     mat->symmetric_eternal = flg;
5206:     break;
5207:   default:
5208:     break;
5209:   }
5210:   if (mat->ops->setoption) {
5211:     (*mat->ops->setoption)(mat,op,flg);
5212:   }
5213:   return(0);
5214: }

5218: /*@
5219:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5220:    this routine retains the old nonzero structure.

5222:    Logically Collective on Mat

5224:    Input Parameters:
5225: .  mat - the matrix

5227:    Level: intermediate

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

5232:    Concepts: matrices^zeroing

5234: .seealso: MatZeroRows()
5235: @*/
5236: PetscErrorCode  MatZeroEntries(Mat mat)
5237: {

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

5248:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5249:   (*mat->ops->zeroentries)(mat);
5250:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5251:   PetscObjectStateIncrease((PetscObject)mat);
5252: #if defined(PETSC_HAVE_CUSP)
5253:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5254:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5255:   }
5256: #endif
5257: #if defined(PETSC_HAVE_VIENNACL)
5258:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5259:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5260:   }
5261: #endif
5262:   return(0);
5263: }

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

5271:    Collective on Mat

5273:    Input Parameters:
5274: +  mat - the matrix
5275: .  numRows - the number of rows to remove
5276: .  rows - the global row indices
5277: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5278: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5279: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5298:    Level: intermediate

5300:    Concepts: matrices^zeroing rows

5302: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5303: @*/
5304: PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5305: {

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

5317:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5318:   MatViewFromOptions(mat,NULL,"-mat_view");
5319:   PetscObjectStateIncrease((PetscObject)mat);
5320: #if defined(PETSC_HAVE_CUSP)
5321:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5322:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5323:   }
5324: #endif
5325: #if defined(PETSC_HAVE_VIENNACL)
5326:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5327:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5328:   }
5329: #endif
5330:   return(0);
5331: }

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

5339:    Collective on Mat

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

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

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

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

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

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

5365:    Level: intermediate

5367:    Concepts: matrices^zeroing rows

5369: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5370: @*/
5371: PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5372: {
5374:   PetscInt       numRows;
5375:   const PetscInt *rows;

5382:   ISGetLocalSize(is,&numRows);
5383:   ISGetIndices(is,&rows);
5384:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5385:   ISRestoreIndices(is,&rows);
5386:   return(0);
5387: }

5391: /*@C
5392:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5393:    of a set of rows of a matrix.

5395:    Collective on Mat

5397:    Input Parameters:
5398: +  mat - the matrix
5399: .  numRows - the number of rows to remove
5400: .  rows - the global row indices
5401: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5402: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5403: -  b - optional vector of right hand side, that will be adjusted by provided solution

5405:    Notes:
5406:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5407:    but does not release memory.  For the dense and block diagonal
5408:    formats this does not alter the nonzero structure.

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

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

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

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

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

5429:    Level: intermediate

5431:    Concepts: matrices^zeroing rows

5433: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5434: @*/
5435: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5436: {

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

5448:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5449:   MatViewFromOptions(mat,NULL,"-mat_view");
5450:   PetscObjectStateIncrease((PetscObject)mat);
5451: #if defined(PETSC_HAVE_CUSP)
5452:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5453:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5454:   }
5455: #endif
5456: #if defined(PETSC_HAVE_VIENNACL)
5457:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5458:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5459:   }
5460: #endif
5461:   return(0);
5462: }

5466: /*@C
5467:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5468:    of a set of rows of a matrix.

5470:    Collective on Mat

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

5479:    Notes:
5480:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5481:    but does not release memory.  For the dense and block diagonal
5482:    formats this does not alter the nonzero structure.

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

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

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

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

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

5503:    Level: intermediate

5505:    Concepts: matrices^zeroing rows

5507: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5508: @*/
5509: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5510: {
5511:   PetscInt       numRows;
5512:   const PetscInt *rows;

5519:   ISGetLocalSize(is,&numRows);
5520:   ISGetIndices(is,&rows);
5521:   MatZeroRows(mat,numRows,rows,diag,x,b);
5522:   ISRestoreIndices(is,&rows);
5523:   return(0);
5524: }

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

5532:    Collective on Mat

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

5542:    Notes:
5543:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5544:    but does not release memory.  For the dense and block diagonal
5545:    formats this does not alter the nonzero structure.

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

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

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

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

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

5565:    In Fortran idxm and idxn should be declared as
5566: $     MatStencil idxm(4,m)
5567:    and the values inserted using
5568: $    idxm(MatStencil_i,1) = i
5569: $    idxm(MatStencil_j,1) = j
5570: $    idxm(MatStencil_k,1) = k
5571: $    idxm(MatStencil_c,1) = c
5572:    etc

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

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

5582:    Level: intermediate

5584:    Concepts: matrices^zeroing rows

5586: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5587: @*/
5588: PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5589: {
5590:   PetscInt       dim     = mat->stencil.dim;
5591:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5592:   PetscInt       *dims   = mat->stencil.dims+1;
5593:   PetscInt       *starts = mat->stencil.starts;
5594:   PetscInt       *dxm    = (PetscInt*) rows;
5595:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


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

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

5634:    Collective on Mat

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

5644:    Notes:
5645:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5646:    but does not release memory.  For the dense and block diagonal
5647:    formats this does not alter the nonzero structure.

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

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

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

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

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

5667:    In Fortran idxm and idxn should be declared as
5668: $     MatStencil idxm(4,m)
5669:    and the values inserted using
5670: $    idxm(MatStencil_i,1) = i
5671: $    idxm(MatStencil_j,1) = j
5672: $    idxm(MatStencil_k,1) = k
5673: $    idxm(MatStencil_c,1) = c
5674:    etc

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

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

5684:    Level: intermediate

5686:    Concepts: matrices^zeroing rows

5688: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5689: @*/
5690: PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5691: {
5692:   PetscInt       dim     = mat->stencil.dim;
5693:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5694:   PetscInt       *dims   = mat->stencil.dims+1;
5695:   PetscInt       *starts = mat->stencil.starts;
5696:   PetscInt       *dxm    = (PetscInt*) rows;
5697:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5705:   PetscMalloc1(numRows, &jdxm);
5706:   for (i = 0; i < numRows; ++i) {
5707:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5708:     for (j = 0; j < 3-sdim; ++j) dxm++;
5709:     /* Local index in X dir */
5710:     tmp = *dxm++ - starts[0];
5711:     /* Loop over remaining dimensions */
5712:     for (j = 0; j < dim-1; ++j) {
5713:       /* If nonlocal, set index to be negative */
5714:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5715:       /* Update local index */
5716:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5717:     }
5718:     /* Skip component slot if necessary */
5719:     if (mat->stencil.noc) dxm++;
5720:     /* Local row number */
5721:     if (tmp >= 0) {
5722:       jdxm[numNewRows++] = tmp;
5723:     }
5724:   }
5725:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5726:   PetscFree(jdxm);
5727:   return(0);
5728: }

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

5736:    Collective on Mat

5738:    Input Parameters:
5739: +  mat - the matrix
5740: .  numRows - the number of rows to remove
5741: .  rows - the global row indices
5742: .  diag - value put in all diagonals of eliminated rows
5743: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5744: -  b - optional vector of right hand side, that will be adjusted by provided solution

5746:    Notes:
5747:    Before calling MatZeroRowsLocal(), the user must first set the
5748:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5750:    For the AIJ matrix formats this removes the old nonzero structure,
5751:    but does not release memory.  For the dense and block diagonal
5752:    formats this does not alter the nonzero structure.

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

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

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

5765:    Level: intermediate

5767:    Concepts: matrices^zeroing

5769: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5770: @*/
5771: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5772: {
5774:   PetscMPIInt    size;

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

5784:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
5785:   if (mat->ops->zerorowslocal) {
5786:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5787:   } else if (size == 1) {
5788:     (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5789:   } else {
5790:     IS             is, newis;
5791:     const PetscInt *newRows;

5793:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5794:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5795:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5796:     ISGetIndices(newis,&newRows);
5797:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5798:     ISRestoreIndices(newis,&newRows);
5799:     ISDestroy(&newis);
5800:     ISDestroy(&is);
5801:   }
5802:   PetscObjectStateIncrease((PetscObject)mat);
5803: #if defined(PETSC_HAVE_CUSP)
5804:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5805:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5806:   }
5807: #endif
5808: #if defined(PETSC_HAVE_VIENNACL)
5809:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5810:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5811:   }
5812: #endif
5813:   return(0);
5814: }

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

5822:    Collective on Mat

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

5831:    Notes:
5832:    Before calling MatZeroRowsLocalIS(), the user must first set the
5833:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5835:    For the AIJ matrix formats this removes the old nonzero structure,
5836:    but does not release memory.  For the dense and block diagonal
5837:    formats this does not alter the nonzero structure.

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

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

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

5850:    Level: intermediate

5852:    Concepts: matrices^zeroing

5854: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5855: @*/
5856: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5857: {
5859:   PetscInt       numRows;
5860:   const PetscInt *rows;

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

5870:   ISGetLocalSize(is,&numRows);
5871:   ISGetIndices(is,&rows);
5872:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5873:   ISRestoreIndices(is,&rows);
5874:   return(0);
5875: }

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

5883:    Collective on Mat

5885:    Input Parameters:
5886: +  mat - the matrix
5887: .  numRows - the number of rows to remove
5888: .  rows - the global row indices
5889: .  diag - value put in all diagonals of eliminated rows
5890: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5891: -  b - optional vector of right hand side, that will be adjusted by provided solution

5893:    Notes:
5894:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5895:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5901:    Level: intermediate

5903:    Concepts: matrices^zeroing

5905: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5906: @*/
5907: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5908: {
5910:   PetscMPIInt    size;

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

5920:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
5921:   if (size == 1) {
5922:     (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5923:   } else {
5924:     IS             is, newis;
5925:     const PetscInt *newRows;

5927:     if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5928:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5929:     ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5930:     ISGetIndices(newis,&newRows);
5931:     (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5932:     ISRestoreIndices(newis,&newRows);
5933:     ISDestroy(&newis);
5934:     ISDestroy(&is);
5935:   }
5936:   PetscObjectStateIncrease((PetscObject)mat);
5937: #if defined(PETSC_HAVE_CUSP)
5938:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5939:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5940:   }
5941: #endif
5942: #if defined(PETSC_HAVE_VIENNACL)
5943:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5944:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5945:   }
5946: #endif
5947:   return(0);
5948: }

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

5956:    Collective on Mat

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

5965:    Notes:
5966:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5967:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5973:    Level: intermediate

5975:    Concepts: matrices^zeroing

5977: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5978: @*/
5979: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5980: {
5982:   PetscInt       numRows;
5983:   const PetscInt *rows;

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

5993:   ISGetLocalSize(is,&numRows);
5994:   ISGetIndices(is,&rows);
5995:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5996:   ISRestoreIndices(is,&rows);
5997:   return(0);
5998: }

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

6005:    Not Collective

6007:    Input Parameter:
6008: .  mat - the matrix

6010:    Output Parameters:
6011: +  m - the number of global rows
6012: -  n - the number of global columns

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

6016:    Level: beginner

6018:    Concepts: matrices^size

6020: .seealso: MatGetLocalSize()
6021: @*/
6022: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6023: {
6026:   if (m) *m = mat->rmap->N;
6027:   if (n) *n = mat->cmap->N;
6028:   return(0);
6029: }

6033: /*@
6034:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6035:    stored locally.  This information may be implementation dependent, so
6036:    use with care.

6038:    Not Collective

6040:    Input Parameters:
6041: .  mat - the matrix

6043:    Output Parameters:
6044: +  m - the number of local rows
6045: -  n - the number of local columns

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

6049:    Level: beginner

6051:    Concepts: matrices^local size

6053: .seealso: MatGetSize()
6054: @*/
6055: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6056: {
6061:   if (m) *m = mat->rmap->n;
6062:   if (n) *n = mat->cmap->n;
6063:   return(0);
6064: }

6068: /*@
6069:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6070:    this processor. (The columns of the "diagonal block")

6072:    Not Collective, unless matrix has not been allocated, then collective on Mat

6074:    Input Parameters:
6075: .  mat - the matrix

6077:    Output Parameters:
6078: +  m - the global index of the first local column
6079: -  n - one more than the global index of the last local column

6081:    Notes: both output parameters can be NULL on input.

6083:    Level: developer

6085:    Concepts: matrices^column ownership

6087: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

6089: @*/
6090: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6091: {
6097:   MatCheckPreallocated(mat,1);
6098:   if (m) *m = mat->cmap->rstart;
6099:   if (n) *n = mat->cmap->rend;
6100:   return(0);
6101: }

6105: /*@
6106:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6107:    this processor, assuming that the matrix is laid out with the first
6108:    n1 rows on the first processor, the next n2 rows on the second, etc.
6109:    For certain parallel layouts this range may not be well defined.

6111:    Not Collective

6113:    Input Parameters:
6114: .  mat - the matrix

6116:    Output Parameters:
6117: +  m - the global index of the first local row
6118: -  n - one more than the global index of the last local row

6120:    Note: Both output parameters can be NULL on input.
6121: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6122: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6123: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

6125:    Level: beginner

6127:    Concepts: matrices^row ownership

6129: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

6131: @*/
6132: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6133: {
6139:   MatCheckPreallocated(mat,1);
6140:   if (m) *m = mat->rmap->rstart;
6141:   if (n) *n = mat->rmap->rend;
6142:   return(0);
6143: }

6147: /*@C
6148:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6149:    each process

6151:    Not Collective, unless matrix has not been allocated, then collective on Mat

6153:    Input Parameters:
6154: .  mat - the matrix

6156:    Output Parameters:
6157: .  ranges - start of each processors portion plus one more then the total length at the end

6159:    Level: beginner

6161:    Concepts: matrices^row ownership

6163: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6165: @*/
6166: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6167: {

6173:   MatCheckPreallocated(mat,1);
6174:   PetscLayoutGetRanges(mat->rmap,ranges);
6175:   return(0);
6176: }

6180: /*@C
6181:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6182:    this processor. (The columns of the "diagonal blocks" for each process)

6184:    Not Collective, unless matrix has not been allocated, then collective on Mat

6186:    Input Parameters:
6187: .  mat - the matrix

6189:    Output Parameters:
6190: .  ranges - start of each processors portion plus one more then the total length at the end

6192:    Level: beginner

6194:    Concepts: matrices^column ownership

6196: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6198: @*/
6199: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6200: {

6206:   MatCheckPreallocated(mat,1);
6207:   PetscLayoutGetRanges(mat->cmap,ranges);
6208:   return(0);
6209: }

6213: /*@C
6214:    MatGetOwnershipIS - Get row and column ownership as index sets

6216:    Not Collective

6218:    Input Arguments:
6219: .  A - matrix of type Elemental

6221:    Output Arguments:
6222: +  rows - rows in which this process owns elements
6223: .  cols - columns in which this process owns elements

6225:    Level: intermediate

6227: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6228: @*/
6229: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6230: {
6231:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6234:   MatCheckPreallocated(A,1);
6235:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6236:   if (f) {
6237:     (*f)(A,rows,cols);
6238:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6239:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6240:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6241:   }
6242:   return(0);
6243: }

6247: /*@C
6248:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6249:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6250:    to complete the factorization.

6252:    Collective on Mat

6254:    Input Parameters:
6255: +  mat - the matrix
6256: .  row - row permutation
6257: .  column - column permutation
6258: -  info - structure containing
6259: $      levels - number of levels of fill.
6260: $      expected fill - as ratio of original fill.
6261: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6262:                 missing diagonal entries)

6264:    Output Parameters:
6265: .  fact - new matrix that has been symbolically factored

6267:    Notes:
6268:    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
6269:    choosing the fill factor for better efficiency.

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

6275:    Level: developer

6277:   Concepts: matrices^symbolic LU factorization
6278:   Concepts: matrices^factorization
6279:   Concepts: LU^symbolic factorization

6281: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6282:           MatGetOrdering(), MatFactorInfo

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

6287: @*/
6288: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6289: {

6299:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6300:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6301:   if (!(fact)->ops->ilufactorsymbolic) {
6302:     const MatSolverPackage spackage;
6303:     MatFactorGetSolverPackage(fact,&spackage);
6304:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6305:   }
6306:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6307:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6308:   MatCheckPreallocated(mat,2);

6310:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6311:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6312:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6313:   return(0);
6314: }

6318: /*@C
6319:    MatICCFactorSymbolic - Performs symbolic incomplete
6320:    Cholesky factorization for a symmetric matrix.  Use
6321:    MatCholeskyFactorNumeric() to complete the factorization.

6323:    Collective on Mat

6325:    Input Parameters:
6326: +  mat - the matrix
6327: .  perm - row and column permutation
6328: -  info - structure containing
6329: $      levels - number of levels of fill.
6330: $      expected fill - as ratio of original fill.

6332:    Output Parameter:
6333: .  fact - the factored matrix

6335:    Notes:
6336:    Most users should employ the KSP interface for linear solvers
6337:    instead of working directly with matrix algebra routines such as this.
6338:    See, e.g., KSPCreate().

6340:    Level: developer

6342:   Concepts: matrices^symbolic incomplete Cholesky factorization
6343:   Concepts: matrices^factorization
6344:   Concepts: Cholsky^symbolic factorization

6346: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

6351: @*/
6352: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6353: {

6362:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6363:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6364:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6365:   if (!(fact)->ops->iccfactorsymbolic) {
6366:     const MatSolverPackage spackage;
6367:     MatFactorGetSolverPackage(fact,&spackage);
6368:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6369:   }
6370:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6371:   MatCheckPreallocated(mat,2);

6373:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6374:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6375:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6376:   return(0);
6377: }

6381: /*@C
6382:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6383:    points to an array of valid matrices, they may be reused to store the new
6384:    submatrices.

6386:    Collective on Mat

6388:    Input Parameters:
6389: +  mat - the matrix
6390: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6391: .  irow, icol - index sets of rows and columns to extract (must be sorted)
6392: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6394:    Output Parameter:
6395: .  submat - the array of submatrices

6397:    Notes:
6398:    MatGetSubMatrices() can extract ONLY sequential submatrices
6399:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6400:    to extract a parallel submatrix.

6402:    Currently both row and column indices must be sorted to guarantee
6403:    correctness with all matrix types.

6405:    When extracting submatrices from a parallel matrix, each processor can
6406:    form a different submatrix by setting the rows and columns of its
6407:    individual index sets according to the local submatrix desired.

6409:    When finished using the submatrices, the user should destroy
6410:    them with MatDestroyMatrices().

6412:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6413:    original matrix has not changed from that last call to MatGetSubMatrices().

6415:    This routine creates the matrices in submat; you should NOT create them before
6416:    calling it. It also allocates the array of matrix pointers submat.

6418:    For BAIJ matrices the index sets must respect the block structure, that is if they
6419:    request one row/column in a block, they must request all rows/columns that are in
6420:    that block. For example, if the block size is 2 you cannot request just row 0 and
6421:    column 0.

6423:    Fortran Note:
6424:    The Fortran interface is slightly different from that given below; it
6425:    requires one to pass in  as submat a Mat (integer) array of size at least m.

6427:    Level: advanced

6429:    Concepts: matrices^accessing submatrices
6430:    Concepts: submatrices

6432: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6433: @*/
6434: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6435: {
6437:   PetscInt       i;
6438:   PetscBool      eq;

6443:   if (n) {
6448:   }
6450:   if (n && scall == MAT_REUSE_MATRIX) {
6453:   }
6454:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6455:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6456:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6457:   MatCheckPreallocated(mat,1);

6459:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6460:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6461:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6462:   for (i=0; i<n; i++) {
6463:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6464:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6465:       ISEqual(irow[i],icol[i],&eq);
6466:       if (eq) {
6467:         if (mat->symmetric) {
6468:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6469:         } else if (mat->hermitian) {
6470:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6471:         } else if (mat->structurally_symmetric) {
6472:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6473:         }
6474:       }
6475:     }
6476:   }
6477:   return(0);
6478: }

6482: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6483: {
6485:   PetscInt       i;
6486:   PetscBool      eq;

6491:   if (n) {
6496:   }
6498:   if (n && scall == MAT_REUSE_MATRIX) {
6501:   }
6502:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6503:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6504:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6505:   MatCheckPreallocated(mat,1);

6507:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6508:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6509:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6510:   for (i=0; i<n; i++) {
6511:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6512:       ISEqual(irow[i],icol[i],&eq);
6513:       if (eq) {
6514:         if (mat->symmetric) {
6515:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6516:         } else if (mat->hermitian) {
6517:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6518:         } else if (mat->structurally_symmetric) {
6519:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6520:         }
6521:       }
6522:     }
6523:   }
6524:   return(0);
6525: }

6529: /*@C
6530:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().

6532:    Collective on Mat

6534:    Input Parameters:
6535: +  n - the number of local matrices
6536: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6537:                        sequence of MatGetSubMatrices())

6539:    Level: advanced

6541:     Notes: Frees not only the matrices, but also the array that contains the matrices
6542:            In Fortran will not free the array.

6544: .seealso: MatGetSubMatrices()
6545: @*/
6546: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6547: {
6549:   PetscInt       i;

6552:   if (!*mat) return(0);
6553:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6555:   for (i=0; i<n; i++) {
6556:     MatDestroy(&(*mat)[i]);
6557:   }
6558:   /* memory is allocated even if n = 0 */
6559:   PetscFree(*mat);
6560:   *mat = NULL;
6561:   return(0);
6562: }

6566: /*@C
6567:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.

6569:    Collective on Mat

6571:    Input Parameters:
6572: .  mat - the matrix

6574:    Output Parameter:
6575: .  matstruct - the sequential matrix with the nonzero structure of mat

6577:   Level: intermediate

6579: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6580: @*/
6581: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6582: {


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

6593:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6594:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6595:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6596:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6597:   return(0);
6598: }

6602: /*@C
6603:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6605:    Collective on Mat

6607:    Input Parameters:
6608: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6609:                        sequence of MatGetSequentialNonzeroStructure())

6611:    Level: advanced

6613:     Notes: Frees not only the matrices, but also the array that contains the matrices

6615: .seealso: MatGetSeqNonzeroStructure()
6616: @*/
6617: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6618: {

6623:   MatDestroy(mat);
6624:   return(0);
6625: }

6629: /*@
6630:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6631:    replaces the index sets by larger ones that represent submatrices with
6632:    additional overlap.

6634:    Collective on Mat

6636:    Input Parameters:
6637: +  mat - the matrix
6638: .  n   - the number of index sets
6639: .  is  - the array of index sets (these index sets will changed during the call)
6640: -  ov  - the additional overlap requested

6642:    Level: developer

6644:    Concepts: overlap
6645:    Concepts: ASM^computing overlap

6647: .seealso: MatGetSubMatrices()
6648: @*/
6649: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6650: {

6656:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6657:   if (n) {
6660:   }
6661:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6662:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6663:   MatCheckPreallocated(mat,1);

6665:   if (!ov) return(0);
6666:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6667:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6668:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6669:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6670:   return(0);
6671: }

6675: /*@
6676:    MatGetBlockSize - Returns the matrix block size; useful especially for the
6677:    block row and block diagonal formats.

6679:    Not Collective

6681:    Input Parameter:
6682: .  mat - the matrix

6684:    Output Parameter:
6685: .  bs - block size

6687:    Notes:
6688:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ.

6690:    If the block size has not been set yet this routine returns -1.

6692:    Level: intermediate

6694:    Concepts: matrices^block size

6696: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6697: @*/
6698: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6699: {
6703:   *bs = PetscAbs(mat->rmap->bs);
6704:   return(0);
6705: }

6709: /*@
6710:    MatGetBlockSizes - Returns the matrix block row and column sizes;
6711:    useful especially for the block row and block diagonal formats.

6713:    Not Collective

6715:    Input Parameter:
6716: .  mat - the matrix

6718:    Output Parameter:
6719: .  rbs - row block size
6720: .  cbs - coumn block size

6722:    Notes:
6723:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ.

6725:    If a block size has not been set yet this routine returns -1.

6727:    Level: intermediate

6729:    Concepts: matrices^block size

6731: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6732: @*/
6733: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6734: {
6739:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
6740:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
6741:   return(0);
6742: }

6746: /*@
6747:    MatSetBlockSize - Sets the matrix block size.

6749:    Logically Collective on Mat

6751:    Input Parameters:
6752: +  mat - the matrix
6753: -  bs - block size

6755:    Notes:
6756:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6758:    Level: intermediate

6760:    Concepts: matrices^block size

6762: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6763: @*/
6764: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6765: {

6771:   PetscLayoutSetBlockSize(mat->rmap,bs);
6772:   PetscLayoutSetBlockSize(mat->cmap,bs);
6773:   return(0);
6774: }

6778: /*@
6779:    MatSetBlockSizes - Sets the matrix block row and column sizes.

6781:    Logically Collective on Mat

6783:    Input Parameters:
6784: +  mat - the matrix
6785: -  rbs - row block size
6786: -  cbs - column block size

6788:    Notes:
6789:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6791:    Level: intermediate

6793:    Concepts: matrices^block size

6795: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6796: @*/
6797: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6798: {

6805:   PetscLayoutSetBlockSize(mat->rmap,rbs);
6806:   PetscLayoutSetBlockSize(mat->cmap,cbs);
6807:   return(0);
6808: }

6812: /*@
6813:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

6815:    Logically Collective on Mat

6817:    Input Parameters:
6818: +  mat - the matrix
6819: .  fromRow - matrix from which to copy row block size
6820: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

6822:    Level: developer

6824:    Concepts: matrices^block size

6826: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
6827: @*/
6828: PetscErrorCode  MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
6829: {

6836:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
6837:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
6838:   return(0);
6839: }

6843: /*@
6844:    MatResidual - Default routine to calculate the residual.

6846:    Collective on Mat and Vec

6848:    Input Parameters:
6849: +  mat - the matrix
6850: .  b   - the right-hand-side
6851: -  x   - the approximate solution

6853:    Output Parameter:
6854: .  r - location to store the residual

6856:    Level: developer

6858: .keywords: MG, default, multigrid, residual

6860: .seealso: PCMGSetResidual()
6861: @*/
6862: PetscErrorCode  MatResidual(Mat mat,Vec b,Vec x,Vec r)
6863: {

6872:   MatCheckPreallocated(mat,1);
6873:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
6874:   if (!mat->ops->residual) {
6875:     MatMult(mat,x,r);
6876:     VecAYPX(r,-1.0,b);
6877:   } else {
6878:     (*mat->ops->residual)(mat,b,x,r);
6879:   }
6880:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
6881:   return(0);
6882: }

6886: /*@C
6887:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.

6889:    Collective on Mat

6891:     Input Parameters:
6892: +   mat - the matrix
6893: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6894: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6895: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6896:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6897:                  always used.

6899:     Output Parameters:
6900: +   n - number of rows in the (possibly compressed) matrix
6901: .   ia - the row pointers [of length n+1]
6902: .   ja - the column indices
6903: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6904:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

6906:     Level: developer

6908:     Notes: You CANNOT change any of the ia[] or ja[] values.

6910:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

6912:     Fortran Node

6914:            In Fortran use
6915: $           PetscInt ia(1), ja(1)
6916: $           PetscOffset iia, jja
6917: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6918: $
6919: $          or
6920: $
6921: $           PetscScalar, pointer :: xx_v(:)
6922: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)


6925:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

6927: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6928: @*/
6929: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6930: {

6940:   MatCheckPreallocated(mat,1);
6941:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6942:   else {
6943:     *done = PETSC_TRUE;
6944:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6945:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6946:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6947:   }
6948:   return(0);
6949: }

6953: /*@C
6954:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.

6956:     Collective on Mat

6958:     Input Parameters:
6959: +   mat - the matrix
6960: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6961: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6962:                 symmetrized
6963: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6964:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6965:                  always used.
6966: .   n - number of columns in the (possibly compressed) matrix
6967: .   ia - the column pointers
6968: -   ja - the row indices

6970:     Output Parameters:
6971: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6973:     Note:
6974:     This routine zeros out n, ia, and ja. This is to prevent accidental
6975:     us of the array after it has been restored. If you pass NULL, it will
6976:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

6978:     Level: developer

6980: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6981: @*/
6982: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6983: {

6993:   MatCheckPreallocated(mat,1);
6994:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6995:   else {
6996:     *done = PETSC_TRUE;
6997:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6998:   }
6999:   return(0);
7000: }

7004: /*@C
7005:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7006:     MatGetRowIJ().

7008:     Collective on Mat

7010:     Input Parameters:
7011: +   mat - the matrix
7012: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7013: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7014:                 symmetrized
7015: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7016:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7017:                  always used.
7018: .   n - size of (possibly compressed) matrix
7019: .   ia - the row pointers
7020: -   ja - the column indices

7022:     Output Parameters:
7023: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7025:     Note:
7026:     This routine zeros out n, ia, and ja. This is to prevent accidental
7027:     us of the array after it has been restored. If you pass NULL, it will
7028:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

7030:     Level: developer

7032: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7033: @*/
7034: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7035: {

7044:   MatCheckPreallocated(mat,1);

7046:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7047:   else {
7048:     *done = PETSC_TRUE;
7049:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7050:     if (n)  *n = 0;
7051:     if (ia) *ia = NULL;
7052:     if (ja) *ja = NULL;
7053:   }
7054:   return(0);
7055: }

7059: /*@C
7060:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7061:     MatGetColumnIJ().

7063:     Collective on Mat

7065:     Input Parameters:
7066: +   mat - the matrix
7067: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7068: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7069:                 symmetrized
7070: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7071:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7072:                  always used.

7074:     Output Parameters:
7075: +   n - size of (possibly compressed) matrix
7076: .   ia - the column pointers
7077: .   ja - the row indices
7078: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7080:     Level: developer

7082: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7083: @*/
7084: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7085: {

7094:   MatCheckPreallocated(mat,1);

7096:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7097:   else {
7098:     *done = PETSC_TRUE;
7099:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7100:     if (n)  *n = 0;
7101:     if (ia) *ia = NULL;
7102:     if (ja) *ja = NULL;
7103:   }
7104:   return(0);
7105: }

7109: /*@C
7110:     MatColoringPatch -Used inside matrix coloring routines that
7111:     use MatGetRowIJ() and/or MatGetColumnIJ().

7113:     Collective on Mat

7115:     Input Parameters:
7116: +   mat - the matrix
7117: .   ncolors - max color value
7118: .   n   - number of entries in colorarray
7119: -   colorarray - array indicating color for each column

7121:     Output Parameters:
7122: .   iscoloring - coloring generated using colorarray information

7124:     Level: developer

7126: .seealso: MatGetRowIJ(), MatGetColumnIJ()

7128: @*/
7129: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7130: {

7138:   MatCheckPreallocated(mat,1);

7140:   if (!mat->ops->coloringpatch) {
7141:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);
7142:   } else {
7143:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7144:   }
7145:   return(0);
7146: }


7151: /*@
7152:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.

7154:    Logically Collective on Mat

7156:    Input Parameter:
7157: .  mat - the factored matrix to be reset

7159:    Notes:
7160:    This routine should be used only with factored matrices formed by in-place
7161:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7162:    format).  This option can save memory, for example, when solving nonlinear
7163:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7164:    ILU(0) preconditioner.

7166:    Note that one can specify in-place ILU(0) factorization by calling
7167: .vb
7168:      PCType(pc,PCILU);
7169:      PCFactorSeUseInPlace(pc);
7170: .ve
7171:    or by using the options -pc_type ilu -pc_factor_in_place

7173:    In-place factorization ILU(0) can also be used as a local
7174:    solver for the blocks within the block Jacobi or additive Schwarz
7175:    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
7176:    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7177:    local solver options.

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

7183:    Level: developer

7185: .seealso: PCFactorSetUseInPlace()

7187:    Concepts: matrices^unfactored

7189: @*/
7190: PetscErrorCode  MatSetUnfactored(Mat mat)
7191: {

7197:   MatCheckPreallocated(mat,1);
7198:   mat->factortype = MAT_FACTOR_NONE;
7199:   if (!mat->ops->setunfactored) return(0);
7200:   (*mat->ops->setunfactored)(mat);
7201:   return(0);
7202: }

7204: /*MC
7205:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7207:     Synopsis:
7208:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7210:     Not collective

7212:     Input Parameter:
7213: .   x - matrix

7215:     Output Parameters:
7216: +   xx_v - the Fortran90 pointer to the array
7217: -   ierr - error code

7219:     Example of Usage:
7220: .vb
7221:       PetscScalar, pointer xx_v(:,:)
7222:       ....
7223:       call MatDenseGetArrayF90(x,xx_v,ierr)
7224:       a = xx_v(3)
7225:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7226: .ve

7228:     Level: advanced

7230: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()

7232:     Concepts: matrices^accessing array

7234: M*/

7236: /*MC
7237:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7238:     accessed with MatDenseGetArrayF90().

7240:     Synopsis:
7241:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7243:     Not collective

7245:     Input Parameters:
7246: +   x - matrix
7247: -   xx_v - the Fortran90 pointer to the array

7249:     Output Parameter:
7250: .   ierr - error code

7252:     Example of Usage:
7253: .vb
7254:        PetscScalar, pointer xx_v(:)
7255:        ....
7256:        call MatDenseGetArrayF90(x,xx_v,ierr)
7257:        a = xx_v(3)
7258:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7259: .ve

7261:     Level: advanced

7263: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()

7265: M*/


7268: /*MC
7269:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7271:     Synopsis:
7272:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7274:     Not collective

7276:     Input Parameter:
7277: .   x - matrix

7279:     Output Parameters:
7280: +   xx_v - the Fortran90 pointer to the array
7281: -   ierr - error code

7283:     Example of Usage:
7284: .vb
7285:       PetscScalar, pointer xx_v(:,:)
7286:       ....
7287:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7288:       a = xx_v(3)
7289:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7290: .ve

7292:     Level: advanced

7294: .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()

7296:     Concepts: matrices^accessing array

7298: M*/

7300: /*MC
7301:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7302:     accessed with MatSeqAIJGetArrayF90().

7304:     Synopsis:
7305:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7307:     Not collective

7309:     Input Parameters:
7310: +   x - matrix
7311: -   xx_v - the Fortran90 pointer to the array

7313:     Output Parameter:
7314: .   ierr - error code

7316:     Example of Usage:
7317: .vb
7318:        PetscScalar, pointer xx_v(:)
7319:        ....
7320:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7321:        a = xx_v(3)
7322:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7323: .ve

7325:     Level: advanced

7327: .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()

7329: M*/


7334: /*@
7335:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7336:                       as the original matrix.

7338:     Collective on Mat

7340:     Input Parameters:
7341: +   mat - the original matrix
7342: .   isrow - parallel IS containing the rows this processor should obtain
7343: .   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.
7344: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7346:     Output Parameter:
7347: .   newmat - the new submatrix, of the same type as the old

7349:     Level: advanced

7351:     Notes:
7352:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7354:     The rows in isrow will be sorted into the same order as the original matrix on each process.

7356:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7357:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7358:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7359:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7360:    you are finished using it.

7362:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7363:     the input matrix.

7365:     If iscol is NULL then all columns are obtained (not supported in Fortran).

7367:    Example usage:
7368:    Consider the following 8x8 matrix with 34 non-zero values, that is
7369:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7370:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7371:    as follows:

7373: .vb
7374:             1  2  0  |  0  3  0  |  0  4
7375:     Proc0   0  5  6  |  7  0  0  |  8  0
7376:             9  0 10  | 11  0  0  | 12  0
7377:     -------------------------------------
7378:            13  0 14  | 15 16 17  |  0  0
7379:     Proc1   0 18  0  | 19 20 21  |  0  0
7380:             0  0  0  | 22 23  0  | 24  0
7381:     -------------------------------------
7382:     Proc2  25 26 27  |  0  0 28  | 29  0
7383:            30  0  0  | 31 32 33  |  0 34
7384: .ve

7386:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7388: .vb
7389:             2  0  |  0  3  0  |  0
7390:     Proc0   5  6  |  7  0  0  |  8
7391:     -------------------------------
7392:     Proc1  18  0  | 19 20 21  |  0
7393:     -------------------------------
7394:     Proc2  26 27  |  0  0 28  | 29
7395:             0  0  | 31 32 33  |  0
7396: .ve


7399:     Concepts: matrices^submatrices

7401: .seealso: MatGetSubMatrices()
7402: @*/
7403: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7404: {
7406:   PetscMPIInt    size;
7407:   Mat            *local;
7408:   IS             iscoltmp;

7417:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7418:   MatCheckPreallocated(mat,1);
7419:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7421:   if (!iscol) {
7422:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7423:   } else {
7424:     iscoltmp = iscol;
7425:   }

7427:   /* if original matrix is on just one processor then use submatrix generated */
7428:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7429:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7430:     if (!iscol) {ISDestroy(&iscoltmp);}
7431:     return(0);
7432:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7433:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7434:     *newmat = *local;
7435:     PetscFree(local);
7436:     if (!iscol) {ISDestroy(&iscoltmp);}
7437:     return(0);
7438:   } else if (!mat->ops->getsubmatrix) {
7439:     /* Create a new matrix type that implements the operation using the full matrix */
7440:     switch (cll) {
7441:     case MAT_INITIAL_MATRIX:
7442:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7443:       break;
7444:     case MAT_REUSE_MATRIX:
7445:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7446:       break;
7447:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7448:     }
7449:     if (!iscol) {ISDestroy(&iscoltmp);}
7450:     return(0);
7451:   }

7453:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7454:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7455:   if (!iscol) {ISDestroy(&iscoltmp);}
7456:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7457:   return(0);
7458: }

7462: /*@
7463:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7464:    used during the assembly process to store values that belong to
7465:    other processors.

7467:    Not Collective

7469:    Input Parameters:
7470: +  mat   - the matrix
7471: .  size  - the initial size of the stash.
7472: -  bsize - the initial size of the block-stash(if used).

7474:    Options Database Keys:
7475: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7476: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7478:    Level: intermediate

7480:    Notes:
7481:      The block-stash is used for values set with MatSetValuesBlocked() while
7482:      the stash is used for values set with MatSetValues()

7484:      Run with the option -info and look for output of the form
7485:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7486:      to determine the appropriate value, MM, to use for size and
7487:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7488:      to determine the value, BMM to use for bsize

7490:    Concepts: stash^setting matrix size
7491:    Concepts: matrices^stash

7493: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7495: @*/
7496: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7497: {

7503:   MatStashSetInitialSize_Private(&mat->stash,size);
7504:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7505:   return(0);
7506: }

7510: /*@
7511:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7512:      the matrix

7514:    Neighbor-wise Collective on Mat

7516:    Input Parameters:
7517: +  mat   - the matrix
7518: .  x,y - the vectors
7519: -  w - where the result is stored

7521:    Level: intermediate

7523:    Notes:
7524:     w may be the same vector as y.

7526:     This allows one to use either the restriction or interpolation (its transpose)
7527:     matrix to do the interpolation

7529:     Concepts: interpolation

7531: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7533: @*/
7534: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7535: {
7537:   PetscInt       M,N,Ny;

7545:   MatCheckPreallocated(A,1);
7546:   MatGetSize(A,&M,&N);
7547:   VecGetSize(y,&Ny);
7548:   if (M == Ny) {
7549:     MatMultAdd(A,x,y,w);
7550:   } else {
7551:     MatMultTransposeAdd(A,x,y,w);
7552:   }
7553:   return(0);
7554: }

7558: /*@
7559:    MatInterpolate - y = A*x or A'*x depending on the shape of
7560:      the matrix

7562:    Neighbor-wise Collective on Mat

7564:    Input Parameters:
7565: +  mat   - the matrix
7566: -  x,y - the vectors

7568:    Level: intermediate

7570:    Notes:
7571:     This allows one to use either the restriction or interpolation (its transpose)
7572:     matrix to do the interpolation

7574:    Concepts: matrices^interpolation

7576: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7578: @*/
7579: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7580: {
7582:   PetscInt       M,N,Ny;

7589:   MatCheckPreallocated(A,1);
7590:   MatGetSize(A,&M,&N);
7591:   VecGetSize(y,&Ny);
7592:   if (M == Ny) {
7593:     MatMult(A,x,y);
7594:   } else {
7595:     MatMultTranspose(A,x,y);
7596:   }
7597:   return(0);
7598: }

7602: /*@
7603:    MatRestrict - y = A*x or A'*x

7605:    Neighbor-wise Collective on Mat

7607:    Input Parameters:
7608: +  mat   - the matrix
7609: -  x,y - the vectors

7611:    Level: intermediate

7613:    Notes:
7614:     This allows one to use either the restriction or interpolation (its transpose)
7615:     matrix to do the restriction

7617:    Concepts: matrices^restriction

7619: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()

7621: @*/
7622: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7623: {
7625:   PetscInt       M,N,Ny;

7632:   MatCheckPreallocated(A,1);

7634:   MatGetSize(A,&M,&N);
7635:   VecGetSize(y,&Ny);
7636:   if (M == Ny) {
7637:     MatMult(A,x,y);
7638:   } else {
7639:     MatMultTranspose(A,x,y);
7640:   }
7641:   return(0);
7642: }

7646: /*@
7647:    MatGetNullSpace - retrieves the null space to a matrix.

7649:    Logically Collective on Mat and MatNullSpace

7651:    Input Parameters:
7652: +  mat - the matrix
7653: -  nullsp - the null space object

7655:    Level: developer

7657:    Notes:
7658:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7660:    Concepts: null space^attaching to matrix

7662: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7663: @*/
7664: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7665: {
7670:   *nullsp = mat->nullsp;
7671:   return(0);
7672: }

7676: /*@
7677:    MatSetNullSpace - attaches a null space to a matrix.
7678:         This null space will be removed from the resulting vector whenever
7679:         MatMult() is called

7681:    Logically Collective on Mat and MatNullSpace

7683:    Input Parameters:
7684: +  mat - the matrix
7685: -  nullsp - the null space object

7687:    Level: advanced

7689:    Notes:
7690:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7692:    Concepts: null space^attaching to matrix

7694: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7695: @*/
7696: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7697: {

7704:   MatCheckPreallocated(mat,1);
7705:   PetscObjectReference((PetscObject)nullsp);
7706:   MatNullSpaceDestroy(&mat->nullsp);

7708:   mat->nullsp = nullsp;
7709:   return(0);
7710: }

7714: /*@
7715:    MatSetNearNullSpace - attaches a null space to a matrix.
7716:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

7718:    Logically Collective on Mat and MatNullSpace

7720:    Input Parameters:
7721: +  mat - the matrix
7722: -  nullsp - the null space object

7724:    Level: advanced

7726:    Notes:
7727:       Overwrites any previous near null space that may have been attached

7729:    Concepts: null space^attaching to matrix

7731: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7732: @*/
7733: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7734: {

7741:   MatCheckPreallocated(mat,1);
7742:   PetscObjectReference((PetscObject)nullsp);
7743:   MatNullSpaceDestroy(&mat->nearnullsp);

7745:   mat->nearnullsp = nullsp;
7746:   return(0);
7747: }

7751: /*@
7752:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

7754:    Not Collective

7756:    Input Parameters:
7757: .  mat - the matrix

7759:    Output Parameters:
7760: .  nullsp - the null space object, NULL if not set

7762:    Level: developer

7764:    Concepts: null space^attaching to matrix

7766: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7767: @*/
7768: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7769: {
7774:   MatCheckPreallocated(mat,1);
7775:   *nullsp = mat->nearnullsp;
7776:   return(0);
7777: }

7781: /*@C
7782:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

7784:    Collective on Mat

7786:    Input Parameters:
7787: +  mat - the matrix
7788: .  row - row/column permutation
7789: .  fill - expected fill factor >= 1.0
7790: -  level - level of fill, for ICC(k)

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

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

7800:    Level: developer

7802:    Concepts: matrices^incomplete Cholesky factorization
7803:    Concepts: Cholesky factorization

7805: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

7810: @*/
7811: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7812: {

7820:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
7821:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7822:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7823:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7824:   MatCheckPreallocated(mat,1);
7825:   (*mat->ops->iccfactor)(mat,row,info);
7826:   PetscObjectStateIncrease((PetscObject)mat);
7827:   return(0);
7828: }

7832: /*@
7833:    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.

7835:    Not Collective

7837:    Input Parameters:
7838: +  mat - the matrix
7839: .  nl - leading dimension of v
7840: -  v - the values compute with ADIFOR

7842:    Level: developer

7844:    Notes:
7845:      Must call MatSetColoring() before using this routine. Also this matrix must already
7846:      have its nonzero pattern determined.

7848: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7849:           MatSetValues(), MatSetColoring()
7850: @*/
7851: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7852: {


7860:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7861:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7862:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7863:   (*mat->ops->setvaluesadifor)(mat,nl,v);
7864:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7865:   PetscObjectStateIncrease((PetscObject)mat);
7866:   return(0);
7867: }

7871: /*@
7872:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7873:          ghosted ones.

7875:    Not Collective

7877:    Input Parameters:
7878: +  mat - the matrix
7879: -  diag = the diagonal values, including ghost ones

7881:    Level: developer

7883:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

7885: .seealso: MatDiagonalScale()
7886: @*/
7887: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7888: {
7890:   PetscMPIInt    size;


7897:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7898:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7899:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7900:   if (size == 1) {
7901:     PetscInt n,m;
7902:     VecGetSize(diag,&n);
7903:     MatGetSize(mat,0,&m);
7904:     if (m == n) {
7905:       MatDiagonalScale(mat,0,diag);
7906:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7907:   } else {
7908:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7909:   }
7910:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7911:   PetscObjectStateIncrease((PetscObject)mat);
7912:   return(0);
7913: }

7917: /*@
7918:    MatGetInertia - Gets the inertia from a factored matrix

7920:    Collective on Mat

7922:    Input Parameter:
7923: .  mat - the matrix

7925:    Output Parameters:
7926: +   nneg - number of negative eigenvalues
7927: .   nzero - number of zero eigenvalues
7928: -   npos - number of positive eigenvalues

7930:    Level: advanced

7932:    Notes: Matrix must have been factored by MatCholeskyFactor()


7935: @*/
7936: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7937: {

7943:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7944:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7945:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7946:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7947:   return(0);
7948: }

7950: /* ----------------------------------------------------------------*/
7953: /*@C
7954:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

7956:    Neighbor-wise Collective on Mat and Vecs

7958:    Input Parameters:
7959: +  mat - the factored matrix
7960: -  b - the right-hand-side vectors

7962:    Output Parameter:
7963: .  x - the result vectors

7965:    Notes:
7966:    The vectors b and x cannot be the same.  I.e., one cannot
7967:    call MatSolves(A,x,x).

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

7974:    Level: developer

7976:    Concepts: matrices^triangular solves

7978: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7979: @*/
7980: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7981: {

7987:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7988:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7989:   if (!mat->rmap->N && !mat->cmap->N) return(0);

7991:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7992:   MatCheckPreallocated(mat,1);
7993:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7994:   (*mat->ops->solves)(mat,b,x);
7995:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7996:   return(0);
7997: }

8001: /*@
8002:    MatIsSymmetric - Test whether a matrix is symmetric

8004:    Collective on Mat

8006:    Input Parameter:
8007: +  A - the matrix to test
8008: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

8010:    Output Parameters:
8011: .  flg - the result

8013:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

8015:    Level: intermediate

8017:    Concepts: matrix^symmetry

8019: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8020: @*/
8021: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8022: {


8029:   if (!A->symmetric_set) {
8030:     if (!A->ops->issymmetric) {
8031:       MatType mattype;
8032:       MatGetType(A,&mattype);
8033:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8034:     }
8035:     (*A->ops->issymmetric)(A,tol,flg);
8036:     if (!tol) {
8037:       A->symmetric_set = PETSC_TRUE;
8038:       A->symmetric     = *flg;
8039:       if (A->symmetric) {
8040:         A->structurally_symmetric_set = PETSC_TRUE;
8041:         A->structurally_symmetric     = PETSC_TRUE;
8042:       }
8043:     }
8044:   } else if (A->symmetric) {
8045:     *flg = PETSC_TRUE;
8046:   } else if (!tol) {
8047:     *flg = PETSC_FALSE;
8048:   } else {
8049:     if (!A->ops->issymmetric) {
8050:       MatType mattype;
8051:       MatGetType(A,&mattype);
8052:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8053:     }
8054:     (*A->ops->issymmetric)(A,tol,flg);
8055:   }
8056:   return(0);
8057: }

8061: /*@
8062:    MatIsHermitian - Test whether a matrix is Hermitian

8064:    Collective on Mat

8066:    Input Parameter:
8067: +  A - the matrix to test
8068: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

8070:    Output Parameters:
8071: .  flg - the result

8073:    Level: intermediate

8075:    Concepts: matrix^symmetry

8077: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8078:           MatIsSymmetricKnown(), MatIsSymmetric()
8079: @*/
8080: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8081: {


8088:   if (!A->hermitian_set) {
8089:     if (!A->ops->ishermitian) {
8090:       MatType mattype;
8091:       MatGetType(A,&mattype);
8092:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8093:     }
8094:     (*A->ops->ishermitian)(A,tol,flg);
8095:     if (!tol) {
8096:       A->hermitian_set = PETSC_TRUE;
8097:       A->hermitian     = *flg;
8098:       if (A->hermitian) {
8099:         A->structurally_symmetric_set = PETSC_TRUE;
8100:         A->structurally_symmetric     = PETSC_TRUE;
8101:       }
8102:     }
8103:   } else if (A->hermitian) {
8104:     *flg = PETSC_TRUE;
8105:   } else if (!tol) {
8106:     *flg = PETSC_FALSE;
8107:   } else {
8108:     if (!A->ops->ishermitian) {
8109:       MatType mattype;
8110:       MatGetType(A,&mattype);
8111:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8112:     }
8113:     (*A->ops->ishermitian)(A,tol,flg);
8114:   }
8115:   return(0);
8116: }

8120: /*@
8121:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

8123:    Not Collective

8125:    Input Parameter:
8126: .  A - the matrix to check

8128:    Output Parameters:
8129: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8130: -  flg - the result

8132:    Level: advanced

8134:    Concepts: matrix^symmetry

8136:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8137:          if you want it explicitly checked

8139: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8140: @*/
8141: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8142: {
8147:   if (A->symmetric_set) {
8148:     *set = PETSC_TRUE;
8149:     *flg = A->symmetric;
8150:   } else {
8151:     *set = PETSC_FALSE;
8152:   }
8153:   return(0);
8154: }

8158: /*@
8159:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8161:    Not Collective

8163:    Input Parameter:
8164: .  A - the matrix to check

8166:    Output Parameters:
8167: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8168: -  flg - the result

8170:    Level: advanced

8172:    Concepts: matrix^symmetry

8174:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8175:          if you want it explicitly checked

8177: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8178: @*/
8179: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8180: {
8185:   if (A->hermitian_set) {
8186:     *set = PETSC_TRUE;
8187:     *flg = A->hermitian;
8188:   } else {
8189:     *set = PETSC_FALSE;
8190:   }
8191:   return(0);
8192: }

8196: /*@
8197:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8199:    Collective on Mat

8201:    Input Parameter:
8202: .  A - the matrix to test

8204:    Output Parameters:
8205: .  flg - the result

8207:    Level: intermediate

8209:    Concepts: matrix^symmetry

8211: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8212: @*/
8213: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8214: {

8220:   if (!A->structurally_symmetric_set) {
8221:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8222:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);

8224:     A->structurally_symmetric_set = PETSC_TRUE;
8225:   }
8226:   *flg = A->structurally_symmetric;
8227:   return(0);
8228: }

8232: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8233: /*@
8234:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8235:        to be communicated to other processors during the MatAssemblyBegin/End() process

8237:     Not collective

8239:    Input Parameter:
8240: .   vec - the vector

8242:    Output Parameters:
8243: +   nstash   - the size of the stash
8244: .   reallocs - the number of additional mallocs incurred.
8245: .   bnstash   - the size of the block stash
8246: -   breallocs - the number of additional mallocs incurred.in the block stash

8248:    Level: advanced

8250: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()

8252: @*/
8253: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8254: {

8258:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8259:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8260:   return(0);
8261: }

8265: /*@C
8266:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8267:      parallel layout

8269:    Collective on Mat

8271:    Input Parameter:
8272: .  mat - the matrix

8274:    Output Parameter:
8275: +   right - (optional) vector that the matrix can be multiplied against
8276: -   left - (optional) vector that the matrix vector product can be stored in

8278:   Level: advanced

8280: .seealso: MatCreate()
8281: @*/
8282: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8283: {

8289:   MatCheckPreallocated(mat,1);
8290:   if (mat->ops->getvecs) {
8291:     (*mat->ops->getvecs)(mat,right,left);
8292:   } else {
8293:     PetscMPIInt size;
8294:     PetscInt rbs,cbs;
8295:     MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8296:     MatGetBlockSizes(mat,&rbs,&cbs);
8297:     if (right) {
8298:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8299:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8300:       VecSetBlockSize(*right,cbs);
8301:       VecSetType(*right,VECSTANDARD);
8302:       PetscLayoutReference(mat->cmap,&(*right)->map);
8303:     }
8304:     if (left) {
8305:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8306:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8307:       VecSetBlockSize(*left,rbs);
8308:       VecSetType(*left,VECSTANDARD);
8309:       PetscLayoutReference(mat->rmap,&(*left)->map);
8310:     }
8311:   }
8312:   return(0);
8313: }

8317: /*@C
8318:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8319:      with default values.

8321:    Not Collective

8323:    Input Parameters:
8324: .    info - the MatFactorInfo data structure


8327:    Notes: The solvers are generally used through the KSP and PC objects, for example
8328:           PCLU, PCILU, PCCHOLESKY, PCICC

8330:    Level: developer

8332: .seealso: MatFactorInfo

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

8337: @*/

8339: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8340: {

8344:   PetscMemzero(info,sizeof(MatFactorInfo));
8345:   return(0);
8346: }

8350: /*@
8351:    MatPtAP - Creates the matrix product C = P^T * A * P

8353:    Neighbor-wise Collective on Mat

8355:    Input Parameters:
8356: +  A - the matrix
8357: .  P - the projection matrix
8358: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8359: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

8361:    Output Parameters:
8362: .  C - the product matrix

8364:    Notes:
8365:    C will be created and must be destroyed by the user with MatDestroy().

8367:    This routine is currently only implemented for pairs of AIJ matrices and classes
8368:    which inherit from AIJ.

8370:    Level: intermediate

8372: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8373: @*/
8374: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8375: {
8377:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8378:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8379:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8380:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

8383:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8384:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

8388:   MatCheckPreallocated(A,1);
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");

8397:   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);
8398:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8400:   if (scall == MAT_REUSE_MATRIX) {
8403:     if (viatranspose || viamatmatmatmult) {
8404:       Mat Pt;
8405:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8406:       if (viamatmatmatmult) {
8407:         MatMatMatMult(Pt,A,P,scall,fill,C);
8408:       } else {
8409:         Mat AP;
8410:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8411:         MatMatMult(Pt,AP,scall,fill,C);
8412:         MatDestroy(&AP);
8413:       }
8414:       MatDestroy(&Pt);
8415:     } else {
8416:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8417:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8418:       (*(*C)->ops->ptapnumeric)(A,P,*C);
8419:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8420:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8421:     }
8422:     return(0);
8423:   }

8425:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8426:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8428:   fA = A->ops->ptap;
8429:   fP = P->ops->ptap;
8430:   if (fP == fA) {
8431:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8432:     ptap = fA;
8433:   } else {
8434:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8435:     char ptapname[256];
8436:     PetscStrcpy(ptapname,"MatPtAP_");
8437:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
8438:     PetscStrcat(ptapname,"_");
8439:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
8440:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8441:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8442:     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);
8443:   }

8445:   if (viatranspose || viamatmatmatmult) {
8446:     Mat Pt;
8447:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8448:     if (viamatmatmatmult) {
8449:       MatMatMatMult(Pt,A,P,scall,fill,C);
8450:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8451:     } else {
8452:       Mat AP;
8453:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8454:       MatMatMult(Pt,AP,scall,fill,C);
8455:       MatDestroy(&AP);
8456:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8457:     }
8458:     MatDestroy(&Pt);
8459:   } else {
8460:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8461:     (*ptap)(A,P,scall,fill,C);
8462:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8463:   }
8464:   return(0);
8465: }

8469: /*@
8470:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

8472:    Neighbor-wise Collective on Mat

8474:    Input Parameters:
8475: +  A - the matrix
8476: -  P - the projection matrix

8478:    Output Parameters:
8479: .  C - the product matrix

8481:    Notes:
8482:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8483:    the user using MatDeatroy().

8485:    This routine is currently only implemented for pairs of AIJ matrices and classes
8486:    which inherit from AIJ.  C will be of type MATAIJ.

8488:    Level: intermediate

8490: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8491: @*/
8492: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8493: {

8499:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8500:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8503:   MatCheckPreallocated(P,2);
8504:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8505:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8508:   MatCheckPreallocated(C,3);
8509:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8510:   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);
8511:   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);
8512:   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);
8513:   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);
8514:   MatCheckPreallocated(A,1);

8516:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8517:   (*C->ops->ptapnumeric)(A,P,C);
8518:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8519:   return(0);
8520: }

8524: /*@
8525:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

8527:    Neighbor-wise Collective on Mat

8529:    Input Parameters:
8530: +  A - the matrix
8531: -  P - the projection matrix

8533:    Output Parameters:
8534: .  C - the (i,j) structure of the product matrix

8536:    Notes:
8537:    C will be created and must be destroyed by the user with MatDestroy().

8539:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8540:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8541:    this (i,j) structure by calling MatPtAPNumeric().

8543:    Level: intermediate

8545: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8546: @*/
8547: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8548: {

8554:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8555:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8556:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8559:   MatCheckPreallocated(P,2);
8560:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8561:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8564:   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);
8565:   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);
8566:   MatCheckPreallocated(A,1);
8567:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8568:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8569:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

8571:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8572:   return(0);
8573: }

8577: /*@
8578:    MatRARt - Creates the matrix product C = R * A * R^T

8580:    Neighbor-wise Collective on Mat

8582:    Input Parameters:
8583: +  A - the matrix
8584: .  R - the projection matrix
8585: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8586: -  fill - expected fill as ratio of nnz(C)/nnz(A)

8588:    Output Parameters:
8589: .  C - the product matrix

8591:    Notes:
8592:    C will be created and must be destroyed by the user with MatDestroy().

8594:    This routine is currently only implemented for pairs of AIJ matrices and classes
8595:    which inherit from AIJ.

8597:    Level: intermediate

8599: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8600: @*/
8601: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,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");
8612:   MatCheckPreallocated(R,2);
8613:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8614:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8616:   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);
8617:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8618:   MatCheckPreallocated(A,1);

8620:   if (!A->ops->rart) {
8621:     MatType mattype;
8622:     MatGetType(A,&mattype);
8623:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8624:   }
8625:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
8626:   (*A->ops->rart)(A,R,scall,fill,C);
8627:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
8628:   return(0);
8629: }

8633: /*@
8634:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

8636:    Neighbor-wise Collective on Mat

8638:    Input Parameters:
8639: +  A - the matrix
8640: -  R - the projection matrix

8642:    Output Parameters:
8643: .  C - the product matrix

8645:    Notes:
8646:    C must have been created by calling MatRARtSymbolic and must be destroyed by
8647:    the user using MatDeatroy().

8649:    This routine is currently only implemented for pairs of AIJ matrices and classes
8650:    which inherit from AIJ.  C will be of type MATAIJ.

8652:    Level: intermediate

8654: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8655: @*/
8656: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8657: {

8663:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8664:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8667:   MatCheckPreallocated(R,2);
8668:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8669:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8672:   MatCheckPreallocated(C,3);
8673:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8674:   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);
8675:   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);
8676:   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);
8677:   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);
8678:   MatCheckPreallocated(A,1);

8680:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8681:   (*A->ops->rartnumeric)(A,R,C);
8682:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8683:   return(0);
8684: }

8688: /*@
8689:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

8691:    Neighbor-wise Collective on Mat

8693:    Input Parameters:
8694: +  A - the matrix
8695: -  R - the projection matrix

8697:    Output Parameters:
8698: .  C - the (i,j) structure of the product matrix

8700:    Notes:
8701:    C will be created and must be destroyed by the user with MatDestroy().

8703:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8704:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8705:    this (i,j) structure by calling MatRARtNumeric().

8707:    Level: intermediate

8709: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8710: @*/
8711: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8712: {

8718:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8719:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8720:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8723:   MatCheckPreallocated(R,2);
8724:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8725:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8728:   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);
8729:   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);
8730:   MatCheckPreallocated(A,1);
8731:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8732:   (*A->ops->rartsymbolic)(A,R,fill,C);
8733:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

8735:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
8736:   return(0);
8737: }

8741: /*@
8742:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

8744:    Neighbor-wise Collective on Mat

8746:    Input Parameters:
8747: +  A - the left matrix
8748: .  B - the right matrix
8749: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8750: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8751:           if the result is a dense matrix this is irrelevent

8753:    Output Parameters:
8754: .  C - the product matrix

8756:    Notes:
8757:    Unless scall is MAT_REUSE_MATRIX C will be created.

8759:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8761:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8762:    actually needed.

8764:    If you have many matrices with the same non-zero structure to multiply, you
8765:    should either
8766: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8767: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

8769:    Level: intermediate

8771: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8772: @*/
8773: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8774: {
8776:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8777:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8778:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

8783:   MatCheckPreallocated(A,1);
8784:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8785:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8788:   MatCheckPreallocated(B,2);
8789:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8790:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8792:   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);
8793:   if (scall == MAT_REUSE_MATRIX) {
8796:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8797:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8798:     (*(*C)->ops->matmultnumeric)(A,B,*C);
8799:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8800:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8801:     return(0);
8802:   }
8803:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8804:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8806:   fA = A->ops->matmult;
8807:   fB = B->ops->matmult;
8808:   if (fB == fA) {
8809:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8810:     mult = fB;
8811:   } else {
8812:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8813:     char multname[256];
8814:     PetscStrcpy(multname,"MatMatMult_");
8815:     PetscStrcat(multname,((PetscObject)A)->type_name);
8816:     PetscStrcat(multname,"_");
8817:     PetscStrcat(multname,((PetscObject)B)->type_name);
8818:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8819:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
8820:     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);
8821:   }
8822:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8823:   (*mult)(A,B,scall,fill,C);
8824:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8825:   return(0);
8826: }

8830: /*@
8831:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8832:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

8834:    Neighbor-wise Collective on Mat

8836:    Input Parameters:
8837: +  A - the left matrix
8838: .  B - the right matrix
8839: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8840:       if C is a dense matrix this is irrelevent

8842:    Output Parameters:
8843: .  C - the product matrix

8845:    Notes:
8846:    Unless scall is MAT_REUSE_MATRIX C will be created.

8848:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8849:    actually needed.

8851:    This routine is currently implemented for
8852:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8853:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8854:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8856:    Level: intermediate

8858:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8859:      We should incorporate them into PETSc.

8861: .seealso: MatMatMult(), MatMatMultNumeric()
8862: @*/
8863: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8864: {
8866:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
8867:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
8868:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

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

8883:   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);
8884:   if (fill == PETSC_DEFAULT) fill = 2.0;
8885:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8886:   MatCheckPreallocated(A,1);

8888:   Asymbolic = A->ops->matmultsymbolic;
8889:   Bsymbolic = B->ops->matmultsymbolic;
8890:   if (Asymbolic == Bsymbolic) {
8891:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8892:     symbolic = Bsymbolic;
8893:   } else { /* dispatch based on the type of A and B */
8894:     char symbolicname[256];
8895:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8896:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8897:     PetscStrcat(symbolicname,"_");
8898:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8899:     PetscStrcat(symbolicname,"_C");
8900:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
8901:     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);
8902:   }
8903:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8904:   (*symbolic)(A,B,fill,C);
8905:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8906:   return(0);
8907: }

8911: /*@
8912:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8913:    Call this routine after first calling MatMatMultSymbolic().

8915:    Neighbor-wise Collective on Mat

8917:    Input Parameters:
8918: +  A - the left matrix
8919: -  B - the right matrix

8921:    Output Parameters:
8922: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

8924:    Notes:
8925:    C must have been created with MatMatMultSymbolic().

8927:    This routine is currently implemented for
8928:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8929:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8930:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8932:    Level: intermediate

8934: .seealso: MatMatMult(), MatMatMultSymbolic()
8935: @*/
8936: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8937: {

8941:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
8942:   return(0);
8943: }

8947: /*@
8948:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

8950:    Neighbor-wise Collective on Mat

8952:    Input Parameters:
8953: +  A - the left matrix
8954: .  B - the right matrix
8955: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8956: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8958:    Output Parameters:
8959: .  C - the product matrix

8961:    Notes:
8962:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8964:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8966:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8967:    actually needed.

8969:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

8971:    Level: intermediate

8973: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8974: @*/
8975: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8976: {
8978:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8979:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

8984:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8985:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8988:   MatCheckPreallocated(B,2);
8989:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8990:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8992:   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);
8993:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8994:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8995:   MatCheckPreallocated(A,1);

8997:   fA = A->ops->mattransposemult;
8998:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8999:   fB = B->ops->mattransposemult;
9000:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9001:   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);

9003:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9004:   if (scall == MAT_INITIAL_MATRIX) {
9005:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9006:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9007:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9008:   }
9009:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9010:   (*A->ops->mattransposemultnumeric)(A,B,*C);
9011:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9012:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9013:   return(0);
9014: }

9018: /*@
9019:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

9021:    Neighbor-wise Collective on Mat

9023:    Input Parameters:
9024: +  A - the left matrix
9025: .  B - the right matrix
9026: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9027: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9029:    Output Parameters:
9030: .  C - the product matrix

9032:    Notes:
9033:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

9035:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9037:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9038:    actually needed.

9040:    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9041:    which inherit from SeqAIJ.  C will be of same type as the input matrices.

9043:    Level: intermediate

9045: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9046: @*/
9047: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9048: {
9050:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9051:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9052:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

9057:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9058:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9061:   MatCheckPreallocated(B,2);
9062:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9063:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9065:   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);
9066:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9067:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9068:   MatCheckPreallocated(A,1);

9070:   fA = A->ops->transposematmult;
9071:   fB = B->ops->transposematmult;
9072:   if (fB==fA) {
9073:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9074:     transposematmult = fA;
9075:   } else {
9076:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9077:     char multname[256];
9078:     PetscStrcpy(multname,"MatTransposeMatMult_");
9079:     PetscStrcat(multname,((PetscObject)A)->type_name);
9080:     PetscStrcat(multname,"_");
9081:     PetscStrcat(multname,((PetscObject)B)->type_name);
9082:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9083:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9084:     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);
9085:   }
9086:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9087:   (*transposematmult)(A,B,scall,fill,C);
9088:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9089:   return(0);
9090: }

9094: /*@
9095:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

9097:    Neighbor-wise Collective on Mat

9099:    Input Parameters:
9100: +  A - the left matrix
9101: .  B - the middle matrix
9102: .  C - the right matrix
9103: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9104: -  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
9105:           if the result is a dense matrix this is irrelevent

9107:    Output Parameters:
9108: .  D - the product matrix

9110:    Notes:
9111:    Unless scall is MAT_REUSE_MATRIX D will be created.

9113:    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call

9115:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9116:    actually needed.

9118:    If you have many matrices with the same non-zero structure to multiply, you
9119:    should either
9120: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9121: $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed

9123:    Level: intermediate

9125: .seealso: MatMatMult, MatPtAP()
9126: @*/
9127: PetscErrorCode  MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9128: {
9130:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9131:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9132:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9133:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9138:   MatCheckPreallocated(A,1);
9139:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9140:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9143:   MatCheckPreallocated(B,2);
9144:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9145:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9148:   MatCheckPreallocated(C,3);
9149:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9150:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9151:   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);
9152:   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);
9153:   if (scall == MAT_REUSE_MATRIX) {
9156:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9157:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9158:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9159:     return(0);
9160:   }
9161:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9162:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9164:   fA = A->ops->matmatmult;
9165:   fB = B->ops->matmatmult;
9166:   fC = C->ops->matmatmult;
9167:   if (fA == fB && fA == fC) {
9168:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9169:     mult = fA;
9170:   } else {
9171:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9172:     char multname[256];
9173:     PetscStrcpy(multname,"MatMatMatMult_");
9174:     PetscStrcat(multname,((PetscObject)A)->type_name);
9175:     PetscStrcat(multname,"_");
9176:     PetscStrcat(multname,((PetscObject)B)->type_name);
9177:     PetscStrcat(multname,"_");
9178:     PetscStrcat(multname,((PetscObject)C)->type_name);
9179:     PetscStrcat(multname,"_C");
9180:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9181:     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);
9182:   }
9183:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9184:   (*mult)(A,B,C,scall,fill,D);
9185:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9186:   return(0);
9187: }

9191: /*@C
9192:    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

9194:    Collective on Mat

9196:    Input Parameters:
9197: +  mat - the matrix
9198: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9199: .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9200: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9202:    Output Parameter:
9203: .  matredundant - redundant matrix

9205:    Notes:
9206:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9207:    original matrix has not changed from that last call to MatGetRedundantMatrix().

9209:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9210:    calling it.

9212:    Only MPIAIJ matrix is supported.

9214:    Level: advanced

9216:    Concepts: subcommunicator
9217:    Concepts: duplicate matrix

9219: .seealso: MatDestroy()
9220: @*/
9221: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9222: {

9227:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9230:   }
9231:   if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9232:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9233:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9234:   MatCheckPreallocated(mat,1);

9236:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
9237:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,reuse,matredundant);
9238:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
9239:   return(0);
9240: }

9244: /*@C
9245:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9246:    a given 'mat' object. Each submatrix can span multiple procs.

9248:    Collective on Mat

9250:    Input Parameters:
9251: +  mat - the matrix
9252: .  subcomm - the subcommunicator obtained by com_split(comm)
9253: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9255:    Output Parameter:
9256: .  subMat - 'parallel submatrices each spans a given subcomm

9258:   Notes:
9259:   The submatrix partition across processors is dictated by 'subComm' a
9260:   communicator obtained by com_split(comm). The comm_split
9261:   is not restriced to be grouped with consecutive original ranks.

9263:   Due the comm_split() usage, the parallel layout of the submatrices
9264:   map directly to the layout of the original matrix [wrt the local
9265:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9266:   into the 'DiagonalMat' of the subMat, hence it is used directly from
9267:   the subMat. However the offDiagMat looses some columns - and this is
9268:   reconstructed with MatSetValues()

9270:   Level: advanced

9272:   Concepts: subcommunicator
9273:   Concepts: submatrices

9275: .seealso: MatGetSubMatrices()
9276: @*/
9277: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9278: {
9280:   PetscMPIInt    commsize,subCommSize;

9283:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9284:   MPI_Comm_size(subComm,&subCommSize);
9285:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

9287:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9288:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9289:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9290:   return(0);
9291: }

9295: /*@
9296:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

9298:    Not Collective

9300:    Input Arguments:
9301:    mat - matrix to extract local submatrix from
9302:    isrow - local row indices for submatrix
9303:    iscol - local column indices for submatrix

9305:    Output Arguments:
9306:    submat - the submatrix

9308:    Level: intermediate

9310:    Notes:
9311:    The submat should be returned with MatRestoreLocalSubMatrix().

9313:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9314:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

9316:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9317:    MatSetValuesBlockedLocal() will also be implemented.

9319: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9320: @*/
9321: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9322: {


9332:   if (mat->ops->getlocalsubmatrix) {
9333:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9334:   } else {
9335:     MatCreateLocalRef(mat,isrow,iscol,submat);
9336:   }
9337:   return(0);
9338: }

9342: /*@
9343:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

9345:    Not Collective

9347:    Input Arguments:
9348:    mat - matrix to extract local submatrix from
9349:    isrow - local row indices for submatrix
9350:    iscol - local column indices for submatrix
9351:    submat - the submatrix

9353:    Level: intermediate

9355: .seealso: MatGetLocalSubMatrix()
9356: @*/
9357: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9358: {

9367:   if (*submat) {
9369:   }

9371:   if (mat->ops->restorelocalsubmatrix) {
9372:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9373:   } else {
9374:     MatDestroy(submat);
9375:   }
9376:   *submat = NULL;
9377:   return(0);
9378: }

9380: /* --------------------------------------------------------*/
9383: /*@
9384:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

9386:    Collective on Mat

9388:    Input Parameter:
9389: .  mat - the matrix

9391:    Output Parameter:
9392: .  is - if any rows have zero diagonals this contains the list of them

9394:    Level: developer

9396:    Concepts: matrix-vector product

9398: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9399: @*/
9400: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9401: {

9407:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9408:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9410:   if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9411:   (*mat->ops->findzerodiagonals)(mat,is);
9412:   return(0);
9413: }

9417: /*@
9418:    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)

9420:    Collective on Mat

9422:    Input Parameter:
9423: .  mat - the matrix

9425:    Output Parameter:
9426: .  is - contains the list of rows with off block diagonal entries

9428:    Level: developer

9430:    Concepts: matrix-vector product

9432: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9433: @*/
9434: PetscErrorCode  MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
9435: {

9441:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9442:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9444:   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
9445:   (*mat->ops->findoffblockdiagonalentries)(mat,is);
9446:   return(0);
9447: }

9451: /*@C
9452:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

9454:   Collective on Mat

9456:   Input Parameters:
9457: . mat - the matrix

9459:   Output Parameters:
9460: . values - the block inverses in column major order (FORTRAN-like)

9462:    Note:
9463:    This routine is not available from Fortran.

9465:   Level: advanced
9466: @*/
9467: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9468: {

9473:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9474:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9475:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9476:   (*mat->ops->invertblockdiagonal)(mat,values);
9477:   return(0);
9478: }

9482: /*@C
9483:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9484:     via MatTransposeColoringCreate().

9486:     Collective on MatTransposeColoring

9488:     Input Parameter:
9489: .   c - coloring context

9491:     Level: intermediate

9493: .seealso: MatTransposeColoringCreate()
9494: @*/
9495: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9496: {
9497:   PetscErrorCode       ierr;
9498:   MatTransposeColoring matcolor=*c;

9501:   if (!matcolor) return(0);
9502:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

9504:   PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
9505:   PetscFree(matcolor->rows);
9506:   PetscFree(matcolor->den2sp);
9507:   PetscFree(matcolor->colorforcol);
9508:   PetscFree(matcolor->columns);
9509:   if (matcolor->brows>0) {
9510:     PetscFree(matcolor->lstart);
9511:   }
9512:   PetscHeaderDestroy(c);
9513:   return(0);
9514: }

9518: /*@C
9519:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9520:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9521:     MatTransposeColoring to sparse B.

9523:     Collective on MatTransposeColoring

9525:     Input Parameters:
9526: +   B - sparse matrix B
9527: .   Btdense - symbolic dense matrix B^T
9528: -   coloring - coloring context created with MatTransposeColoringCreate()

9530:     Output Parameter:
9531: .   Btdense - dense matrix B^T

9533:     Options Database Keys:
9534: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9535: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9536: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

9538:     Level: intermediate

9540: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

9542: .keywords: coloring
9543: @*/
9544: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9545: {


9553:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9554:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9555:   return(0);
9556: }

9560: /*@C
9561:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9562:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9563:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9564:     Csp from Cden.

9566:     Collective on MatTransposeColoring

9568:     Input Parameters:
9569: +   coloring - coloring context created with MatTransposeColoringCreate()
9570: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

9572:     Output Parameter:
9573: .   Csp - sparse matrix

9575:     Options Database Keys:
9576: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9577: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9578: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

9580:     Level: intermediate

9582: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

9584: .keywords: coloring
9585: @*/
9586: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9587: {


9595:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9596:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9597:   return(0);
9598: }

9602: /*@C
9603:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

9605:    Collective on Mat

9607:    Input Parameters:
9608: +  mat - the matrix product C
9609: -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()

9611:     Output Parameter:
9612: .   color - the new coloring context

9614:     Level: intermediate

9616: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9617:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9618: @*/
9619: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9620: {
9621:   MatTransposeColoring c;
9622:   MPI_Comm             comm;
9623:   PetscErrorCode       ierr;

9626:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9627:   PetscObjectGetComm((PetscObject)mat,&comm);
9628:   PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);

9630:   c->ctype = iscoloring->ctype;
9631:   if (mat->ops->transposecoloringcreate) {
9632:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9633:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

9635:   *color = c;
9636:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9637:   return(0);
9638: }

9642: /*@
9643:       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 
9644:         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 
9645:         same, otherwise it will be larger

9647:      Not Collective

9649:   Input Parameter:
9650: .    A  - the matrix

9652:   Output Parameter:
9653: .    state - the current state

9655:   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 
9656:          different matrices

9658:   Level: intermediate

9660: @*/
9661: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
9662: {
9664:   *state = mat->nonzerostate;
9665:   return(0);
9666: }