Actual source code: matrix.c

petsc-master 2015-04-27
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>
  8: #include <petsc/private/isimpl.h>

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

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

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

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

 47:    Logically Collective on Vec

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

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

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

 64:    Level: intermediate

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

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


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

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

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


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

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

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

110:   Level: intermediate

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

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

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

131:    Not Collective

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

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

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

141:    Level: advanced

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

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:   MatCreateVecs(mat,&diag,NULL);
192:   MatGetDiagonal(mat,diag);
193:   VecSum(diag,trace);
194:   VecDestroy(&diag);
195:   return(0);
196: }

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

203:    Logically Collective on Mat

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

208:    Level: advanced


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

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

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

243:    Collective on Mat

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

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

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

254:    Level: advanced

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

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


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

281:    Logically Collective on Mat

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

286:    Level: advanced


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

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

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

321:    Collective on Mat

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

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

330:    Level: advanced


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

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

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

356:    Not Collective

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

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

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

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

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

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

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

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


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

406:    Level: advanced

408:    Concepts: matrices^row access

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

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

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

436:    Logically Collective on Mat

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

441:    Level: advanced

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

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

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

476:    Not Collective

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

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

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

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

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

506:    Level: advanced

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

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

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

532:    Not Collective

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

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

540:    Level: advanced

542:    Concepts: matrices^row access

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

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

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

566:    Not Collective

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

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


575:    Level: advanced

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

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

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

597:    Logically Collective on Mat

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

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

607:    Level: advanced

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

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

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

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

629:    Logically Collective on Mat

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

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

639:    Level: advanced

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

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

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

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

661:    Not Collective

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

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

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

672:    Level: advanced

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

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

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

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

693:    Collective on Mat

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

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

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

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

705:    Level: beginner

707: .keywords: Mat, setup

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

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

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

742:    Collective on Mat

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

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

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

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

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

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

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

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

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

813: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
814:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
815: @*/
816: PetscErrorCode  MatView(Mat mat,PetscViewer viewer)
817: {
818:   PetscErrorCode    ierr;
819:   PetscInt          rows,cols,rbs,cbs;
820:   PetscBool         iascii;
821:   PetscViewerFormat format;
822: #if defined(PETSC_HAVE_SAWS)
823:   PetscBool         issaws;
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,&issaws);
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:       MatGetBlockSizes(mat,&rbs,&cbs);
853:       if (rbs != 1 || cbs != 1) {
854:         if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
855:         else            {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
856:       } else {
857:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
858:       }
859:       if (mat->factortype) {
860:         const MatSolverPackage solver;
861:         MatFactorGetSolverPackage(mat,&solver);
862:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
863:       }
864:       if (mat->ops->getinfo) {
865:         MatInfo info;
866:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
867:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%g, allocated nonzeros=%g\n",info.nz_used,info.nz_allocated);
868:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
869:       }
870:       if (mat->nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached null space\n");}
871:       if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");}
872:     }
873: #if defined(PETSC_HAVE_SAWS)
874:   } else if (issaws) {
875:     PetscMPIInt rank;

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

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

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

921:    Collective on PetscViewer

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

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

933:    Level: beginner

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1017: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1018: {
1020:   Mat_Redundant  *redund = *redundant;
1021:   PetscInt       i;

1024:   if (redund){
1025:     if (redund->matseq) { /* via MatGetSubMatrices()  */
1026:       ISDestroy(&redund->isrow);
1027:       ISDestroy(&redund->iscol);
1028:       MatDestroy(&redund->matseq[0]);
1029:       PetscFree(redund->matseq);
1030:     } else {
1031:       PetscFree2(redund->send_rank,redund->recv_rank);
1032:       PetscFree(redund->sbuf_j);
1033:       PetscFree(redund->sbuf_a);
1034:       for (i=0; i<redund->nrecvs; i++) {
1035:         PetscFree(redund->rbuf_j[i]);
1036:         PetscFree(redund->rbuf_a[i]);
1037:       }
1038:       PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1039:     }

1041:     if (redund->subcomm) {
1042:       PetscCommDestroy(&redund->subcomm);
1043:     }
1044:     PetscFree(redund);
1045:   }
1046:   return(0);
1047: }

1051: /*@
1052:    MatDestroy - Frees space taken by a matrix.

1054:    Collective on Mat

1056:    Input Parameter:
1057: .  A - the matrix

1059:    Level: beginner

1061: @*/
1062: PetscErrorCode  MatDestroy(Mat *A)
1063: {

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

1071:   /* if memory was published with SAWs then destroy it */
1072:   PetscObjectSAWsViewOff((PetscObject)*A);
1073:   if ((*A)->ops->destroy) {
1074:     (*(*A)->ops->destroy)(*A);
1075:   }
1076:   MatDestroy_Redundant(&(*A)->redundant);
1077:   MatNullSpaceDestroy(&(*A)->nullsp);
1078:   MatNullSpaceDestroy(&(*A)->nearnullsp);
1079:   PetscLayoutDestroy(&(*A)->rmap);
1080:   PetscLayoutDestroy(&(*A)->cmap);
1081:   PetscHeaderDestroy(A);
1082:   return(0);
1083: }

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

1092:    Not Collective

1094:    Input Parameters:
1095: +  mat - the matrix
1096: .  v - a logically two-dimensional array of values
1097: .  m, idxm - the number of rows and their global indices
1098: .  n, idxn - the number of columns and their global indices
1099: -  addv - either ADD_VALUES or INSERT_VALUES, where
1100:    ADD_VALUES adds values to any existing entries, and
1101:    INSERT_VALUES replaces existing entries with new values

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

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

1109:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1110:    options cannot be mixed without intervening calls to the assembly
1111:    routines.

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

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

1121:    Efficiency Alert:
1122:    The routine MatSetValuesBlocked() may offer much better efficiency
1123:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1125:    Level: beginner

1127:    Concepts: matrices^putting entries in

1129: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1130:           InsertMode, INSERT_VALUES, ADD_VALUES
1131: @*/
1132: PetscErrorCode  MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1133: {
1135: #if defined(PETSC_USE_DEBUG)
1136:   PetscInt       i,j;
1137: #endif

1142:   if (!m || !n) return(0); /* no values to insert */
1146:   MatCheckPreallocated(mat,1);
1147:   if (mat->insertmode == NOT_SET_VALUES) {
1148:     mat->insertmode = addv;
1149:   }
1150: #if defined(PETSC_USE_DEBUG)
1151:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1152:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1153:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);

1155:   for (i=0; i<m; i++) {
1156:     for (j=0; j<n; j++) {
1157:       if (PetscIsInfOrNanScalar(v[i*n+j]))
1158: #if defined(PETSC_USE_COMPLEX)
1159:         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]);
1160: #else
1161:       SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1162: #endif
1163:     }
1164:   }
1165: #endif

1167:   if (mat->assembled) {
1168:     mat->was_assembled = PETSC_TRUE;
1169:     mat->assembled     = PETSC_FALSE;
1170:   }
1171:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1172:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1173:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1174: #if defined(PETSC_HAVE_CUSP)
1175:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1176:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1177:   }
1178: #endif
1179: #if defined(PETSC_HAVE_VIENNACL)
1180:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1181:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1182:   }
1183: #endif
1184:   return(0);
1185: }


1190: /*@
1191:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1192:         values into a matrix

1194:    Not Collective

1196:    Input Parameters:
1197: +  mat - the matrix
1198: .  row - the (block) row to set
1199: -  v - a logically two-dimensional array of values

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

1204:    All the nonzeros in the row must be provided

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

1208:    The row must belong to this process

1210:    Level: intermediate

1212:    Concepts: matrices^putting entries in

1214: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1215:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1216: @*/
1217: PetscErrorCode  MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1218: {
1220:   PetscInt       globalrow;

1226:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1227:   MatSetValuesRow(mat,globalrow,v);
1228: #if defined(PETSC_HAVE_CUSP)
1229:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1230:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1231:   }
1232: #endif
1233: #if defined(PETSC_HAVE_VIENNACL)
1234:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1235:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1236:   }
1237: #endif
1238:   return(0);
1239: }

1243: /*@
1244:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1245:         values into a matrix

1247:    Not Collective

1249:    Input Parameters:
1250: +  mat - the matrix
1251: .  row - the (block) row to set
1252: -  v - a logically two-dimensional array of values

1254:    Notes:
1255:    The values, v, are column-oriented for the block version.

1257:    All the nonzeros in the row must be provided

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

1261:    The row must belong to this process

1263:    Level: advanced

1265:    Concepts: matrices^putting entries in

1267: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1268:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1269: @*/
1270: PetscErrorCode  MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1271: {

1277:   MatCheckPreallocated(mat,1);
1279: #if defined(PETSC_USE_DEBUG)
1280:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1281:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1282: #endif
1283:   mat->insertmode = INSERT_VALUES;

1285:   if (mat->assembled) {
1286:     mat->was_assembled = PETSC_TRUE;
1287:     mat->assembled     = PETSC_FALSE;
1288:   }
1289:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1290:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1291:   (*mat->ops->setvaluesrow)(mat,row,v);
1292:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1293: #if defined(PETSC_HAVE_CUSP)
1294:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1295:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1296:   }
1297: #endif
1298: #if defined(PETSC_HAVE_VIENNACL)
1299:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1300:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1301:   }
1302: #endif
1303:   return(0);
1304: }

1308: /*@
1309:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1310:      Using structured grid indexing

1312:    Not Collective

1314:    Input Parameters:
1315: +  mat - the matrix
1316: .  m - number of rows being entered
1317: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1318: .  n - number of columns being entered
1319: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1320: .  v - a logically two-dimensional array of values
1321: -  addv - either ADD_VALUES or INSERT_VALUES, where
1322:    ADD_VALUES adds values to any existing entries, and
1323:    INSERT_VALUES replaces existing entries with new values

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

1328:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1329:    options cannot be mixed without intervening calls to the assembly
1330:    routines.

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

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

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

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

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

1348:    In Fortran idxm and idxn should be declared as
1349: $     MatStencil idxm(4,m),idxn(4,n)
1350:    and the values inserted using
1351: $    idxm(MatStencil_i,1) = i
1352: $    idxm(MatStencil_j,1) = j
1353: $    idxm(MatStencil_k,1) = k
1354: $    idxm(MatStencil_c,1) = c
1355:    etc

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

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

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

1368:    Efficiency Alert:
1369:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1370:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1372:    Level: beginner

1374:    Concepts: matrices^putting entries in

1376: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1377:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1378: @*/
1379: PetscErrorCode  MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1380: {
1382:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1383:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1384:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1394:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1395:     jdxm = buf; jdxn = buf+m;
1396:   } else {
1397:     PetscMalloc2(m,&bufm,n,&bufn);
1398:     jdxm = bufm; jdxn = bufn;
1399:   }
1400:   for (i=0; i<m; i++) {
1401:     for (j=0; j<3-sdim; j++) dxm++;
1402:     tmp = *dxm++ - starts[0];
1403:     for (j=0; j<dim-1; j++) {
1404:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1405:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1406:     }
1407:     if (mat->stencil.noc) dxm++;
1408:     jdxm[i] = tmp;
1409:   }
1410:   for (i=0; i<n; i++) {
1411:     for (j=0; j<3-sdim; j++) dxn++;
1412:     tmp = *dxn++ - starts[0];
1413:     for (j=0; j<dim-1; j++) {
1414:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1415:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1416:     }
1417:     if (mat->stencil.noc) dxn++;
1418:     jdxn[i] = tmp;
1419:   }
1420:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1421:   PetscFree2(bufm,bufn);
1422:   return(0);
1423: }

1427: /*@
1428:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1429:      Using structured grid indexing

1431:    Not Collective

1433:    Input Parameters:
1434: +  mat - the matrix
1435: .  m - number of rows being entered
1436: .  idxm - grid coordinates for matrix rows being entered
1437: .  n - number of columns being entered
1438: .  idxn - grid coordinates for matrix columns being entered
1439: .  v - a logically two-dimensional array of values
1440: -  addv - either ADD_VALUES or INSERT_VALUES, where
1441:    ADD_VALUES adds values to any existing entries, and
1442:    INSERT_VALUES replaces existing entries with new values

1444:    Notes:
1445:    By default the values, v, are row-oriented and unsorted.
1446:    See MatSetOption() for other options.

1448:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1449:    options cannot be mixed without intervening calls to the assembly
1450:    routines.

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

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

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

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

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

1468:    In Fortran idxm and idxn should be declared as
1469: $     MatStencil idxm(4,m),idxn(4,n)
1470:    and the values inserted using
1471: $    idxm(MatStencil_i,1) = i
1472: $    idxm(MatStencil_j,1) = j
1473: $    idxm(MatStencil_k,1) = k
1474:    etc

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

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

1484:    Level: beginner

1486:    Concepts: matrices^putting entries in

1488: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1489:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1490:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1491: @*/
1492: PetscErrorCode  MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1493: {
1495:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1496:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1497:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1507:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1508:     jdxm = buf; jdxn = buf+m;
1509:   } else {
1510:     PetscMalloc2(m,&bufm,n,&bufn);
1511:     jdxm = bufm; jdxn = bufn;
1512:   }
1513:   for (i=0; i<m; i++) {
1514:     for (j=0; j<3-sdim; j++) dxm++;
1515:     tmp = *dxm++ - starts[0];
1516:     for (j=0; j<sdim-1; j++) {
1517:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1518:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1519:     }
1520:     dxm++;
1521:     jdxm[i] = tmp;
1522:   }
1523:   for (i=0; i<n; i++) {
1524:     for (j=0; j<3-sdim; j++) dxn++;
1525:     tmp = *dxn++ - starts[0];
1526:     for (j=0; j<sdim-1; j++) {
1527:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1528:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1529:     }
1530:     dxn++;
1531:     jdxn[i] = tmp;
1532:   }
1533:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1534:   PetscFree2(bufm,bufn);
1535: #if defined(PETSC_HAVE_CUSP)
1536:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1537:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1538:   }
1539: #endif
1540: #if defined(PETSC_HAVE_VIENNACL)
1541:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1542:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1543:   }
1544: #endif
1545:   return(0);
1546: }

1550: /*@
1551:    MatSetStencil - Sets the grid information for setting values into a matrix via
1552:         MatSetValuesStencil()

1554:    Not Collective

1556:    Input Parameters:
1557: +  mat - the matrix
1558: .  dim - dimension of the grid 1, 2, or 3
1559: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1560: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1561: -  dof - number of degrees of freedom per node


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

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

1570:    Level: beginner

1572:    Concepts: matrices^putting entries in

1574: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1575:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1576: @*/
1577: PetscErrorCode  MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1578: {
1579:   PetscInt i;


1586:   mat->stencil.dim = dim + (dof > 1);
1587:   for (i=0; i<dim; i++) {
1588:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1589:     mat->stencil.starts[i] = starts[dim-i-1];
1590:   }
1591:   mat->stencil.dims[dim]   = dof;
1592:   mat->stencil.starts[dim] = 0;
1593:   mat->stencil.noc         = (PetscBool)(dof == 1);
1594:   return(0);
1595: }

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

1602:    Not Collective

1604:    Input Parameters:
1605: +  mat - the matrix
1606: .  v - a logically two-dimensional array of values
1607: .  m, idxm - the number of block rows and their global block indices
1608: .  n, idxn - the number of block columns and their global block indices
1609: -  addv - either ADD_VALUES or INSERT_VALUES, where
1610:    ADD_VALUES adds values to any existing entries, and
1611:    INSERT_VALUES replaces existing entries with new values

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

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

1623:    Note that you must call MatSetBlockSize() when constructing this matrix (before
1624:    preallocating it).

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

1629:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1630:    options cannot be mixed without intervening calls to the assembly
1631:    routines.

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

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

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

1647:    Example:
1648: $   Suppose m=n=2 and block size(bs) = 2 The array is
1649: $
1650: $   1  2  | 3  4
1651: $   5  6  | 7  8
1652: $   - - - | - - -
1653: $   9  10 | 11 12
1654: $   13 14 | 15 16
1655: $
1656: $   v[] should be passed in like
1657: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1658: $
1659: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1660: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

1662:    Level: intermediate

1664:    Concepts: matrices^putting entries in blocked

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

1675:   if (!m || !n) return(0); /* no values to insert */
1679:   MatCheckPreallocated(mat,1);
1680:   if (mat->insertmode == NOT_SET_VALUES) {
1681:     mat->insertmode = addv;
1682:   }
1683: #if defined(PETSC_USE_DEBUG)
1684:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1685:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1686:   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1687: #endif

1689:   if (mat->assembled) {
1690:     mat->was_assembled = PETSC_TRUE;
1691:     mat->assembled     = PETSC_FALSE;
1692:   }
1693:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1694:   if (mat->ops->setvaluesblocked) {
1695:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1696:   } else {
1697:     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1698:     PetscInt i,j,bs,cbs;
1699:     MatGetBlockSizes(mat,&bs,&cbs);
1700:     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1701:       iidxm = buf; iidxn = buf + m*bs;
1702:     } else {
1703:       PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1704:       iidxm = bufr; iidxn = bufc;
1705:     }
1706:     for (i=0; i<m; i++) {
1707:       for (j=0; j<bs; j++) {
1708:         iidxm[i*bs+j] = bs*idxm[i] + j;
1709:       }
1710:     }
1711:     for (i=0; i<n; i++) {
1712:       for (j=0; j<cbs; j++) {
1713:         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1714:       }
1715:     }
1716:     MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1717:     PetscFree2(bufr,bufc);
1718:   }
1719:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1720: #if defined(PETSC_HAVE_CUSP)
1721:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1722:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1723:   }
1724: #endif
1725: #if defined(PETSC_HAVE_VIENNACL)
1726:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1727:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1728:   }
1729: #endif
1730:   return(0);
1731: }

1735: /*@
1736:    MatGetValues - Gets a block of values from a matrix.

1738:    Not Collective; currently only returns a local block

1740:    Input Parameters:
1741: +  mat - the matrix
1742: .  v - a logically two-dimensional array for storing the values
1743: .  m, idxm - the number of rows and their global indices
1744: -  n, idxn - the number of columns and their global indices

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

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

1754:    MatGetValues() requires that the matrix has been assembled
1755:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1756:    MatSetValues() and MatGetValues() CANNOT be made in succession
1757:    without intermediate matrix assembly.

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

1762:    Level: advanced

1764:    Concepts: matrices^accessing values

1766: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1767: @*/
1768: PetscErrorCode  MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1769: {

1775:   if (!m || !n) return(0);
1779:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1780:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1781:   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1782:   MatCheckPreallocated(mat,1);

1784:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1785:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1786:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1787:   return(0);
1788: }

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

1796:   Not Collective

1798:   Input Parameters:
1799: + mat - the matrix
1800: . nb - the number of blocks
1801: . bs - the number of rows (and columns) in each block
1802: . rows - a concatenation of the rows for each block
1803: - v - a concatenation of logically two-dimensional arrays of values

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

1808:   Level: advanced

1810:   Concepts: matrices^putting entries in

1812: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1813:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1814: @*/
1815: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1816: {

1824: #if defined(PETSC_USE_DEBUG)
1825:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1826: #endif

1828:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1829:   if (mat->ops->setvaluesbatch) {
1830:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1831:   } else {
1832:     PetscInt b;
1833:     for (b = 0; b < nb; ++b) {
1834:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1835:     }
1836:   }
1837:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1838:   return(0);
1839: }

1843: /*@
1844:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1845:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1846:    using a local (per-processor) numbering.

1848:    Not Collective

1850:    Input Parameters:
1851: +  x - the matrix
1852: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1853: - cmapping - column mapping

1855:    Level: intermediate

1857:    Concepts: matrices^local to global mapping
1858:    Concepts: local to global mapping^for matrices

1860: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1861: @*/
1862: PetscErrorCode  MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1863: {


1872:   if (x->ops->setlocaltoglobalmapping) {
1873:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1874:   } else {
1875:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1876:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1877:   }
1878:   return(0);
1879: }


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

1887:    Not Collective

1889:    Input Parameters:
1890: .  A - the matrix

1892:    Output Parameters:
1893: + rmapping - row mapping
1894: - cmapping - column mapping

1896:    Level: advanced

1898:    Concepts: matrices^local to global mapping
1899:    Concepts: local to global mapping^for matrices

1901: .seealso:  MatSetValuesLocal()
1902: @*/
1903: PetscErrorCode  MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1904: {
1910:   if (rmapping) *rmapping = A->rmap->mapping;
1911:   if (cmapping) *cmapping = A->cmap->mapping;
1912:   return(0);
1913: }

1917: /*@
1918:    MatGetLayouts - Gets the PetscLayout objects for rows and columns

1920:    Not Collective

1922:    Input Parameters:
1923: .  A - the matrix

1925:    Output Parameters:
1926: + rmap - row layout
1927: - cmap - column layout

1929:    Level: advanced

1931: .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
1932: @*/
1933: PetscErrorCode  MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1934: {
1940:   if (rmap) *rmap = A->rmap;
1941:   if (cmap) *cmap = A->cmap;
1942:   return(0);
1943: }

1947: /*@
1948:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1949:    using a local ordering of the nodes.

1951:    Not Collective

1953:    Input Parameters:
1954: +  x - the matrix
1955: .  nrow, irow - number of rows and their local indices
1956: .  ncol, icol - number of columns and their local indices
1957: .  y -  a logically two-dimensional array of values
1958: -  addv - either INSERT_VALUES or ADD_VALUES, where
1959:    ADD_VALUES adds values to any existing entries, and
1960:    INSERT_VALUES replaces existing entries with new values

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

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

1968:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1969:    options cannot be mixed without intervening calls to the assembly
1970:    routines.

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

1975:    Level: intermediate

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

1979: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1980:            MatSetValueLocal()
1981: @*/
1982: PetscErrorCode  MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1983: {

1989:   MatCheckPreallocated(mat,1);
1990:   if (!nrow || !ncol) return(0); /* no values to insert */
1994:   if (mat->insertmode == NOT_SET_VALUES) {
1995:     mat->insertmode = addv;
1996:   }
1997: #if defined(PETSC_USE_DEBUG)
1998:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1999:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2000:   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2001: #endif

2003:   if (mat->assembled) {
2004:     mat->was_assembled = PETSC_TRUE;
2005:     mat->assembled     = PETSC_FALSE;
2006:   }
2007:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2008:   if (mat->ops->setvalueslocal) {
2009:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
2010:   } else {
2011:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2012:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2013:       irowm = buf; icolm = buf+nrow;
2014:     } else {
2015:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2016:       irowm = bufr; icolm = bufc;
2017:     }
2018:     ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
2019:     ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
2020:     MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
2021:     PetscFree2(bufr,bufc);
2022:   }
2023:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2024: #if defined(PETSC_HAVE_CUSP)
2025:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2026:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2027:   }
2028: #endif
2029: #if defined(PETSC_HAVE_VIENNACL)
2030:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2031:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2032:   }
2033: #endif
2034:   return(0);
2035: }

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

2043:    Not Collective

2045:    Input Parameters:
2046: +  x - the matrix
2047: .  nrow, irow - number of rows and their local indices
2048: .  ncol, icol - number of columns and their local indices
2049: .  y -  a logically two-dimensional array of values
2050: -  addv - either INSERT_VALUES or ADD_VALUES, where
2051:    ADD_VALUES adds values to any existing entries, and
2052:    INSERT_VALUES replaces existing entries with new values

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

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

2061:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2062:    options cannot be mixed without intervening calls to the assembly
2063:    routines.

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

2068:    Level: intermediate

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

2072: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2073:            MatSetValuesLocal(),  MatSetValuesBlocked()
2074: @*/
2075: PetscErrorCode  MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2076: {

2082:   MatCheckPreallocated(mat,1);
2083:   if (!nrow || !ncol) return(0); /* no values to insert */
2087:   if (mat->insertmode == NOT_SET_VALUES) {
2088:     mat->insertmode = addv;
2089:   }
2090: #if defined(PETSC_USE_DEBUG)
2091:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2092:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2093:   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);
2094: #endif

2096:   if (mat->assembled) {
2097:     mat->was_assembled = PETSC_TRUE;
2098:     mat->assembled     = PETSC_FALSE;
2099:   }
2100:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2101:   if (mat->ops->setvaluesblockedlocal) {
2102:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2103:   } else {
2104:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2105:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2106:       irowm = buf; icolm = buf + nrow;
2107:     } else {
2108:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2109:       irowm = bufr; icolm = bufc;
2110:     }
2111:     ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2112:     ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2113:     MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2114:     PetscFree2(bufr,bufc);
2115:   }
2116:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2117: #if defined(PETSC_HAVE_CUSP)
2118:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2119:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2120:   }
2121: #endif
2122: #if defined(PETSC_HAVE_VIENNACL)
2123:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2124:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2125:   }
2126: #endif
2127:   return(0);
2128: }

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

2135:    Collective on Mat and Vec

2137:    Input Parameters:
2138: +  mat - the matrix
2139: -  x   - the vector to be multiplied

2141:    Output Parameters:
2142: .  y - the result

2144:    Notes:
2145:    The vectors x and y cannot be the same.  I.e., one cannot
2146:    call MatMult(A,y,y).

2148:    Level: developer

2150:    Concepts: matrix-vector product

2152: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2153: @*/
2154: PetscErrorCode  MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2155: {


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

2169:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2170:   (*mat->ops->multdiagonalblock)(mat,x,y);
2171:   PetscObjectStateIncrease((PetscObject)y);
2172:   return(0);
2173: }

2175: /* --------------------------------------------------------*/
2178: /*@
2179:    MatMult - Computes the matrix-vector product, y = Ax.

2181:    Neighbor-wise Collective on Mat and Vec

2183:    Input Parameters:
2184: +  mat - the matrix
2185: -  x   - the vector to be multiplied

2187:    Output Parameters:
2188: .  y - the result

2190:    Notes:
2191:    The vectors x and y cannot be the same.  I.e., one cannot
2192:    call MatMult(A,y,y).

2194:    Level: beginner

2196:    Concepts: matrix-vector product

2198: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2199: @*/
2200: PetscErrorCode  MatMult(Mat mat,Vec x,Vec y)
2201: {

2209:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2210:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2211:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2212: #if !defined(PETSC_HAVE_CONSTRAINTS)
2213:   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);
2214:   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);
2215:   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);
2216: #endif
2217:   VecLocked(y,3);
2218:   VecValidValues(x,2,PETSC_TRUE);
2219:   MatCheckPreallocated(mat,1);

2221:   VecLockPush(x);
2222:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2223:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2224:   (*mat->ops->mult)(mat,x,y);
2225:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2226:   VecValidValues(y,3,PETSC_FALSE);
2227:   VecLockPop(x);
2228:   return(0);
2229: }

2233: /*@
2234:    MatMultTranspose - Computes matrix transpose times a vector.

2236:    Neighbor-wise Collective on Mat and Vec

2238:    Input Parameters:
2239: +  mat - the matrix
2240: -  x   - the vector to be multilplied

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

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

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

2252:    Level: beginner

2254:    Concepts: matrix vector product^transpose

2256: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2257: @*/
2258: PetscErrorCode  MatMultTranspose(Mat mat,Vec x,Vec y)
2259: {


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

2278:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2279:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2280:   VecLockPush(x);
2281:   (*mat->ops->multtranspose)(mat,x,y);
2282:   VecLockPop(x);
2283:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2284:   PetscObjectStateIncrease((PetscObject)y);
2285:   VecValidValues(y,3,PETSC_FALSE);
2286:   return(0);
2287: }

2291: /*@
2292:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2294:    Neighbor-wise Collective on Mat and Vec

2296:    Input Parameters:
2297: +  mat - the matrix
2298: -  x   - the vector to be multilplied

2300:    Output Parameters:
2301: .  y - the result

2303:    Notes:
2304:    The vectors x and y cannot be the same.  I.e., one cannot
2305:    call MatMultHermitianTranspose(A,y,y).

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

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

2311:    Level: beginner

2313:    Concepts: matrix vector product^transpose

2315: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2316: @*/
2317: PetscErrorCode  MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2318: {
2320:   Vec            w;


2328:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2329:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2330:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2331: #if !defined(PETSC_HAVE_CONSTRAINTS)
2332:   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);
2333:   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);
2334: #endif
2335:   MatCheckPreallocated(mat,1);

2337:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2338:   if (mat->ops->multhermitiantranspose) {
2339:     VecLockPush(x);
2340:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2341:     VecLockPop(x);
2342:   } else {
2343:     VecDuplicate(x,&w);
2344:     VecCopy(x,w);
2345:     VecConjugate(w);
2346:     MatMultTranspose(mat,w,y);
2347:     VecDestroy(&w);
2348:     VecConjugate(y);
2349:   }
2350:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2351:   PetscObjectStateIncrease((PetscObject)y);
2352:   return(0);
2353: }

2357: /*@
2358:     MatMultAdd -  Computes v3 = v2 + A * v1.

2360:     Neighbor-wise Collective on Mat and Vec

2362:     Input Parameters:
2363: +   mat - the matrix
2364: -   v1, v2 - the vectors

2366:     Output Parameters:
2367: .   v3 - the result

2369:     Notes:
2370:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2371:     call MatMultAdd(A,v1,v2,v1).

2373:     Level: beginner

2375:     Concepts: matrix vector product^addition

2377: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2378: @*/
2379: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2380: {


2390:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2391:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2392:   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);
2393:   /* 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);
2394:      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); */
2395:   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);
2396:   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);
2397:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2398:   MatCheckPreallocated(mat,1);

2400:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2401:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2402:   VecLockPush(v1);
2403:   (*mat->ops->multadd)(mat,v1,v2,v3);
2404:   VecLockPop(v1);
2405:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2406:   PetscObjectStateIncrease((PetscObject)v3);
2407:   return(0);
2408: }

2412: /*@
2413:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2415:    Neighbor-wise Collective on Mat and Vec

2417:    Input Parameters:
2418: +  mat - the matrix
2419: -  v1, v2 - the vectors

2421:    Output Parameters:
2422: .  v3 - the result

2424:    Notes:
2425:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2426:    call MatMultTransposeAdd(A,v1,v2,v1).

2428:    Level: beginner

2430:    Concepts: matrix vector product^transpose and addition

2432: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2433: @*/
2434: PetscErrorCode  MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2435: {


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

2454:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2455:   VecLockPush(v1);
2456:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2457:   VecLockPop(v1);
2458:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2459:   PetscObjectStateIncrease((PetscObject)v3);
2460:   return(0);
2461: }

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

2468:    Neighbor-wise Collective on Mat and Vec

2470:    Input Parameters:
2471: +  mat - the matrix
2472: -  v1, v2 - the vectors

2474:    Output Parameters:
2475: .  v3 - the result

2477:    Notes:
2478:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2479:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2481:    Level: beginner

2483:    Concepts: matrix vector product^transpose and addition

2485: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2486: @*/
2487: PetscErrorCode  MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2488: {


2498:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2499:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2500:   if (!mat->ops->multhermitiantransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2501:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2502:   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);
2503:   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);
2504:   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);
2505:   MatCheckPreallocated(mat,1);

2507:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2508:   VecLockPush(v1);
2509:   (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2510:   VecLockPop(v1);
2511:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2512:   PetscObjectStateIncrease((PetscObject)v3);
2513:   return(0);
2514: }

2518: /*@
2519:    MatMultConstrained - The inner multiplication routine for a
2520:    constrained matrix P^T A P.

2522:    Neighbor-wise Collective on Mat and Vec

2524:    Input Parameters:
2525: +  mat - the matrix
2526: -  x   - the vector to be multilplied

2528:    Output Parameters:
2529: .  y - the result

2531:    Notes:
2532:    The vectors x and y cannot be the same.  I.e., one cannot
2533:    call MatMult(A,y,y).

2535:    Level: beginner

2537: .keywords: matrix, multiply, matrix-vector product, constraint
2538: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2539: @*/
2540: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
2541: {

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

2555:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2556:   VecLockPush(x);
2557:   (*mat->ops->multconstrained)(mat,x,y);
2558:   VecLockPop(x);
2559:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2560:   PetscObjectStateIncrease((PetscObject)y);
2561:   return(0);
2562: }

2566: /*@
2567:    MatMultTransposeConstrained - The inner multiplication routine for a
2568:    constrained matrix P^T A^T P.

2570:    Neighbor-wise Collective on Mat and Vec

2572:    Input Parameters:
2573: +  mat - the matrix
2574: -  x   - the vector to be multilplied

2576:    Output Parameters:
2577: .  y - the result

2579:    Notes:
2580:    The vectors x and y cannot be the same.  I.e., one cannot
2581:    call MatMult(A,y,y).

2583:    Level: beginner

2585: .keywords: matrix, multiply, matrix-vector product, constraint
2586: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2587: @*/
2588: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2589: {

2596:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2597:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2598:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2599:   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);
2600:   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);

2602:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2603:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2604:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2605:   PetscObjectStateIncrease((PetscObject)y);
2606:   return(0);
2607: }

2611: /*@C
2612:    MatGetFactorType - gets the type of factorization it is

2614:    Note Collective
2615:    as the flag

2617:    Input Parameters:
2618: .  mat - the matrix

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

2623:     Level: intermediate

2625: .seealso:    MatFactorType, MatGetFactor()
2626: @*/
2627: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
2628: {
2632:   *t = mat->factortype;
2633:   return(0);
2634: }

2636: /* ------------------------------------------------------------*/
2639: /*@C
2640:    MatGetInfo - Returns information about matrix storage (number of
2641:    nonzeros, memory, etc.).

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

2645:    Input Parameters:
2646: .  mat - the matrix

2648:    Output Parameters:
2649: +  flag - flag indicating the type of parameters to be returned
2650:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2651:    MAT_GLOBAL_SUM - sum over all processors)
2652: -  info - matrix information context

2654:    Notes:
2655:    The MatInfo context contains a variety of matrix data, including
2656:    number of nonzeros allocated and used, number of mallocs during
2657:    matrix assembly, etc.  Additional information for factored matrices
2658:    is provided (such as the fill ratio, number of mallocs during
2659:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2660:    when using the runtime options
2661: $       -info -mat_view ::ascii_info

2663:    Example for C/C++ Users:
2664:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2665:    data within the MatInfo context.  For example,
2666: .vb
2667:       MatInfo info;
2668:       Mat     A;
2669:       double  mal, nz_a, nz_u;

2671:       MatGetInfo(A,MAT_LOCAL,&info);
2672:       mal  = info.mallocs;
2673:       nz_a = info.nz_allocated;
2674: .ve

2676:    Example for Fortran Users:
2677:    Fortran users should declare info as a double precision
2678:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2679:    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2680:    a complete list of parameter names.
2681: .vb
2682:       double  precision info(MAT_INFO_SIZE)
2683:       double  precision mal, nz_a
2684:       Mat     A
2685:       integer ierr

2687:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2688:       mal = info(MAT_INFO_MALLOCS)
2689:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2690: .ve

2692:     Level: intermediate

2694:     Concepts: matrices^getting information on

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

2699: .seealso: MatStashGetInfo()

2701: @*/
2702: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2703: {

2710:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2711:   MatCheckPreallocated(mat,1);
2712:   (*mat->ops->getinfo)(mat,flag,info);
2713:   return(0);
2714: }

2716: /* ----------------------------------------------------------*/

2720: /*@C
2721:    MatLUFactor - Performs in-place LU factorization of matrix.

2723:    Collective on Mat

2725:    Input Parameters:
2726: +  mat - the matrix
2727: .  row - row permutation
2728: .  col - column permutation
2729: -  info - options for factorization, includes
2730: $          fill - expected fill as ratio of original fill.
2731: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2732: $                   Run with the option -info to determine an optimal value to use

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

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

2742:    Level: developer

2744:    Concepts: matrices^LU factorization

2746: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2747:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2752: @*/
2753: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2754: {
2756:   MatFactorInfo  tinfo;

2764:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2765:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2766:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2767:   MatCheckPreallocated(mat,1);
2768:   if (!info) {
2769:     MatFactorInfoInitialize(&tinfo);
2770:     info = &tinfo;
2771:   }

2773:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2774:   (*mat->ops->lufactor)(mat,row,col,info);
2775:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2776:   PetscObjectStateIncrease((PetscObject)mat);
2777:   return(0);
2778: }

2782: /*@C
2783:    MatILUFactor - Performs in-place ILU factorization of matrix.

2785:    Collective on Mat

2787:    Input Parameters:
2788: +  mat - the matrix
2789: .  row - row permutation
2790: .  col - column permutation
2791: -  info - structure containing
2792: $      levels - number of levels of fill.
2793: $      expected fill - as ratio of original fill.
2794: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2795:                 missing diagonal entries)

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

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

2805:    Level: developer

2807:    Concepts: matrices^ILU factorization

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

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

2814: @*/
2815: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2816: {

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

2831:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2832:   (*mat->ops->ilufactor)(mat,row,col,info);
2833:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2834:   PetscObjectStateIncrease((PetscObject)mat);
2835:   return(0);
2836: }

2840: /*@C
2841:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2842:    Call this routine before calling MatLUFactorNumeric().

2844:    Collective on Mat

2846:    Input Parameters:
2847: +  fact - the factor matrix obtained with MatGetFactor()
2848: .  mat - the matrix
2849: .  row, col - row and column permutations
2850: -  info - options for factorization, includes
2851: $          fill - expected fill as ratio of original fill.
2852: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2853: $                   Run with the option -info to determine an optimal value to use


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

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

2862:    Level: developer

2864:    Concepts: matrices^LU symbolic factorization

2866: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()

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

2871: @*/
2872: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2873: {

2883:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2884:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2885:   if (!(fact)->ops->lufactorsymbolic) {
2886:     const MatSolverPackage spackage;
2887:     MatFactorGetSolverPackage(fact,&spackage);
2888:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2889:   }
2890:   MatCheckPreallocated(mat,2);

2892:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2893:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2894:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2895:   PetscObjectStateIncrease((PetscObject)fact);
2896:   return(0);
2897: }

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

2905:    Collective on Mat

2907:    Input Parameters:
2908: +  fact - the factor matrix obtained with MatGetFactor()
2909: .  mat - the matrix
2910: -  info - options for factorization

2912:    Notes:
2913:    See MatLUFactor() for in-place factorization.  See
2914:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

2920:    Level: developer

2922:    Concepts: matrices^LU numeric factorization

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

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

2929: @*/
2930: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2931: {

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

2942:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2943:   MatCheckPreallocated(mat,2);
2944:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2945:   (fact->ops->lufactornumeric)(fact,mat,info);
2946:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2947:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
2948:   PetscObjectStateIncrease((PetscObject)fact);
2949:   return(0);
2950: }

2954: /*@C
2955:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2956:    symmetric matrix.

2958:    Collective on Mat

2960:    Input Parameters:
2961: +  mat - the matrix
2962: .  perm - row and column permutations
2963: -  f - expected fill as ratio of original fill

2965:    Notes:
2966:    See MatLUFactor() for the nonsymmetric case.  See also
2967:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

2973:    Level: developer

2975:    Concepts: matrices^Cholesky factorization

2977: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2978:           MatGetOrdering()

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

2983: @*/
2984: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2985: {

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

2999:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3000:   (*mat->ops->choleskyfactor)(mat,perm,info);
3001:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3002:   PetscObjectStateIncrease((PetscObject)mat);
3003:   return(0);
3004: }

3008: /*@C
3009:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3010:    of a symmetric matrix.

3012:    Collective on Mat

3014:    Input Parameters:
3015: +  fact - the factor matrix obtained with MatGetFactor()
3016: .  mat - the matrix
3017: .  perm - row and column permutations
3018: -  info - options for factorization, includes
3019: $          fill - expected fill as ratio of original fill.
3020: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3021: $                   Run with the option -info to determine an optimal value to use

3023:    Notes:
3024:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3025:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

3031:    Level: developer

3033:    Concepts: matrices^Cholesky symbolic factorization

3035: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3036:           MatGetOrdering()

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

3041: @*/
3042: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3043: {

3052:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3053:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3054:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3055:   if (!(fact)->ops->choleskyfactorsymbolic) {
3056:     const MatSolverPackage spackage;
3057:     MatFactorGetSolverPackage(fact,&spackage);
3058:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3059:   }
3060:   MatCheckPreallocated(mat,2);

3062:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3063:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3064:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3065:   PetscObjectStateIncrease((PetscObject)fact);
3066:   return(0);
3067: }

3071: /*@C
3072:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3073:    of a symmetric matrix. Call this routine after first calling
3074:    MatCholeskyFactorSymbolic().

3076:    Collective on Mat

3078:    Input Parameters:
3079: +  fact - the factor matrix obtained with MatGetFactor()
3080: .  mat - the initial matrix
3081: .  info - options for factorization
3082: -  fact - the symbolic factor of mat


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

3090:    Level: developer

3092:    Concepts: matrices^Cholesky numeric factorization

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

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

3099: @*/
3100: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3101: {

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

3114:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3115:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3116:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3117:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3118:   PetscObjectStateIncrease((PetscObject)fact);
3119:   return(0);
3120: }

3122: /* ----------------------------------------------------------------*/
3125: /*@
3126:    MatSolve - Solves A x = b, given a factored matrix.

3128:    Neighbor-wise Collective on Mat and Vec

3130:    Input Parameters:
3131: +  mat - the factored matrix
3132: -  b - the right-hand-side vector

3134:    Output Parameter:
3135: .  x - the result vector

3137:    Notes:
3138:    The vectors b and x cannot be the same.  I.e., one cannot
3139:    call MatSolve(A,x,x).

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

3146:    Level: developer

3148:    Concepts: matrices^triangular solves

3150: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3151: @*/
3152: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
3153: {

3163:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3164:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3165:   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);
3166:   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);
3167:   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);
3168:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3169:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3170:   MatCheckPreallocated(mat,1);

3172:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3173:   (*mat->ops->solve)(mat,b,x);
3174:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3175:   PetscObjectStateIncrease((PetscObject)x);
3176:   return(0);
3177: }

3181: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
3182: {
3184:   Vec            b,x;
3185:   PetscInt       m,N,i;
3186:   PetscScalar    *bb,*xx;
3187:   PetscBool      flg;

3190:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3191:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3192:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3193:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3195:   MatDenseGetArray(B,&bb);
3196:   MatDenseGetArray(X,&xx);
3197:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3198:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3199:   MatCreateVecs(A,&x,&b);
3200:   for (i=0; i<N; i++) {
3201:     VecPlaceArray(b,bb + i*m);
3202:     VecPlaceArray(x,xx + i*m);
3203:     MatSolve(A,b,x);
3204:     VecResetArray(x);
3205:     VecResetArray(b);
3206:   }
3207:   VecDestroy(&b);
3208:   VecDestroy(&x);
3209:   MatDenseRestoreArray(B,&bb);
3210:   MatDenseRestoreArray(X,&xx);
3211:   return(0);
3212: }

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

3219:    Neighbor-wise Collective on Mat

3221:    Input Parameters:
3222: +  mat - the factored matrix
3223: -  B - the right-hand-side matrix  (dense matrix)

3225:    Output Parameter:
3226: .  X - the result matrix (dense matrix)

3228:    Notes:
3229:    The matrices b and x cannot be the same.  I.e., one cannot
3230:    call MatMatSolve(A,x,x).

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

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

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

3243:    Level: developer

3245:    Concepts: matrices^triangular solves

3247: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3248: @*/
3249: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
3250: {

3260:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3261:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3262:   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);
3263:   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);
3264:   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);
3265:   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3266:   if (!A->rmap->N && !A->cmap->N) return(0);
3267:   MatCheckPreallocated(A,1);

3269:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3270:   if (!A->ops->matsolve) {
3271:     PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3272:     MatMatSolve_Basic(A,B,X);
3273:   } else {
3274:     (*A->ops->matsolve)(A,B,X);
3275:   }
3276:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3277:   PetscObjectStateIncrease((PetscObject)X);
3278:   return(0);
3279: }


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

3288:    Neighbor-wise Collective on Mat and Vec

3290:    Input Parameters:
3291: +  mat - the factored matrix
3292: -  b - the right-hand-side vector

3294:    Output Parameter:
3295: .  x - the result vector

3297:    Notes:
3298:    MatSolve() should be used for most applications, as it performs
3299:    a forward solve followed by a backward solve.

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

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

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

3314:    Level: developer

3316:    Concepts: matrices^forward solves

3318: .seealso: MatSolve(), MatBackwardSolve()
3319: @*/
3320: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
3321: {

3331:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3332:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3333:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3334:   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);
3335:   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);
3336:   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);
3337:   MatCheckPreallocated(mat,1);
3338:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3339:   (*mat->ops->forwardsolve)(mat,b,x);
3340:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3341:   PetscObjectStateIncrease((PetscObject)x);
3342:   return(0);
3343: }

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

3351:    Neighbor-wise Collective on Mat and Vec

3353:    Input Parameters:
3354: +  mat - the factored matrix
3355: -  b - the right-hand-side vector

3357:    Output Parameter:
3358: .  x - the result vector

3360:    Notes:
3361:    MatSolve() should be used for most applications, as it performs
3362:    a forward solve followed by a backward solve.

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

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

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

3377:    Level: developer

3379:    Concepts: matrices^backward solves

3381: .seealso: MatSolve(), MatForwardSolve()
3382: @*/
3383: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
3384: {

3394:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3395:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3396:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3397:   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);
3398:   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);
3399:   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);
3400:   MatCheckPreallocated(mat,1);

3402:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3403:   (*mat->ops->backwardsolve)(mat,b,x);
3404:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3405:   PetscObjectStateIncrease((PetscObject)x);
3406:   return(0);
3407: }

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

3414:    Neighbor-wise Collective on Mat and Vec

3416:    Input Parameters:
3417: +  mat - the factored matrix
3418: .  b - the right-hand-side vector
3419: -  y - the vector to be added to

3421:    Output Parameter:
3422: .  x - the result vector

3424:    Notes:
3425:    The vectors b and x cannot be the same.  I.e., one cannot
3426:    call MatSolveAdd(A,x,y,x).

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

3432:    Level: developer

3434:    Concepts: matrices^triangular solves

3436: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3437: @*/
3438: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3439: {
3440:   PetscScalar    one = 1.0;
3441:   Vec            tmp;

3453:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3454:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3455:   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);
3456:   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);
3457:   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);
3458:   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);
3459:   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);
3460:   MatCheckPreallocated(mat,1);

3462:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3463:   if (mat->ops->solveadd) {
3464:     (*mat->ops->solveadd)(mat,b,y,x);
3465:   } else {
3466:     /* do the solve then the add manually */
3467:     if (x != y) {
3468:       MatSolve(mat,b,x);
3469:       VecAXPY(x,one,y);
3470:     } else {
3471:       VecDuplicate(x,&tmp);
3472:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3473:       VecCopy(x,tmp);
3474:       MatSolve(mat,b,x);
3475:       VecAXPY(x,one,tmp);
3476:       VecDestroy(&tmp);
3477:     }
3478:   }
3479:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3480:   PetscObjectStateIncrease((PetscObject)x);
3481:   return(0);
3482: }

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

3489:    Neighbor-wise Collective on Mat and Vec

3491:    Input Parameters:
3492: +  mat - the factored matrix
3493: -  b - the right-hand-side vector

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

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

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

3506:    Level: developer

3508:    Concepts: matrices^triangular solves

3510: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3511: @*/
3512: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
3513: {

3523:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3524:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3525:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3526:   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);
3527:   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);
3528:   MatCheckPreallocated(mat,1);
3529:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3530:   (*mat->ops->solvetranspose)(mat,b,x);
3531:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3532:   PetscObjectStateIncrease((PetscObject)x);
3533:   return(0);
3534: }

3538: /*@
3539:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3540:                       factored matrix.

3542:    Neighbor-wise Collective on Mat and Vec

3544:    Input Parameters:
3545: +  mat - the factored matrix
3546: .  b - the right-hand-side vector
3547: -  y - the vector to be added to

3549:    Output Parameter:
3550: .  x - the result vector

3552:    Notes:
3553:    The vectors b and x cannot be the same.  I.e., one cannot
3554:    call MatSolveTransposeAdd(A,x,y,x).

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

3560:    Level: developer

3562:    Concepts: matrices^triangular solves

3564: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3565: @*/
3566: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3567: {
3568:   PetscScalar    one = 1.0;
3570:   Vec            tmp;

3581:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3582:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3583:   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);
3584:   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);
3585:   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);
3586:   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);
3587:   MatCheckPreallocated(mat,1);

3589:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3590:   if (mat->ops->solvetransposeadd) {
3591:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3592:   } else {
3593:     /* do the solve then the add manually */
3594:     if (x != y) {
3595:       MatSolveTranspose(mat,b,x);
3596:       VecAXPY(x,one,y);
3597:     } else {
3598:       VecDuplicate(x,&tmp);
3599:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3600:       VecCopy(x,tmp);
3601:       MatSolveTranspose(mat,b,x);
3602:       VecAXPY(x,one,tmp);
3603:       VecDestroy(&tmp);
3604:     }
3605:   }
3606:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3607:   PetscObjectStateIncrease((PetscObject)x);
3608:   return(0);
3609: }
3610: /* ----------------------------------------------------------------*/

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

3617:    Neighbor-wise Collective on Mat and Vec

3619:    Input Parameters:
3620: +  mat - the matrix
3621: .  b - the right hand side
3622: .  omega - the relaxation factor
3623: .  flag - flag indicating the type of SOR (see below)
3624: .  shift -  diagonal shift
3625: .  its - the number of iterations
3626: -  lits - the number of local iterations

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

3631:    SOR Flags:
3632: .     SOR_FORWARD_SWEEP - forward SOR
3633: .     SOR_BACKWARD_SWEEP - backward SOR
3634: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3635: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3636: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3637: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3638: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3639:          upper/lower triangular part of matrix to
3640:          vector (with omega)
3641: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3643:    Notes:
3644:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3645:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3646:    on each processor.

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

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

3653:    Notes for Advanced Users:
3654:    The flags are implemented as bitwise inclusive or operations.
3655:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3656:    to specify a zero initial guess for SSOR.

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

3662:    Vectors x and b CANNOT be the same

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

3666:    Level: developer

3668:    Concepts: matrices^relaxation
3669:    Concepts: matrices^SOR
3670:    Concepts: matrices^Gauss-Seidel

3672: @*/
3673: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3674: {

3684:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3685:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3686:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3687:   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);
3688:   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);
3689:   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);
3690:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3691:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3692:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3694:   MatCheckPreallocated(mat,1);
3695:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3696:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3697:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3698:   PetscObjectStateIncrease((PetscObject)x);
3699:   return(0);
3700: }

3704: /*
3705:       Default matrix copy routine.
3706: */
3707: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3708: {
3709:   PetscErrorCode    ierr;
3710:   PetscInt          i,rstart = 0,rend = 0,nz;
3711:   const PetscInt    *cwork;
3712:   const PetscScalar *vwork;

3715:   if (B->assembled) {
3716:     MatZeroEntries(B);
3717:   }
3718:   MatGetOwnershipRange(A,&rstart,&rend);
3719:   for (i=rstart; i<rend; i++) {
3720:     MatGetRow(A,i,&nz,&cwork,&vwork);
3721:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3722:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3723:   }
3724:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3725:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3726:   PetscObjectStateIncrease((PetscObject)B);
3727:   return(0);
3728: }

3732: /*@
3733:    MatCopy - Copys a matrix to another matrix.

3735:    Collective on Mat

3737:    Input Parameters:
3738: +  A - the matrix
3739: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3741:    Output Parameter:
3742: .  B - where the copy is put

3744:    Notes:
3745:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3746:    same nonzero pattern or the routine will crash.

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

3752:    Level: intermediate

3754:    Concepts: matrices^copying

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

3758: @*/
3759: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3760: {
3762:   PetscInt       i;

3770:   MatCheckPreallocated(B,2);
3771:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3772:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3773:   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);
3774:   MatCheckPreallocated(A,1);

3776:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3777:   if (A->ops->copy) {
3778:     (*A->ops->copy)(A,B,str);
3779:   } else { /* generic conversion */
3780:     MatCopy_Basic(A,B,str);
3781:   }

3783:   B->stencil.dim = A->stencil.dim;
3784:   B->stencil.noc = A->stencil.noc;
3785:   for (i=0; i<=A->stencil.dim; i++) {
3786:     B->stencil.dims[i]   = A->stencil.dims[i];
3787:     B->stencil.starts[i] = A->stencil.starts[i];
3788:   }

3790:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3791:   PetscObjectStateIncrease((PetscObject)B);
3792:   return(0);
3793: }

3797: /*@C
3798:    MatConvert - Converts a matrix to another matrix, either of the same
3799:    or different type.

3801:    Collective on Mat

3803:    Input Parameters:
3804: +  mat - the matrix
3805: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3806:    same type as the original matrix.
3807: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3808:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3809:    MAT_INITIAL_MATRIX.

3811:    Output Parameter:
3812: .  M - pointer to place new matrix

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

3819:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3820:    the MPI communicator of the generated matrix is always the same as the communicator
3821:    of the input matrix.

3823:    Level: intermediate

3825:    Concepts: matrices^converting between storage formats

3827: .seealso: MatCopy(), MatDuplicate()
3828: @*/
3829: PetscErrorCode  MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3830: {
3832:   PetscBool      sametype,issame,flg;
3833:   char           convname[256],mtype[256];
3834:   Mat            B;

3840:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3841:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3842:   MatCheckPreallocated(mat,1);
3843:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

3845:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3846:   if (flg) {
3847:     newtype = mtype;
3848:   }
3849:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3850:   PetscStrcmp(newtype,"same",&issame);
3851:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");

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

3855:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3856:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3857:   } else {
3858:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3859:     const char     *prefix[3] = {"seq","mpi",""};
3860:     PetscInt       i;
3861:     /*
3862:        Order of precedence:
3863:        1) See if a specialized converter is known to the current matrix.
3864:        2) See if a specialized converter is known to the desired matrix class.
3865:        3) See if a good general converter is registered for the desired class
3866:           (as of 6/27/03 only MATMPIADJ falls into this category).
3867:        4) See if a good general converter is known for the current matrix.
3868:        5) Use a really basic converter.
3869:     */

3871:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3872:     for (i=0; i<3; i++) {
3873:       PetscStrcpy(convname,"MatConvert_");
3874:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3875:       PetscStrcat(convname,"_");
3876:       PetscStrcat(convname,prefix[i]);
3877:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3878:       PetscStrcat(convname,"_C");
3879:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3880:       if (conv) goto foundconv;
3881:     }

3883:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3884:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
3885:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3886:     MatSetType(B,newtype);
3887:     for (i=0; i<3; i++) {
3888:       PetscStrcpy(convname,"MatConvert_");
3889:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3890:       PetscStrcat(convname,"_");
3891:       PetscStrcat(convname,prefix[i]);
3892:       PetscStrcat(convname,newtype);
3893:       PetscStrcat(convname,"_C");
3894:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3895:       if (conv) {
3896:         MatDestroy(&B);
3897:         goto foundconv;
3898:       }
3899:     }

3901:     /* 3) See if a good general converter is registered for the desired class */
3902:     conv = B->ops->convertfrom;
3903:     MatDestroy(&B);
3904:     if (conv) goto foundconv;

3906:     /* 4) See if a good general converter is known for the current matrix */
3907:     if (mat->ops->convert) {
3908:       conv = mat->ops->convert;
3909:     }
3910:     if (conv) goto foundconv;

3912:     /* 5) Use a really basic converter. */
3913:     conv = MatConvert_Basic;

3915: foundconv:
3916:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3917:     (*conv)(mat,newtype,reuse,M);
3918:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3919:   }
3920:   PetscObjectStateIncrease((PetscObject)*M);

3922:   /* Copy Mat options */
3923:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3924:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3925:   return(0);
3926: }

3930: /*@C
3931:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3933:    Not Collective

3935:    Input Parameter:
3936: .  mat - the matrix, must be a factored matrix

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

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

3945:    Level: intermediate

3947: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3948: @*/
3949: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3950: {
3951:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

3956:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3957:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
3958:   if (!conv) {
3959:     *type = MATSOLVERPETSC;
3960:   } else {
3961:     (*conv)(mat,type);
3962:   }
3963:   return(0);
3964: }

3966: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
3967: struct _MatSolverPackageForSpecifcType {
3968:   MatType                        mtype;
3969:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
3970:   MatSolverPackageForSpecifcType next;
3971: };

3973: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
3974: struct _MatSolverPackageHolder {
3975:   char                           *name;
3976:   MatSolverPackageForSpecifcType handlers;
3977:   MatSolverPackageHolder         next;
3978: };

3980: static MatSolverPackageHolder MatSolverPackageHolders = NULL;

3984: /*@C
3985:    MatSolvePackageRegister - Registers a MatSolverPackage that works for a particular matrix type

3987:    Input Parameters:
3988: +    package - name of the package, for example petsc or superlu
3989: .    mtype - the matrix type that works with this package
3990: .    ftype - the type of factorization supported by the package
3991: -    getfactor - routine that will create the factored matrix ready to be used

3993:     Level: intermediate

3995: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3996: @*/
3997: PetscErrorCode  MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
3998: {
3999:   PetscErrorCode                 ierr;
4000:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4001:   PetscBool                      flg;
4002:   MatSolverPackageForSpecifcType inext,iprev = NULL;

4005:   if (!MatSolverPackageHolders) {
4006:     PetscNew(&MatSolverPackageHolders);
4007:     PetscStrallocpy(package,&MatSolverPackageHolders->name);
4008:     PetscNew(&MatSolverPackageHolders->handlers);
4009:     PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4010:     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4011:     return(0);
4012:   }
4013:   while (next) {
4014:     PetscStrcasecmp(package,next->name,&flg);
4015:     if (flg) {
4016:       inext = next->handlers;
4017:       while (inext) {
4018:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4019:         if (flg) {
4020:           inext->getfactor[(int)ftype-1] = getfactor;
4021:           return(0);
4022:         }
4023:         iprev = inext;
4024:         inext = inext->next;
4025:       }
4026:       PetscNew(&iprev->next);
4027:       PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4028:       iprev->next->getfactor[(int)ftype-1] = getfactor;
4029:       return(0);
4030:     }
4031:     prev = next;
4032:     next = next->next;
4033:   }
4034:   PetscNew(&prev->next);
4035:   PetscStrallocpy(package,&prev->next->name);
4036:   PetscNew(&prev->next->handlers);
4037:   PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4038:   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4039:   return(0);
4040: }

4044: /*@C
4045:    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist

4047:    Input Parameters:
4048: +    package - name of the package, for example petsc or superlu
4049: .    ftype - the type of factorization supported by the package
4050: -    mtype - the matrix type that works with this package

4052:    Output Parameters:
4053: +   foundpackage - PETSC_TRUE if the package was registered
4054: .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4055: -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found

4057:     Level: intermediate

4059: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4060: @*/
4061: PetscErrorCode  MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4062: {
4063:   PetscErrorCode                 ierr;
4064:   MatSolverPackageHolder         next = MatSolverPackageHolders;
4065:   PetscBool                      flg;
4066:   MatSolverPackageForSpecifcType inext;

4069:   if (foundpackage) *foundpackage = PETSC_FALSE;
4070:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4071:   if (getfactor)    *getfactor    = NULL;
4072:   while (next) {
4073:     PetscStrcasecmp(package,next->name,&flg);
4074:     if (flg) {
4075:       if (foundpackage) *foundpackage = PETSC_TRUE;
4076:       inext = next->handlers;
4077:       while (inext) {
4078:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4079:         if (flg) {
4080:           if (foundmtype) *foundmtype = PETSC_TRUE;
4081:           if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4082:           return(0);
4083:         }
4084:         inext = inext->next;
4085:       }
4086:     }
4087:     next = next->next;
4088:   }
4089:   return(0);
4090: }

4094: PetscErrorCode  MatSolverPackageDestroy(void)
4095: {
4096:   PetscErrorCode                 ierr;
4097:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4098:   MatSolverPackageForSpecifcType inext,iprev;

4101:   while (next) {
4102:     PetscFree(next->name);
4103:     inext = next->handlers;
4104:     while (inext) {
4105:       PetscFree(inext->mtype);
4106:       iprev = inext;
4107:       inext = inext->next;
4108:       PetscFree(iprev);
4109:     }
4110:     prev = next;
4111:     next = next->next;
4112:     PetscFree(prev);
4113:   }
4114:   MatSolverPackageHolders = NULL;
4115:   return(0);
4116: }

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

4123:    Collective on Mat

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

4130:    Output Parameters:
4131: .  f - the factor matrix used with MatXXFactorSymbolic() calls

4133:    Notes:
4134:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4135:      such as pastix, superlu, mumps etc.

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

4139:    Level: intermediate

4141: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4142: @*/
4143: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4144: {
4145:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4146:   PetscBool      foundpackage,foundmtype;


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

4155:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4156:   if (!foundpackage) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4157:   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4158:   if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support factorization type %s for  matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);

4160:   (*conv)(mat,ftype,f);
4161:   return(0);
4162: }

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

4169:    Not Collective

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

4176:    Output Parameter:
4177: .    flg - PETSC_TRUE if the factorization is available

4179:    Notes:
4180:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4181:      such as pastix, superlu, mumps etc.

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

4185:    Level: intermediate

4187: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4188: @*/
4189: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4190: {
4191:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);


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

4200:   *flg = PETSC_FALSE;
4201:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4202:   if (gconv) {
4203:     *flg = PETSC_TRUE;
4204:   }
4205:   return(0);
4206: }

4208: #include <petscdmtypes.h>

4212: /*@
4213:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4215:    Collective on Mat

4217:    Input Parameters:
4218: +  mat - the matrix
4219: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4220:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

4222:    Output Parameter:
4223: .  M - pointer to place new matrix

4225:    Level: intermediate

4227:    Concepts: matrices^duplicating

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

4231: .seealso: MatCopy(), MatConvert()
4232: @*/
4233: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4234: {
4236:   Mat            B;
4237:   PetscInt       i;
4238:   DM             dm;

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

4248:   *M = 0;
4249:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4250:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4251:   (*mat->ops->duplicate)(mat,op,M);
4252:   B    = *M;

4254:   B->stencil.dim = mat->stencil.dim;
4255:   B->stencil.noc = mat->stencil.noc;
4256:   for (i=0; i<=mat->stencil.dim; i++) {
4257:     B->stencil.dims[i]   = mat->stencil.dims[i];
4258:     B->stencil.starts[i] = mat->stencil.starts[i];
4259:   }

4261:   B->nooffproczerorows = mat->nooffproczerorows;
4262:   B->nooffprocentries  = mat->nooffprocentries;

4264:   PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4265:   if (dm) {
4266:     PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4267:   }
4268:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4269:   PetscObjectStateIncrease((PetscObject)B);
4270:   return(0);
4271: }

4275: /*@
4276:    MatGetDiagonal - Gets the diagonal of a matrix.

4278:    Logically Collective on Mat and Vec

4280:    Input Parameters:
4281: +  mat - the matrix
4282: -  v - the vector for storing the diagonal

4284:    Output Parameter:
4285: .  v - the diagonal of the matrix

4287:    Level: intermediate

4289:    Note:
4290:    Currently only correct in parallel for square matrices.

4292:    Concepts: matrices^accessing diagonals

4294: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4295: @*/
4296: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
4297: {

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

4308:   (*mat->ops->getdiagonal)(mat,v);
4309:   PetscObjectStateIncrease((PetscObject)v);
4310:   return(0);
4311: }

4315: /*@C
4316:    MatGetRowMin - Gets the minimum value (of the real part) of each
4317:         row of the matrix

4319:    Logically Collective on Mat and Vec

4321:    Input Parameters:
4322: .  mat - the matrix

4324:    Output Parameter:
4325: +  v - the vector for storing the maximums
4326: -  idx - the indices of the column found for each row (optional)

4328:    Level: intermediate

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

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

4335:    Concepts: matrices^getting row maximums

4337: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4338:           MatGetRowMax()
4339: @*/
4340: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4341: {

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

4352:   (*mat->ops->getrowmin)(mat,v,idx);
4353:   PetscObjectStateIncrease((PetscObject)v);
4354:   return(0);
4355: }

4359: /*@C
4360:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4361:         row of the matrix

4363:    Logically Collective on Mat and Vec

4365:    Input Parameters:
4366: .  mat - the matrix

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

4372:    Level: intermediate

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

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

4379:    Concepts: matrices^getting row maximums

4381: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4382: @*/
4383: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4384: {

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

4396:   (*mat->ops->getrowminabs)(mat,v,idx);
4397:   PetscObjectStateIncrease((PetscObject)v);
4398:   return(0);
4399: }

4403: /*@C
4404:    MatGetRowMax - Gets the maximum value (of the real part) of each
4405:         row of the matrix

4407:    Logically Collective on Mat and Vec

4409:    Input Parameters:
4410: .  mat - the matrix

4412:    Output Parameter:
4413: +  v - the vector for storing the maximums
4414: -  idx - the indices of the column found for each row (optional)

4416:    Level: intermediate

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

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

4423:    Concepts: matrices^getting row maximums

4425: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4426: @*/
4427: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4428: {

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

4439:   (*mat->ops->getrowmax)(mat,v,idx);
4440:   PetscObjectStateIncrease((PetscObject)v);
4441:   return(0);
4442: }

4446: /*@C
4447:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4448:         row of the matrix

4450:    Logically Collective on Mat and Vec

4452:    Input Parameters:
4453: .  mat - the matrix

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

4459:    Level: intermediate

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

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

4466:    Concepts: matrices^getting row maximums

4468: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4469: @*/
4470: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4471: {

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

4483:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4484:   PetscObjectStateIncrease((PetscObject)v);
4485:   return(0);
4486: }

4490: /*@
4491:    MatGetRowSum - Gets the sum of each row of the matrix

4493:    Logically Collective on Mat and Vec

4495:    Input Parameters:
4496: .  mat - the matrix

4498:    Output Parameter:
4499: .  v - the vector for storing the sum of rows

4501:    Level: intermediate

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

4505:    Concepts: matrices^getting row sums

4507: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4508: @*/
4509: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4510: {
4511:   PetscInt       start = 0, end = 0, row;
4512:   PetscScalar    *array;

4519:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4520:   MatCheckPreallocated(mat,1);
4521:   MatGetOwnershipRange(mat, &start, &end);
4522:   VecGetArray(v, &array);
4523:   for (row = start; row < end; ++row) {
4524:     PetscInt          ncols, col;
4525:     const PetscInt    *cols;
4526:     const PetscScalar *vals;

4528:     array[row - start] = 0.0;

4530:     MatGetRow(mat, row, &ncols, &cols, &vals);
4531:     for (col = 0; col < ncols; col++) {
4532:       array[row - start] += vals[col];
4533:     }
4534:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4535:   }
4536:   VecRestoreArray(v, &array);
4537:   PetscObjectStateIncrease((PetscObject) v);
4538:   return(0);
4539: }

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

4546:    Collective on Mat

4548:    Input Parameter:
4549: +  mat - the matrix to transpose
4550: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4552:    Output Parameters:
4553: .  B - the transpose

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

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

4560:    Level: intermediate

4562:    Concepts: matrices^transposing

4564: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4565: @*/
4566: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4567: {

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

4578:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4579:   (*mat->ops->transpose)(mat,reuse,B);
4580:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4581:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4582:   return(0);
4583: }

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

4591:    Collective on Mat

4593:    Input Parameter:
4594: +  A - the matrix to test
4595: -  B - the matrix to test against, this can equal the first parameter

4597:    Output Parameters:
4598: .  flg - the result

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

4605:    Level: intermediate

4607:    Concepts: matrices^transposing, matrix^symmetry

4609: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4610: @*/
4611: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4612: {
4613:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4619:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4620:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4621:   *flg = PETSC_FALSE;
4622:   if (f && g) {
4623:     if (f == g) {
4624:       (*f)(A,B,tol,flg);
4625:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4626:   } else {
4627:     MatType mattype;
4628:     if (!f) {
4629:       MatGetType(A,&mattype);
4630:     } else {
4631:       MatGetType(B,&mattype);
4632:     }
4633:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4634:   }
4635:   return(0);
4636: }

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

4643:    Collective on Mat

4645:    Input Parameter:
4646: +  mat - the matrix to transpose and complex conjugate
4647: -  reuse - store the transpose matrix in the provided B

4649:    Output Parameters:
4650: .  B - the Hermitian

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

4655:    Level: intermediate

4657:    Concepts: matrices^transposing, complex conjugatex

4659: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4660: @*/
4661: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4662: {

4666:   MatTranspose(mat,reuse,B);
4667: #if defined(PETSC_USE_COMPLEX)
4668:   MatConjugate(*B);
4669: #endif
4670:   return(0);
4671: }

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

4678:    Collective on Mat

4680:    Input Parameter:
4681: +  A - the matrix to test
4682: -  B - the matrix to test against, this can equal the first parameter

4684:    Output Parameters:
4685: .  flg - the result

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

4692:    Level: intermediate

4694:    Concepts: matrices^transposing, matrix^symmetry

4696: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4697: @*/
4698: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4699: {
4700:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4706:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4707:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4708:   if (f && g) {
4709:     if (f==g) {
4710:       (*f)(A,B,tol,flg);
4711:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4712:   }
4713:   return(0);
4714: }

4718: /*@
4719:    MatPermute - Creates a new matrix with rows and columns permuted from the
4720:    original.

4722:    Collective on Mat

4724:    Input Parameters:
4725: +  mat - the matrix to permute
4726: .  row - row permutation, each processor supplies only the permutation for its rows
4727: -  col - column permutation, each processor supplies only the permutation for its columns

4729:    Output Parameters:
4730: .  B - the permuted matrix

4732:    Level: advanced

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

4738:    Concepts: matrices^permuting

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

4742: @*/
4743: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4744: {

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

4758:   (*mat->ops->permute)(mat,row,col,B);
4759:   PetscObjectStateIncrease((PetscObject)*B);
4760:   return(0);
4761: }

4765: /*@
4766:    MatEqual - Compares two matrices.

4768:    Collective on Mat

4770:    Input Parameters:
4771: +  A - the first matrix
4772: -  B - the second matrix

4774:    Output Parameter:
4775: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4777:    Level: intermediate

4779:    Concepts: matrices^equality between
4780: @*/
4781: PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4782: {

4792:   MatCheckPreallocated(B,2);
4793:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4794:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4795:   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);
4796:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4797:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4798:   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);
4799:   MatCheckPreallocated(A,1);

4801:   (*A->ops->equal)(A,B,flg);
4802:   return(0);
4803: }

4807: /*@
4808:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4809:    matrices that are stored as vectors.  Either of the two scaling
4810:    matrices can be NULL.

4812:    Collective on Mat

4814:    Input Parameters:
4815: +  mat - the matrix to be scaled
4816: .  l - the left scaling vector (or NULL)
4817: -  r - the right scaling vector (or NULL)

4819:    Notes:
4820:    MatDiagonalScale() computes A = LAR, where
4821:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4822:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4824:    Level: intermediate

4826:    Concepts: matrices^diagonal scaling
4827:    Concepts: diagonal scaling of matrices

4829: .seealso: MatScale()
4830: @*/
4831: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4832: {

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

4845:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4846:   (*mat->ops->diagonalscale)(mat,l,r);
4847:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4848:   PetscObjectStateIncrease((PetscObject)mat);
4849: #if defined(PETSC_HAVE_CUSP)
4850:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4851:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4852:   }
4853: #endif
4854: #if defined(PETSC_HAVE_VIENNACL)
4855:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4856:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4857:   }
4858: #endif
4859:   return(0);
4860: }

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

4867:     Logically Collective on Mat

4869:     Input Parameters:
4870: +   mat - the matrix to be scaled
4871: -   a  - the scaling value

4873:     Output Parameter:
4874: .   mat - the scaled matrix

4876:     Level: intermediate

4878:     Concepts: matrices^scaling all entries

4880: .seealso: MatDiagonalScale()
4881: @*/
4882: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4883: {

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

4895:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4896:   if (a != (PetscScalar)1.0) {
4897:     (*mat->ops->scale)(mat,a);
4898:     PetscObjectStateIncrease((PetscObject)mat);
4899:   }
4900:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4901: #if defined(PETSC_HAVE_CUSP)
4902:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4903:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4904:   }
4905: #endif
4906: #if defined(PETSC_HAVE_VIENNACL)
4907:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4908:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4909:   }
4910: #endif
4911:   return(0);
4912: }

4916: /*@
4917:    MatNorm - Calculates various norms of a matrix.

4919:    Collective on Mat

4921:    Input Parameters:
4922: +  mat - the matrix
4923: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4925:    Output Parameters:
4926: .  nrm - the resulting norm

4928:    Level: intermediate

4930:    Concepts: matrices^norm
4931:    Concepts: norm^of matrix
4932: @*/
4933: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4934: {


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

4947:   (*mat->ops->norm)(mat,type,nrm);
4948:   return(0);
4949: }

4951: /*
4952:      This variable is used to prevent counting of MatAssemblyBegin() that
4953:    are called from within a MatAssemblyEnd().
4954: */
4955: static PetscInt MatAssemblyEnd_InUse = 0;
4958: /*@
4959:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4960:    be called after completing all calls to MatSetValues().

4962:    Collective on Mat

4964:    Input Parameters:
4965: +  mat - the matrix
4966: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

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

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

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

4983:    Level: beginner

4985:    Concepts: matrices^assembling

4987: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4988: @*/
4989: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4990: {

4996:   MatCheckPreallocated(mat,1);
4997:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4998:   if (mat->assembled) {
4999:     mat->was_assembled = PETSC_TRUE;
5000:     mat->assembled     = PETSC_FALSE;
5001:   }
5002:   if (!MatAssemblyEnd_InUse) {
5003:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5004:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5005:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5006:   } else if (mat->ops->assemblybegin) {
5007:     (*mat->ops->assemblybegin)(mat,type);
5008:   }
5009:   return(0);
5010: }

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

5018:    Not Collective

5020:    Input Parameter:
5021: .  mat - the matrix

5023:    Output Parameter:
5024: .  assembled - PETSC_TRUE or PETSC_FALSE

5026:    Level: advanced

5028:    Concepts: matrices^assembled?

5030: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5031: @*/
5032: PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
5033: {
5038:   *assembled = mat->assembled;
5039:   return(0);
5040: }

5044: /*@
5045:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5046:    be called after MatAssemblyBegin().

5048:    Collective on Mat

5050:    Input Parameters:
5051: +  mat - the matrix
5052: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5054:    Options Database Keys:
5055: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5056: .  -mat_view ::ascii_info_detail - Prints more detailed info
5057: .  -mat_view - Prints matrix in ASCII format
5058: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5059: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5060: .  -display <name> - Sets display name (default is host)
5061: .  -draw_pause <sec> - Sets number of seconds to pause after display
5062: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 11 Using MATLAB with PETSc )
5063: .  -viewer_socket_machine <machine> - Machine to use for socket
5064: .  -viewer_socket_port <port> - Port number to use for socket
5065: -  -mat_view binary:filename[:append] - Save matrix to file in binary format

5067:    Notes:
5068:    MatSetValues() generally caches the values.  The matrix is ready to
5069:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5070:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5071:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5072:    using the matrix.

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

5078:    Level: beginner

5080: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5081: @*/
5082: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
5083: {
5084:   PetscErrorCode  ierr;
5085:   static PetscInt inassm = 0;
5086:   PetscBool       flg    = PETSC_FALSE;


5092:   inassm++;
5093:   MatAssemblyEnd_InUse++;
5094:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5095:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5096:     if (mat->ops->assemblyend) {
5097:       (*mat->ops->assemblyend)(mat,type);
5098:     }
5099:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5100:   } else if (mat->ops->assemblyend) {
5101:     (*mat->ops->assemblyend)(mat,type);
5102:   }

5104:   /* Flush assembly is not a true assembly */
5105:   if (type != MAT_FLUSH_ASSEMBLY) {
5106:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5107:   }
5108:   mat->insertmode = NOT_SET_VALUES;
5109:   MatAssemblyEnd_InUse--;
5110:   PetscObjectStateIncrease((PetscObject)mat);
5111:   if (!mat->symmetric_eternal) {
5112:     mat->symmetric_set              = PETSC_FALSE;
5113:     mat->hermitian_set              = PETSC_FALSE;
5114:     mat->structurally_symmetric_set = PETSC_FALSE;
5115:   }
5116: #if defined(PETSC_HAVE_CUSP)
5117:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5118:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5119:   }
5120: #endif
5121: #if defined(PETSC_HAVE_VIENNACL)
5122:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5123:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5124:   }
5125: #endif
5126:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5127:     MatViewFromOptions(mat,NULL,"-mat_view");

5129:     if (mat->checksymmetryonassembly) {
5130:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5131:       if (flg) {
5132:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5133:       } else {
5134:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5135:       }
5136:     }
5137:     if (mat->nullsp && mat->checknullspaceonassembly) {
5138:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5139:     }
5140:   }
5141:   inassm--;
5142:   return(0);
5143: }

5147: /*@
5148:    MatSetOption - Sets a parameter option for a matrix. Some options
5149:    may be specific to certain storage formats.  Some options
5150:    determine how values will be inserted (or added). Sorted,
5151:    row-oriented input will generally assemble the fastest. The default
5152:    is row-oriented.

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

5156:    Input Parameters:
5157: +  mat - the matrix
5158: .  option - the option, one of those listed below (and possibly others),
5159: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5161:   Options Describing Matrix Structure:
5162: +    MAT_SPD - symmetric positive definite
5163: .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5164: .    MAT_HERMITIAN - transpose is the complex conjugation
5165: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5166: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5167:                             you set to be kept with all future use of the matrix
5168:                             including after MatAssemblyBegin/End() which could
5169:                             potentially change the symmetry structure, i.e. you
5170:                             KNOW the matrix will ALWAYS have the property you set.


5173:    Options For Use with MatSetValues():
5174:    Insert a logically dense subblock, which can be
5175: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

5192:    Notes:
5193:    Some options are relevant only for particular matrix types and
5194:    are thus ignored by others.  Other options are not supported by
5195:    certain matrix types and will generate an error message if set.

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

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

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

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

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

5223:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5224:    searches during matrix assembly. When this flag is set, the hash table
5225:    is created during the first Matrix Assembly. This hash table is
5226:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5227:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5228:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5229:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5248:    Level: intermediate

5250:    Concepts: matrices^setting options

5252: .seealso:  MatOption, Mat

5254: @*/
5255: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool flg)
5256: {

5262:   if (op > 0) {
5265:   }

5267:   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);
5268:   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()");

5270:   switch (op) {
5271:   case MAT_NO_OFF_PROC_ENTRIES:
5272:     mat->nooffprocentries = flg;
5273:     return(0);
5274:     break;
5275:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5276:     mat->nooffproczerorows = flg;
5277:     return(0);
5278:     break;
5279:   case MAT_SPD:
5280:     mat->spd_set = PETSC_TRUE;
5281:     mat->spd     = flg;
5282:     if (flg) {
5283:       mat->symmetric                  = PETSC_TRUE;
5284:       mat->structurally_symmetric     = PETSC_TRUE;
5285:       mat->symmetric_set              = PETSC_TRUE;
5286:       mat->structurally_symmetric_set = PETSC_TRUE;
5287:     }
5288:     break;
5289:   case MAT_SYMMETRIC:
5290:     mat->symmetric = flg;
5291:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5292:     mat->symmetric_set              = PETSC_TRUE;
5293:     mat->structurally_symmetric_set = flg;
5294:     break;
5295:   case MAT_HERMITIAN:
5296:     mat->hermitian = flg;
5297:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5298:     mat->hermitian_set              = PETSC_TRUE;
5299:     mat->structurally_symmetric_set = flg;
5300:     break;
5301:   case MAT_STRUCTURALLY_SYMMETRIC:
5302:     mat->structurally_symmetric     = flg;
5303:     mat->structurally_symmetric_set = PETSC_TRUE;
5304:     break;
5305:   case MAT_SYMMETRY_ETERNAL:
5306:     mat->symmetric_eternal = flg;
5307:     break;
5308:   default:
5309:     break;
5310:   }
5311:   if (mat->ops->setoption) {
5312:     (*mat->ops->setoption)(mat,op,flg);
5313:   }
5314:   return(0);
5315: }

5319: /*@
5320:    MatGetOption - Gets a parameter option that has been set for a matrix.

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

5324:    Input Parameters:
5325: +  mat - the matrix
5326: -  option - the option, this only responds to certain options, check the code for which ones

5328:    Output Parameter:
5329: .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

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

5333:    Level: intermediate

5335:    Concepts: matrices^setting options

5337: .seealso:  MatOption, MatSetOption()

5339: @*/
5340: PetscErrorCode  MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5341: {

5346:   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);
5347:   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()");

5349:   switch (op) {
5350:   case MAT_NO_OFF_PROC_ENTRIES:
5351:     *flg = mat->nooffprocentries;
5352:     break;
5353:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5354:     *flg = mat->nooffproczerorows;
5355:     break;
5356:   case MAT_SYMMETRIC:
5357:     *flg = mat->symmetric;
5358:     break;
5359:   case MAT_HERMITIAN:
5360:     *flg = mat->hermitian;
5361:     break;
5362:   case MAT_STRUCTURALLY_SYMMETRIC:
5363:     *flg = mat->structurally_symmetric;
5364:     break;
5365:   case MAT_SYMMETRY_ETERNAL:
5366:     *flg = mat->symmetric_eternal;
5367:     break;
5368:   default:
5369:     break;
5370:   }
5371:   return(0);
5372: }

5376: /*@
5377:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5378:    this routine retains the old nonzero structure.

5380:    Logically Collective on Mat

5382:    Input Parameters:
5383: .  mat - the matrix

5385:    Level: intermediate

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

5390:    Concepts: matrices^zeroing

5392: .seealso: MatZeroRows()
5393: @*/
5394: PetscErrorCode  MatZeroEntries(Mat mat)
5395: {

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

5406:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5407:   (*mat->ops->zeroentries)(mat);
5408:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5409:   PetscObjectStateIncrease((PetscObject)mat);
5410: #if defined(PETSC_HAVE_CUSP)
5411:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5412:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5413:   }
5414: #endif
5415: #if defined(PETSC_HAVE_VIENNACL)
5416:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5417:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5418:   }
5419: #endif
5420:   return(0);
5421: }

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

5429:    Collective on Mat

5431:    Input Parameters:
5432: +  mat - the matrix
5433: .  numRows - the number of rows to remove
5434: .  rows - the global row indices
5435: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5436: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5437: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5456:    Level: intermediate

5458:    Concepts: matrices^zeroing rows

5460: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5461: @*/
5462: PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5463: {

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

5475:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5476:   MatViewFromOptions(mat,NULL,"-mat_view");
5477:   PetscObjectStateIncrease((PetscObject)mat);
5478: #if defined(PETSC_HAVE_CUSP)
5479:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5480:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5481:   }
5482: #endif
5483: #if defined(PETSC_HAVE_VIENNACL)
5484:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5485:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5486:   }
5487: #endif
5488:   return(0);
5489: }

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

5497:    Collective on Mat

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

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

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

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

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

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

5523:    Level: intermediate

5525:    Concepts: matrices^zeroing rows

5527: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5528: @*/
5529: PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5530: {
5532:   PetscInt       numRows;
5533:   const PetscInt *rows;

5540:   ISGetLocalSize(is,&numRows);
5541:   ISGetIndices(is,&rows);
5542:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5543:   ISRestoreIndices(is,&rows);
5544:   return(0);
5545: }

5549: /*@C
5550:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5551:    of a set of rows of a matrix.

5553:    Collective on Mat

5555:    Input Parameters:
5556: +  mat - the matrix
5557: .  numRows - the number of rows to remove
5558: .  rows - the global row indices
5559: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5560: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5561: -  b - optional vector of right hand side, that will be adjusted by provided solution

5563:    Notes:
5564:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5565:    but does not release memory.  For the dense and block diagonal
5566:    formats this does not alter the nonzero structure.

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

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

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

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

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

5587:    Level: intermediate

5589:    Concepts: matrices^zeroing rows

5591: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5592: @*/
5593: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5594: {

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

5606:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5607:   MatViewFromOptions(mat,NULL,"-mat_view");
5608:   PetscObjectStateIncrease((PetscObject)mat);
5609: #if defined(PETSC_HAVE_CUSP)
5610:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5611:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5612:   }
5613: #endif
5614: #if defined(PETSC_HAVE_VIENNACL)
5615:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5616:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5617:   }
5618: #endif
5619:   return(0);
5620: }

5624: /*@C
5625:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5626:    of a set of rows of a matrix.

5628:    Collective on Mat

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

5637:    Notes:
5638:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5639:    but does not release memory.  For the dense and block diagonal
5640:    formats this does not alter the nonzero structure.

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

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

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

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

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

5661:    Level: intermediate

5663:    Concepts: matrices^zeroing rows

5665: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5666: @*/
5667: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5668: {
5669:   PetscInt       numRows;
5670:   const PetscInt *rows;

5677:   ISGetLocalSize(is,&numRows);
5678:   ISGetIndices(is,&rows);
5679:   MatZeroRows(mat,numRows,rows,diag,x,b);
5680:   ISRestoreIndices(is,&rows);
5681:   return(0);
5682: }

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

5690:    Collective on Mat

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

5700:    Notes:
5701:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5702:    but does not release memory.  For the dense and block diagonal
5703:    formats this does not alter the nonzero structure.

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

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

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

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

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

5723:    In Fortran idxm and idxn should be declared as
5724: $     MatStencil idxm(4,m)
5725:    and the values inserted using
5726: $    idxm(MatStencil_i,1) = i
5727: $    idxm(MatStencil_j,1) = j
5728: $    idxm(MatStencil_k,1) = k
5729: $    idxm(MatStencil_c,1) = c
5730:    etc

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

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

5740:    Level: intermediate

5742:    Concepts: matrices^zeroing rows

5744: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5745: @*/
5746: PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5747: {
5748:   PetscInt       dim     = mat->stencil.dim;
5749:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5750:   PetscInt       *dims   = mat->stencil.dims+1;
5751:   PetscInt       *starts = mat->stencil.starts;
5752:   PetscInt       *dxm    = (PetscInt*) rows;
5753:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5761:   PetscMalloc1(numRows, &jdxm);
5762:   for (i = 0; i < numRows; ++i) {
5763:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5764:     for (j = 0; j < 3-sdim; ++j) dxm++;
5765:     /* Local index in X dir */
5766:     tmp = *dxm++ - starts[0];
5767:     /* Loop over remaining dimensions */
5768:     for (j = 0; j < dim-1; ++j) {
5769:       /* If nonlocal, set index to be negative */
5770:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5771:       /* Update local index */
5772:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5773:     }
5774:     /* Skip component slot if necessary */
5775:     if (mat->stencil.noc) dxm++;
5776:     /* Local row number */
5777:     if (tmp >= 0) {
5778:       jdxm[numNewRows++] = tmp;
5779:     }
5780:   }
5781:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5782:   PetscFree(jdxm);
5783:   return(0);
5784: }

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

5792:    Collective on Mat

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

5802:    Notes:
5803:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5804:    but does not release memory.  For the dense and block diagonal
5805:    formats this does not alter the nonzero structure.

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

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

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

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

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

5825:    In Fortran idxm and idxn should be declared as
5826: $     MatStencil idxm(4,m)
5827:    and the values inserted using
5828: $    idxm(MatStencil_i,1) = i
5829: $    idxm(MatStencil_j,1) = j
5830: $    idxm(MatStencil_k,1) = k
5831: $    idxm(MatStencil_c,1) = c
5832:    etc

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

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

5842:    Level: intermediate

5844:    Concepts: matrices^zeroing rows

5846: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5847: @*/
5848: PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5849: {
5850:   PetscInt       dim     = mat->stencil.dim;
5851:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5852:   PetscInt       *dims   = mat->stencil.dims+1;
5853:   PetscInt       *starts = mat->stencil.starts;
5854:   PetscInt       *dxm    = (PetscInt*) rows;
5855:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5863:   PetscMalloc1(numRows, &jdxm);
5864:   for (i = 0; i < numRows; ++i) {
5865:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5866:     for (j = 0; j < 3-sdim; ++j) dxm++;
5867:     /* Local index in X dir */
5868:     tmp = *dxm++ - starts[0];
5869:     /* Loop over remaining dimensions */
5870:     for (j = 0; j < dim-1; ++j) {
5871:       /* If nonlocal, set index to be negative */
5872:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5873:       /* Update local index */
5874:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5875:     }
5876:     /* Skip component slot if necessary */
5877:     if (mat->stencil.noc) dxm++;
5878:     /* Local row number */
5879:     if (tmp >= 0) {
5880:       jdxm[numNewRows++] = tmp;
5881:     }
5882:   }
5883:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5884:   PetscFree(jdxm);
5885:   return(0);
5886: }

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

5894:    Collective on Mat

5896:    Input Parameters:
5897: +  mat - the matrix
5898: .  numRows - the number of rows to remove
5899: .  rows - the global row indices
5900: .  diag - value put in all diagonals of eliminated rows
5901: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5902: -  b - optional vector of right hand side, that will be adjusted by provided solution

5904:    Notes:
5905:    Before calling MatZeroRowsLocal(), the user must first set the
5906:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5908:    For the AIJ matrix formats this removes the old nonzero structure,
5909:    but does not release memory.  For the dense and block diagonal
5910:    formats this does not alter the nonzero structure.

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

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

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

5923:    Level: intermediate

5925:    Concepts: matrices^zeroing

5927: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5928: @*/
5929: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5930: {

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

5941:   if (mat->ops->zerorowslocal) {
5942:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5943:   } else {
5944:     IS             is, newis;
5945:     const PetscInt *newRows;

5947:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5948:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5949:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5950:     ISGetIndices(newis,&newRows);
5951:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5952:     ISRestoreIndices(newis,&newRows);
5953:     ISDestroy(&newis);
5954:     ISDestroy(&is);
5955:   }
5956:   PetscObjectStateIncrease((PetscObject)mat);
5957: #if defined(PETSC_HAVE_CUSP)
5958:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5959:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5960:   }
5961: #endif
5962: #if defined(PETSC_HAVE_VIENNACL)
5963:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5964:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5965:   }
5966: #endif
5967:   return(0);
5968: }

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

5976:    Collective on Mat

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

5985:    Notes:
5986:    Before calling MatZeroRowsLocalIS(), the user must first set the
5987:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5989:    For the AIJ matrix formats this removes the old nonzero structure,
5990:    but does not release memory.  For the dense and block diagonal
5991:    formats this does not alter the nonzero structure.

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

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

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

6004:    Level: intermediate

6006:    Concepts: matrices^zeroing

6008: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6009: @*/
6010: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6011: {
6013:   PetscInt       numRows;
6014:   const PetscInt *rows;

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

6024:   ISGetLocalSize(is,&numRows);
6025:   ISGetIndices(is,&rows);
6026:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6027:   ISRestoreIndices(is,&rows);
6028:   return(0);
6029: }

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

6037:    Collective on Mat

6039:    Input Parameters:
6040: +  mat - the matrix
6041: .  numRows - the number of rows to remove
6042: .  rows - the global row indices
6043: .  diag - value put in all diagonals of eliminated rows
6044: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6045: -  b - optional vector of right hand side, that will be adjusted by provided solution

6047:    Notes:
6048:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6049:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6055:    Level: intermediate

6057:    Concepts: matrices^zeroing

6059: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6060: @*/
6061: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6062: {
6064:   IS             is, newis;
6065:   const PetscInt *newRows;

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

6075:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6076:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6077:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6078:   ISGetIndices(newis,&newRows);
6079:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6080:   ISRestoreIndices(newis,&newRows);
6081:   ISDestroy(&newis);
6082:   ISDestroy(&is);
6083:   PetscObjectStateIncrease((PetscObject)mat);
6084: #if defined(PETSC_HAVE_CUSP)
6085:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6086:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6087:   }
6088: #endif
6089: #if defined(PETSC_HAVE_VIENNACL)
6090:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6091:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6092:   }
6093: #endif
6094:   return(0);
6095: }

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

6103:    Collective on Mat

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

6112:    Notes:
6113:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6114:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6120:    Level: intermediate

6122:    Concepts: matrices^zeroing

6124: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6125: @*/
6126: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6127: {
6129:   PetscInt       numRows;
6130:   const PetscInt *rows;

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

6140:   ISGetLocalSize(is,&numRows);
6141:   ISGetIndices(is,&rows);
6142:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6143:   ISRestoreIndices(is,&rows);
6144:   return(0);
6145: }

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

6152:    Not Collective

6154:    Input Parameter:
6155: .  mat - the matrix

6157:    Output Parameters:
6158: +  m - the number of global rows
6159: -  n - the number of global columns

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

6163:    Level: beginner

6165:    Concepts: matrices^size

6167: .seealso: MatGetLocalSize()
6168: @*/
6169: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6170: {
6173:   if (m) *m = mat->rmap->N;
6174:   if (n) *n = mat->cmap->N;
6175:   return(0);
6176: }

6180: /*@
6181:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6182:    stored locally.  This information may be implementation dependent, so
6183:    use with care.

6185:    Not Collective

6187:    Input Parameters:
6188: .  mat - the matrix

6190:    Output Parameters:
6191: +  m - the number of local rows
6192: -  n - the number of local columns

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

6196:    Level: beginner

6198:    Concepts: matrices^local size

6200: .seealso: MatGetSize()
6201: @*/
6202: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6203: {
6208:   if (m) *m = mat->rmap->n;
6209:   if (n) *n = mat->cmap->n;
6210:   return(0);
6211: }

6215: /*@
6216:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6217:    this processor. (The columns of the "diagonal block")

6219:    Not Collective, unless matrix has not been allocated, then collective on Mat

6221:    Input Parameters:
6222: .  mat - the matrix

6224:    Output Parameters:
6225: +  m - the global index of the first local column
6226: -  n - one more than the global index of the last local column

6228:    Notes: both output parameters can be NULL on input.

6230:    Level: developer

6232:    Concepts: matrices^column ownership

6234: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

6236: @*/
6237: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6238: {
6244:   MatCheckPreallocated(mat,1);
6245:   if (m) *m = mat->cmap->rstart;
6246:   if (n) *n = mat->cmap->rend;
6247:   return(0);
6248: }

6252: /*@
6253:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6254:    this processor, assuming that the matrix is laid out with the first
6255:    n1 rows on the first processor, the next n2 rows on the second, etc.
6256:    For certain parallel layouts this range may not be well defined.

6258:    Not Collective

6260:    Input Parameters:
6261: .  mat - the matrix

6263:    Output Parameters:
6264: +  m - the global index of the first local row
6265: -  n - one more than the global index of the last local row

6267:    Note: Both output parameters can be NULL on input.
6268: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6269: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6270: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

6272:    Level: beginner

6274:    Concepts: matrices^row ownership

6276: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

6278: @*/
6279: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6280: {
6286:   MatCheckPreallocated(mat,1);
6287:   if (m) *m = mat->rmap->rstart;
6288:   if (n) *n = mat->rmap->rend;
6289:   return(0);
6290: }

6294: /*@C
6295:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6296:    each process

6298:    Not Collective, unless matrix has not been allocated, then collective on Mat

6300:    Input Parameters:
6301: .  mat - the matrix

6303:    Output Parameters:
6304: .  ranges - start of each processors portion plus one more then the total length at the end

6306:    Level: beginner

6308:    Concepts: matrices^row ownership

6310: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6312: @*/
6313: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6314: {

6320:   MatCheckPreallocated(mat,1);
6321:   PetscLayoutGetRanges(mat->rmap,ranges);
6322:   return(0);
6323: }

6327: /*@C
6328:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6329:    this processor. (The columns of the "diagonal blocks" for each process)

6331:    Not Collective, unless matrix has not been allocated, then collective on Mat

6333:    Input Parameters:
6334: .  mat - the matrix

6336:    Output Parameters:
6337: .  ranges - start of each processors portion plus one more then the total length at the end

6339:    Level: beginner

6341:    Concepts: matrices^column ownership

6343: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6345: @*/
6346: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6347: {

6353:   MatCheckPreallocated(mat,1);
6354:   PetscLayoutGetRanges(mat->cmap,ranges);
6355:   return(0);
6356: }

6360: /*@C
6361:    MatGetOwnershipIS - Get row and column ownership as index sets

6363:    Not Collective

6365:    Input Arguments:
6366: .  A - matrix of type Elemental

6368:    Output Arguments:
6369: +  rows - rows in which this process owns elements
6370: .  cols - columns in which this process owns elements

6372:    Level: intermediate

6374: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6375: @*/
6376: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6377: {
6378:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6381:   MatCheckPreallocated(A,1);
6382:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6383:   if (f) {
6384:     (*f)(A,rows,cols);
6385:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6386:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6387:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6388:   }
6389:   return(0);
6390: }

6394: /*@C
6395:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6396:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6397:    to complete the factorization.

6399:    Collective on Mat

6401:    Input Parameters:
6402: +  mat - the matrix
6403: .  row - row permutation
6404: .  column - column permutation
6405: -  info - structure containing
6406: $      levels - number of levels of fill.
6407: $      expected fill - as ratio of original fill.
6408: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6409:                 missing diagonal entries)

6411:    Output Parameters:
6412: .  fact - new matrix that has been symbolically factored

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

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

6420:    Level: developer

6422:   Concepts: matrices^symbolic LU factorization
6423:   Concepts: matrices^factorization
6424:   Concepts: LU^symbolic factorization

6426: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6427:           MatGetOrdering(), MatFactorInfo

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

6432: @*/
6433: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6434: {

6444:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6445:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6446:   if (!(fact)->ops->ilufactorsymbolic) {
6447:     const MatSolverPackage spackage;
6448:     MatFactorGetSolverPackage(fact,&spackage);
6449:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6450:   }
6451:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6452:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6453:   MatCheckPreallocated(mat,2);

6455:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6456:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6457:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6458:   return(0);
6459: }

6463: /*@C
6464:    MatICCFactorSymbolic - Performs symbolic incomplete
6465:    Cholesky factorization for a symmetric matrix.  Use
6466:    MatCholeskyFactorNumeric() to complete the factorization.

6468:    Collective on Mat

6470:    Input Parameters:
6471: +  mat - the matrix
6472: .  perm - row and column permutation
6473: -  info - structure containing
6474: $      levels - number of levels of fill.
6475: $      expected fill - as ratio of original fill.

6477:    Output Parameter:
6478: .  fact - the factored matrix

6480:    Notes:
6481:    Most users should employ the KSP interface for linear solvers
6482:    instead of working directly with matrix algebra routines such as this.
6483:    See, e.g., KSPCreate().

6485:    Level: developer

6487:   Concepts: matrices^symbolic incomplete Cholesky factorization
6488:   Concepts: matrices^factorization
6489:   Concepts: Cholsky^symbolic factorization

6491: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

6496: @*/
6497: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6498: {

6507:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6508:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6509:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6510:   if (!(fact)->ops->iccfactorsymbolic) {
6511:     const MatSolverPackage spackage;
6512:     MatFactorGetSolverPackage(fact,&spackage);
6513:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6514:   }
6515:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6516:   MatCheckPreallocated(mat,2);

6518:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6519:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6520:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6521:   return(0);
6522: }

6526: /*@C
6527:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6528:    points to an array of valid matrices, they may be reused to store the new
6529:    submatrices.

6531:    Collective on Mat

6533:    Input Parameters:
6534: +  mat - the matrix
6535: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6536: .  irow, icol - index sets of rows and columns to extract
6537: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6539:    Output Parameter:
6540: .  submat - the array of submatrices

6542:    Notes:
6543:    MatGetSubMatrices() can extract ONLY sequential submatrices
6544:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6545:    to extract a parallel submatrix.

6547:    Some matrix types place restrictions on the row and column
6548:    indices, such as that they be sorted or that they be equal to each other.

6550:    The index sets may not have duplicate entries.

6552:    When extracting submatrices from a parallel matrix, each processor can
6553:    form a different submatrix by setting the rows and columns of its
6554:    individual index sets according to the local submatrix desired.

6556:    When finished using the submatrices, the user should destroy
6557:    them with MatDestroyMatrices().

6559:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6560:    original matrix has not changed from that last call to MatGetSubMatrices().

6562:    This routine creates the matrices in submat; you should NOT create them before
6563:    calling it. It also allocates the array of matrix pointers submat.

6565:    For BAIJ matrices the index sets must respect the block structure, that is if they
6566:    request one row/column in a block, they must request all rows/columns that are in
6567:    that block. For example, if the block size is 2 you cannot request just row 0 and
6568:    column 0.

6570:    Fortran Note:
6571:    The Fortran interface is slightly different from that given below; it
6572:    requires one to pass in  as submat a Mat (integer) array of size at least m.

6574:    Level: advanced

6576:    Concepts: matrices^accessing submatrices
6577:    Concepts: submatrices

6579: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6580: @*/
6581: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6582: {
6584:   PetscInt       i;
6585:   PetscBool      eq;

6590:   if (n) {
6595:   }
6597:   if (n && scall == MAT_REUSE_MATRIX) {
6600:   }
6601:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6602:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6603:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6604:   MatCheckPreallocated(mat,1);

6606:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6607:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6608:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6609:   for (i=0; i<n; i++) {
6610:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6611:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6612:       ISEqual(irow[i],icol[i],&eq);
6613:       if (eq) {
6614:         if (mat->symmetric) {
6615:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6616:         } else if (mat->hermitian) {
6617:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6618:         } else if (mat->structurally_symmetric) {
6619:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6620:         }
6621:       }
6622:     }
6623:   }
6624:   return(0);
6625: }

6629: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6630: {
6632:   PetscInt       i;
6633:   PetscBool      eq;

6638:   if (n) {
6643:   }
6645:   if (n && scall == MAT_REUSE_MATRIX) {
6648:   }
6649:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6650:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6651:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6652:   MatCheckPreallocated(mat,1);

6654:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6655:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6656:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6657:   for (i=0; i<n; i++) {
6658:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6659:       ISEqual(irow[i],icol[i],&eq);
6660:       if (eq) {
6661:         if (mat->symmetric) {
6662:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6663:         } else if (mat->hermitian) {
6664:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6665:         } else if (mat->structurally_symmetric) {
6666:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6667:         }
6668:       }
6669:     }
6670:   }
6671:   return(0);
6672: }

6676: /*@C
6677:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().

6679:    Collective on Mat

6681:    Input Parameters:
6682: +  n - the number of local matrices
6683: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6684:                        sequence of MatGetSubMatrices())

6686:    Level: advanced

6688:     Notes: Frees not only the matrices, but also the array that contains the matrices
6689:            In Fortran will not free the array.

6691: .seealso: MatGetSubMatrices()
6692: @*/
6693: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6694: {
6696:   PetscInt       i;

6699:   if (!*mat) return(0);
6700:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6702:   for (i=0; i<n; i++) {
6703:     MatDestroy(&(*mat)[i]);
6704:   }
6705:   /* memory is allocated even if n = 0 */
6706:   PetscFree(*mat);
6707:   *mat = NULL;
6708:   return(0);
6709: }

6713: /*@C
6714:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.

6716:    Collective on Mat

6718:    Input Parameters:
6719: .  mat - the matrix

6721:    Output Parameter:
6722: .  matstruct - the sequential matrix with the nonzero structure of mat

6724:   Level: intermediate

6726: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6727: @*/
6728: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6729: {


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

6740:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6741:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6742:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6743:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6744:   return(0);
6745: }

6749: /*@C
6750:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6752:    Collective on Mat

6754:    Input Parameters:
6755: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6756:                        sequence of MatGetSequentialNonzeroStructure())

6758:    Level: advanced

6760:     Notes: Frees not only the matrices, but also the array that contains the matrices

6762: .seealso: MatGetSeqNonzeroStructure()
6763: @*/
6764: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6765: {

6770:   MatDestroy(mat);
6771:   return(0);
6772: }

6776: /*@
6777:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6778:    replaces the index sets by larger ones that represent submatrices with
6779:    additional overlap.

6781:    Collective on Mat

6783:    Input Parameters:
6784: +  mat - the matrix
6785: .  n   - the number of index sets
6786: .  is  - the array of index sets (these index sets will changed during the call)
6787: -  ov  - the additional overlap requested

6789:    Level: developer

6791:    Concepts: overlap
6792:    Concepts: ASM^computing overlap

6794: .seealso: MatGetSubMatrices()
6795: @*/
6796: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6797: {

6803:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6804:   if (n) {
6807:   }
6808:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6809:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6810:   MatCheckPreallocated(mat,1);

6812:   if (!ov) return(0);
6813:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6814:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6815:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6816:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6817:   return(0);
6818: }

6822: /*@
6823:    MatGetBlockSize - Returns the matrix block size.

6825:    Not Collective

6827:    Input Parameter:
6828: .  mat - the matrix

6830:    Output Parameter:
6831: .  bs - block size

6833:    Notes:
6834:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

6836:    If the block size has not been set yet this routine returns 1.

6838:    Level: intermediate

6840:    Concepts: matrices^block size

6842: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6843: @*/
6844: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6845: {
6849:   *bs = PetscAbs(mat->rmap->bs);
6850:   return(0);
6851: }

6855: /*@
6856:    MatGetBlockSizes - Returns the matrix block row and column sizes.

6858:    Not Collective

6860:    Input Parameter:
6861: .  mat - the matrix

6863:    Output Parameter:
6864: .  rbs - row block size
6865: .  cbs - coumn block size

6867:    Notes:
6868:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6869:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

6871:    If a block size has not been set yet this routine returns 1.

6873:    Level: intermediate

6875:    Concepts: matrices^block size

6877: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
6878: @*/
6879: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6880: {
6885:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
6886:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
6887:   return(0);
6888: }

6892: /*@
6893:    MatSetBlockSize - Sets the matrix block size.

6895:    Logically Collective on Mat

6897:    Input Parameters:
6898: +  mat - the matrix
6899: -  bs - block size

6901:    Notes:
6902:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

6904:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6906:    Level: intermediate

6908:    Concepts: matrices^block size

6910: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
6911: @*/
6912: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6913: {

6919:   PetscLayoutSetBlockSize(mat->rmap,bs);
6920:   PetscLayoutSetBlockSize(mat->cmap,bs);
6921:   return(0);
6922: }

6926: /*@
6927:    MatSetBlockSizes - Sets the matrix block row and column sizes.

6929:    Logically Collective on Mat

6931:    Input Parameters:
6932: +  mat - the matrix
6933: -  rbs - row block size
6934: -  cbs - column block size

6936:    Notes:
6937:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6938:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

6940:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6942:     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().

6944:    Level: intermediate

6946:    Concepts: matrices^block size

6948: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
6949: @*/
6950: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6951: {

6958:   PetscLayoutSetBlockSize(mat->rmap,rbs);
6959:   PetscLayoutSetBlockSize(mat->cmap,cbs);
6960:   return(0);
6961: }

6965: /*@
6966:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

6968:    Logically Collective on Mat

6970:    Input Parameters:
6971: +  mat - the matrix
6972: .  fromRow - matrix from which to copy row block size
6973: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

6975:    Level: developer

6977:    Concepts: matrices^block size

6979: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
6980: @*/
6981: PetscErrorCode  MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
6982: {

6989:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
6990:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
6991:   return(0);
6992: }

6996: /*@
6997:    MatResidual - Default routine to calculate the residual.

6999:    Collective on Mat and Vec

7001:    Input Parameters:
7002: +  mat - the matrix
7003: .  b   - the right-hand-side
7004: -  x   - the approximate solution

7006:    Output Parameter:
7007: .  r - location to store the residual

7009:    Level: developer

7011: .keywords: MG, default, multigrid, residual

7013: .seealso: PCMGSetResidual()
7014: @*/
7015: PetscErrorCode  MatResidual(Mat mat,Vec b,Vec x,Vec r)
7016: {

7025:   MatCheckPreallocated(mat,1);
7026:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7027:   if (!mat->ops->residual) {
7028:     MatMult(mat,x,r);
7029:     VecAYPX(r,-1.0,b);
7030:   } else {
7031:     (*mat->ops->residual)(mat,b,x,r);
7032:   }
7033:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7034:   return(0);
7035: }

7039: /*@C
7040:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.

7042:    Collective on Mat

7044:     Input Parameters:
7045: +   mat - the matrix
7046: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7047: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7048: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7049:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7050:                  always used.

7052:     Output Parameters:
7053: +   n - number of rows in the (possibly compressed) matrix
7054: .   ia - the row pointers [of length n+1]
7055: .   ja - the column indices
7056: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7057:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

7059:     Level: developer

7061:     Notes: You CANNOT change any of the ia[] or ja[] values.

7063:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

7065:     Fortran Node

7067:            In Fortran use
7068: $           PetscInt ia(1), ja(1)
7069: $           PetscOffset iia, jja
7070: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7071: $
7072: $          or
7073: $
7074: $           PetscScalar, pointer :: xx_v(:)
7075: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)


7078:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

7080: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7081: @*/
7082: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7083: {

7093:   MatCheckPreallocated(mat,1);
7094:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7095:   else {
7096:     *done = PETSC_TRUE;
7097:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7098:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7099:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7100:   }
7101:   return(0);
7102: }

7106: /*@C
7107:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.

7109:     Collective on Mat

7111:     Input Parameters:
7112: +   mat - the matrix
7113: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7114: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7115:                 symmetrized
7116: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7117:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7118:                  always used.
7119: .   n - number of columns in the (possibly compressed) matrix
7120: .   ia - the column pointers
7121: -   ja - the row indices

7123:     Output Parameters:
7124: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

7126:     Note:
7127:     This routine zeros out n, ia, and ja. This is to prevent accidental
7128:     us of the array after it has been restored. If you pass NULL, it will
7129:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

7131:     Level: developer

7133: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7134: @*/
7135: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7136: {

7146:   MatCheckPreallocated(mat,1);
7147:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7148:   else {
7149:     *done = PETSC_TRUE;
7150:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7151:   }
7152:   return(0);
7153: }

7157: /*@C
7158:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7159:     MatGetRowIJ().

7161:     Collective on Mat

7163:     Input Parameters:
7164: +   mat - the matrix
7165: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7166: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7167:                 symmetrized
7168: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7169:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7170:                  always used.
7171: .   n - size of (possibly compressed) matrix
7172: .   ia - the row pointers
7173: -   ja - the column indices

7175:     Output Parameters:
7176: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7178:     Note:
7179:     This routine zeros out n, ia, and ja. This is to prevent accidental
7180:     us of the array after it has been restored. If you pass NULL, it will
7181:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

7183:     Level: developer

7185: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7186: @*/
7187: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7188: {

7197:   MatCheckPreallocated(mat,1);

7199:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7200:   else {
7201:     *done = PETSC_TRUE;
7202:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7203:     if (n)  *n = 0;
7204:     if (ia) *ia = NULL;
7205:     if (ja) *ja = NULL;
7206:   }
7207:   return(0);
7208: }

7212: /*@C
7213:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7214:     MatGetColumnIJ().

7216:     Collective on Mat

7218:     Input Parameters:
7219: +   mat - the matrix
7220: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7221: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7222:                 symmetrized
7223: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7224:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7225:                  always used.

7227:     Output Parameters:
7228: +   n - size of (possibly compressed) matrix
7229: .   ia - the column pointers
7230: .   ja - the row indices
7231: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7233:     Level: developer

7235: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7236: @*/
7237: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7238: {

7247:   MatCheckPreallocated(mat,1);

7249:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7250:   else {
7251:     *done = PETSC_TRUE;
7252:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7253:     if (n)  *n = 0;
7254:     if (ia) *ia = NULL;
7255:     if (ja) *ja = NULL;
7256:   }
7257:   return(0);
7258: }

7262: /*@C
7263:     MatColoringPatch -Used inside matrix coloring routines that
7264:     use MatGetRowIJ() and/or MatGetColumnIJ().

7266:     Collective on Mat

7268:     Input Parameters:
7269: +   mat - the matrix
7270: .   ncolors - max color value
7271: .   n   - number of entries in colorarray
7272: -   colorarray - array indicating color for each column

7274:     Output Parameters:
7275: .   iscoloring - coloring generated using colorarray information

7277:     Level: developer

7279: .seealso: MatGetRowIJ(), MatGetColumnIJ()

7281: @*/
7282: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7283: {

7291:   MatCheckPreallocated(mat,1);

7293:   if (!mat->ops->coloringpatch) {
7294:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7295:   } else {
7296:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7297:   }
7298:   return(0);
7299: }


7304: /*@
7305:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.

7307:    Logically Collective on Mat

7309:    Input Parameter:
7310: .  mat - the factored matrix to be reset

7312:    Notes:
7313:    This routine should be used only with factored matrices formed by in-place
7314:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7315:    format).  This option can save memory, for example, when solving nonlinear
7316:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7317:    ILU(0) preconditioner.

7319:    Note that one can specify in-place ILU(0) factorization by calling
7320: .vb
7321:      PCType(pc,PCILU);
7322:      PCFactorSeUseInPlace(pc);
7323: .ve
7324:    or by using the options -pc_type ilu -pc_factor_in_place

7326:    In-place factorization ILU(0) can also be used as a local
7327:    solver for the blocks within the block Jacobi or additive Schwarz
7328:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7329:    for details on setting local solver options.

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

7335:    Level: developer

7337: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()

7339:    Concepts: matrices^unfactored

7341: @*/
7342: PetscErrorCode  MatSetUnfactored(Mat mat)
7343: {

7349:   MatCheckPreallocated(mat,1);
7350:   mat->factortype = MAT_FACTOR_NONE;
7351:   if (!mat->ops->setunfactored) return(0);
7352:   (*mat->ops->setunfactored)(mat);
7353:   return(0);
7354: }

7356: /*MC
7357:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7359:     Synopsis:
7360:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7362:     Not collective

7364:     Input Parameter:
7365: .   x - matrix

7367:     Output Parameters:
7368: +   xx_v - the Fortran90 pointer to the array
7369: -   ierr - error code

7371:     Example of Usage:
7372: .vb
7373:       PetscScalar, pointer xx_v(:,:)
7374:       ....
7375:       call MatDenseGetArrayF90(x,xx_v,ierr)
7376:       a = xx_v(3)
7377:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7378: .ve

7380:     Level: advanced

7382: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()

7384:     Concepts: matrices^accessing array

7386: M*/

7388: /*MC
7389:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7390:     accessed with MatDenseGetArrayF90().

7392:     Synopsis:
7393:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7395:     Not collective

7397:     Input Parameters:
7398: +   x - matrix
7399: -   xx_v - the Fortran90 pointer to the array

7401:     Output Parameter:
7402: .   ierr - error code

7404:     Example of Usage:
7405: .vb
7406:        PetscScalar, pointer xx_v(:)
7407:        ....
7408:        call MatDenseGetArrayF90(x,xx_v,ierr)
7409:        a = xx_v(3)
7410:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7411: .ve

7413:     Level: advanced

7415: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()

7417: M*/


7420: /*MC
7421:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7423:     Synopsis:
7424:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7426:     Not collective

7428:     Input Parameter:
7429: .   x - matrix

7431:     Output Parameters:
7432: +   xx_v - the Fortran90 pointer to the array
7433: -   ierr - error code

7435:     Example of Usage:
7436: .vb
7437:       PetscScalar, pointer xx_v(:,:)
7438:       ....
7439:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7440:       a = xx_v(3)
7441:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7442: .ve

7444:     Level: advanced

7446: .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()

7448:     Concepts: matrices^accessing array

7450: M*/

7452: /*MC
7453:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7454:     accessed with MatSeqAIJGetArrayF90().

7456:     Synopsis:
7457:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7459:     Not collective

7461:     Input Parameters:
7462: +   x - matrix
7463: -   xx_v - the Fortran90 pointer to the array

7465:     Output Parameter:
7466: .   ierr - error code

7468:     Example of Usage:
7469: .vb
7470:        PetscScalar, pointer xx_v(:)
7471:        ....
7472:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7473:        a = xx_v(3)
7474:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7475: .ve

7477:     Level: advanced

7479: .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()

7481: M*/


7486: /*@
7487:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7488:                       as the original matrix.

7490:     Collective on Mat

7492:     Input Parameters:
7493: +   mat - the original matrix
7494: .   isrow - parallel IS containing the rows this processor should obtain
7495: .   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.
7496: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7498:     Output Parameter:
7499: .   newmat - the new submatrix, of the same type as the old

7501:     Level: advanced

7503:     Notes:
7504:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7506:     Some matrix types place restrictions on the row and column indices, such
7507:     as that they be sorted or that they be equal to each other.

7509:     The index sets may not have duplicate entries.

7511:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7512:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7513:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7514:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7515:    you are finished using it.

7517:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7518:     the input matrix.

7520:     If iscol is NULL then all columns are obtained (not supported in Fortran).

7522:    Example usage:
7523:    Consider the following 8x8 matrix with 34 non-zero values, that is
7524:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7525:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7526:    as follows:

7528: .vb
7529:             1  2  0  |  0  3  0  |  0  4
7530:     Proc0   0  5  6  |  7  0  0  |  8  0
7531:             9  0 10  | 11  0  0  | 12  0
7532:     -------------------------------------
7533:            13  0 14  | 15 16 17  |  0  0
7534:     Proc1   0 18  0  | 19 20 21  |  0  0
7535:             0  0  0  | 22 23  0  | 24  0
7536:     -------------------------------------
7537:     Proc2  25 26 27  |  0  0 28  | 29  0
7538:            30  0  0  | 31 32 33  |  0 34
7539: .ve

7541:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7543: .vb
7544:             2  0  |  0  3  0  |  0
7545:     Proc0   5  6  |  7  0  0  |  8
7546:     -------------------------------
7547:     Proc1  18  0  | 19 20 21  |  0
7548:     -------------------------------
7549:     Proc2  26 27  |  0  0 28  | 29
7550:             0  0  | 31 32 33  |  0
7551: .ve


7554:     Concepts: matrices^submatrices

7556: .seealso: MatGetSubMatrices()
7557: @*/
7558: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7559: {
7561:   PetscMPIInt    size;
7562:   Mat            *local;
7563:   IS             iscoltmp;

7572:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7573:   MatCheckPreallocated(mat,1);
7574:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7576:   if (!iscol || isrow == iscol) {
7577:     PetscBool stride;
7578:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7579:     if (stride) {
7580:       PetscInt first,step,n,rstart,rend;
7581:       ISStrideGetInfo(isrow,&first,&step);
7582:       if (step == 1) {
7583:         MatGetOwnershipRange(mat,&rstart,&rend);
7584:         if (rstart == first) {
7585:           ISGetLocalSize(isrow,&n);
7586:           if (n == rend-rstart) {
7587:             /* special case grabbing all rows; NEED to do a global reduction to make sure all processes are doing this */
7588:             if (cll == MAT_INITIAL_MATRIX) {
7589:               *newmat = mat;
7590:               PetscObjectReference((PetscObject)mat);
7591:             }
7592:             return(0);
7593:           }
7594:         }
7595:       }
7596:     }
7597:   }

7599:   if (!iscol) {
7600:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7601:   } else {
7602:     iscoltmp = iscol;
7603:   }

7605:   /* if original matrix is on just one processor then use submatrix generated */
7606:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7607:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7608:     if (!iscol) {ISDestroy(&iscoltmp);}
7609:     return(0);
7610:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7611:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7612:     *newmat = *local;
7613:     PetscFree(local);
7614:     if (!iscol) {ISDestroy(&iscoltmp);}
7615:     return(0);
7616:   } else if (!mat->ops->getsubmatrix) {
7617:     /* Create a new matrix type that implements the operation using the full matrix */
7618:     PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7619:     switch (cll) {
7620:     case MAT_INITIAL_MATRIX:
7621:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7622:       break;
7623:     case MAT_REUSE_MATRIX:
7624:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7625:       break;
7626:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7627:     }
7628:     PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7629:     if (!iscol) {ISDestroy(&iscoltmp);}
7630:     return(0);
7631:   }

7633:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7634:   PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7635:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7636:   PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7637:   if (!iscol) {ISDestroy(&iscoltmp);}
7638:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7639:   return(0);
7640: }

7644: /*@
7645:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7646:    used during the assembly process to store values that belong to
7647:    other processors.

7649:    Not Collective

7651:    Input Parameters:
7652: +  mat   - the matrix
7653: .  size  - the initial size of the stash.
7654: -  bsize - the initial size of the block-stash(if used).

7656:    Options Database Keys:
7657: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7658: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7660:    Level: intermediate

7662:    Notes:
7663:      The block-stash is used for values set with MatSetValuesBlocked() while
7664:      the stash is used for values set with MatSetValues()

7666:      Run with the option -info and look for output of the form
7667:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7668:      to determine the appropriate value, MM, to use for size and
7669:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7670:      to determine the value, BMM to use for bsize

7672:    Concepts: stash^setting matrix size
7673:    Concepts: matrices^stash

7675: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7677: @*/
7678: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7679: {

7685:   MatStashSetInitialSize_Private(&mat->stash,size);
7686:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7687:   return(0);
7688: }

7692: /*@
7693:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7694:      the matrix

7696:    Neighbor-wise Collective on Mat

7698:    Input Parameters:
7699: +  mat   - the matrix
7700: .  x,y - the vectors
7701: -  w - where the result is stored

7703:    Level: intermediate

7705:    Notes:
7706:     w may be the same vector as y.

7708:     This allows one to use either the restriction or interpolation (its transpose)
7709:     matrix to do the interpolation

7711:     Concepts: interpolation

7713: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7715: @*/
7716: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7717: {
7719:   PetscInt       M,N,Ny;

7727:   MatCheckPreallocated(A,1);
7728:   MatGetSize(A,&M,&N);
7729:   VecGetSize(y,&Ny);
7730:   if (M == Ny) {
7731:     MatMultAdd(A,x,y,w);
7732:   } else {
7733:     MatMultTransposeAdd(A,x,y,w);
7734:   }
7735:   return(0);
7736: }

7740: /*@
7741:    MatInterpolate - y = A*x or A'*x depending on the shape of
7742:      the matrix

7744:    Neighbor-wise Collective on Mat

7746:    Input Parameters:
7747: +  mat   - the matrix
7748: -  x,y - the vectors

7750:    Level: intermediate

7752:    Notes:
7753:     This allows one to use either the restriction or interpolation (its transpose)
7754:     matrix to do the interpolation

7756:    Concepts: matrices^interpolation

7758: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7760: @*/
7761: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7762: {
7764:   PetscInt       M,N,Ny;

7771:   MatCheckPreallocated(A,1);
7772:   MatGetSize(A,&M,&N);
7773:   VecGetSize(y,&Ny);
7774:   if (M == Ny) {
7775:     MatMult(A,x,y);
7776:   } else {
7777:     MatMultTranspose(A,x,y);
7778:   }
7779:   return(0);
7780: }

7784: /*@
7785:    MatRestrict - y = A*x or A'*x

7787:    Neighbor-wise Collective on Mat

7789:    Input Parameters:
7790: +  mat   - the matrix
7791: -  x,y - the vectors

7793:    Level: intermediate

7795:    Notes:
7796:     This allows one to use either the restriction or interpolation (its transpose)
7797:     matrix to do the restriction

7799:    Concepts: matrices^restriction

7801: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()

7803: @*/
7804: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7805: {
7807:   PetscInt       M,N,Ny;

7814:   MatCheckPreallocated(A,1);

7816:   MatGetSize(A,&M,&N);
7817:   VecGetSize(y,&Ny);
7818:   if (M == Ny) {
7819:     MatMult(A,x,y);
7820:   } else {
7821:     MatMultTranspose(A,x,y);
7822:   }
7823:   return(0);
7824: }

7828: /*@
7829:    MatGetNullSpace - retrieves the null space to a matrix.

7831:    Logically Collective on Mat and MatNullSpace

7833:    Input Parameters:
7834: +  mat - the matrix
7835: -  nullsp - the null space object

7837:    Level: developer

7839:    Notes:
7840:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7842:    Concepts: null space^attaching to matrix

7844: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7845: @*/
7846: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7847: {
7852:   *nullsp = mat->nullsp;
7853:   return(0);
7854: }

7858: /*@
7859:    MatSetNullSpace - attaches a null space to a matrix.
7860:         This null space will be removed from the resulting vector whenever
7861:         MatMult() is called

7863:    Logically Collective on Mat and MatNullSpace

7865:    Input Parameters:
7866: +  mat - the matrix
7867: -  nullsp - the null space object

7869:    Level: advanced

7871:    Notes:
7872:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7874:    Concepts: null space^attaching to matrix

7876: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7877: @*/
7878: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7879: {

7886:   MatCheckPreallocated(mat,1);
7887:   PetscObjectReference((PetscObject)nullsp);
7888:   MatNullSpaceDestroy(&mat->nullsp);

7890:   mat->nullsp = nullsp;
7891:   return(0);
7892: }

7896: /*@
7897:    MatSetNearNullSpace - attaches a null space to a matrix.
7898:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

7900:    Logically Collective on Mat and MatNullSpace

7902:    Input Parameters:
7903: +  mat - the matrix
7904: -  nullsp - the null space object

7906:    Level: advanced

7908:    Notes:
7909:       Overwrites any previous near null space that may have been attached

7911:    Concepts: null space^attaching to matrix

7913: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7914: @*/
7915: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7916: {

7923:   MatCheckPreallocated(mat,1);
7924:   PetscObjectReference((PetscObject)nullsp);
7925:   MatNullSpaceDestroy(&mat->nearnullsp);

7927:   mat->nearnullsp = nullsp;
7928:   return(0);
7929: }

7933: /*@
7934:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

7936:    Not Collective

7938:    Input Parameters:
7939: .  mat - the matrix

7941:    Output Parameters:
7942: .  nullsp - the null space object, NULL if not set

7944:    Level: developer

7946:    Concepts: null space^attaching to matrix

7948: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7949: @*/
7950: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7951: {
7956:   MatCheckPreallocated(mat,1);
7957:   *nullsp = mat->nearnullsp;
7958:   return(0);
7959: }

7963: /*@C
7964:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

7966:    Collective on Mat

7968:    Input Parameters:
7969: +  mat - the matrix
7970: .  row - row/column permutation
7971: .  fill - expected fill factor >= 1.0
7972: -  level - level of fill, for ICC(k)

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

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

7982:    Level: developer

7984:    Concepts: matrices^incomplete Cholesky factorization
7985:    Concepts: Cholesky factorization

7987: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

7992: @*/
7993: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7994: {

8002:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8003:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8004:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8005:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8006:   MatCheckPreallocated(mat,1);
8007:   (*mat->ops->iccfactor)(mat,row,info);
8008:   PetscObjectStateIncrease((PetscObject)mat);
8009:   return(0);
8010: }

8014: /*@
8015:    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.

8017:    Not Collective

8019:    Input Parameters:
8020: +  mat - the matrix
8021: .  nl - leading dimension of v
8022: -  v - the values compute with ADIFOR

8024:    Level: developer

8026:    Notes:
8027:      Must call MatSetColoring() before using this routine. Also this matrix must already
8028:      have its nonzero pattern determined.

8030: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8031:           MatSetValues(), MatSetColoring()
8032: @*/
8033: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8034: {


8042:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8043:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
8044:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8045:   (*mat->ops->setvaluesadifor)(mat,nl,v);
8046:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
8047:   PetscObjectStateIncrease((PetscObject)mat);
8048:   return(0);
8049: }

8053: /*@
8054:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8055:          ghosted ones.

8057:    Not Collective

8059:    Input Parameters:
8060: +  mat - the matrix
8061: -  diag = the diagonal values, including ghost ones

8063:    Level: developer

8065:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

8067: .seealso: MatDiagonalScale()
8068: @*/
8069: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
8070: {
8072:   PetscMPIInt    size;


8079:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8080:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8081:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8082:   if (size == 1) {
8083:     PetscInt n,m;
8084:     VecGetSize(diag,&n);
8085:     MatGetSize(mat,0,&m);
8086:     if (m == n) {
8087:       MatDiagonalScale(mat,0,diag);
8088:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8089:   } else {
8090:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8091:   }
8092:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8093:   PetscObjectStateIncrease((PetscObject)mat);
8094:   return(0);
8095: }

8099: /*@
8100:    MatGetInertia - Gets the inertia from a factored matrix

8102:    Collective on Mat

8104:    Input Parameter:
8105: .  mat - the matrix

8107:    Output Parameters:
8108: +   nneg - number of negative eigenvalues
8109: .   nzero - number of zero eigenvalues
8110: -   npos - number of positive eigenvalues

8112:    Level: advanced

8114:    Notes: Matrix must have been factored by MatCholeskyFactor()


8117: @*/
8118: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8119: {

8125:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8126:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8127:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8128:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8129:   return(0);
8130: }

8132: /* ----------------------------------------------------------------*/
8135: /*@C
8136:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

8138:    Neighbor-wise Collective on Mat and Vecs

8140:    Input Parameters:
8141: +  mat - the factored matrix
8142: -  b - the right-hand-side vectors

8144:    Output Parameter:
8145: .  x - the result vectors

8147:    Notes:
8148:    The vectors b and x cannot be the same.  I.e., one cannot
8149:    call MatSolves(A,x,x).

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

8156:    Level: developer

8158:    Concepts: matrices^triangular solves

8160: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8161: @*/
8162: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
8163: {

8169:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8170:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8171:   if (!mat->rmap->N && !mat->cmap->N) return(0);

8173:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8174:   MatCheckPreallocated(mat,1);
8175:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8176:   (*mat->ops->solves)(mat,b,x);
8177:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8178:   return(0);
8179: }

8183: /*@
8184:    MatIsSymmetric - Test whether a matrix is symmetric

8186:    Collective on Mat

8188:    Input Parameter:
8189: +  A - the matrix to test
8190: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

8192:    Output Parameters:
8193: .  flg - the result

8195:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

8197:    Level: intermediate

8199:    Concepts: matrix^symmetry

8201: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8202: @*/
8203: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8204: {


8211:   if (!A->symmetric_set) {
8212:     if (!A->ops->issymmetric) {
8213:       MatType mattype;
8214:       MatGetType(A,&mattype);
8215:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8216:     }
8217:     (*A->ops->issymmetric)(A,tol,flg);
8218:     if (!tol) {
8219:       A->symmetric_set = PETSC_TRUE;
8220:       A->symmetric     = *flg;
8221:       if (A->symmetric) {
8222:         A->structurally_symmetric_set = PETSC_TRUE;
8223:         A->structurally_symmetric     = PETSC_TRUE;
8224:       }
8225:     }
8226:   } else if (A->symmetric) {
8227:     *flg = PETSC_TRUE;
8228:   } else if (!tol) {
8229:     *flg = PETSC_FALSE;
8230:   } else {
8231:     if (!A->ops->issymmetric) {
8232:       MatType mattype;
8233:       MatGetType(A,&mattype);
8234:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8235:     }
8236:     (*A->ops->issymmetric)(A,tol,flg);
8237:   }
8238:   return(0);
8239: }

8243: /*@
8244:    MatIsHermitian - Test whether a matrix is Hermitian

8246:    Collective on Mat

8248:    Input Parameter:
8249: +  A - the matrix to test
8250: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

8252:    Output Parameters:
8253: .  flg - the result

8255:    Level: intermediate

8257:    Concepts: matrix^symmetry

8259: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8260:           MatIsSymmetricKnown(), MatIsSymmetric()
8261: @*/
8262: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8263: {


8270:   if (!A->hermitian_set) {
8271:     if (!A->ops->ishermitian) {
8272:       MatType mattype;
8273:       MatGetType(A,&mattype);
8274:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8275:     }
8276:     (*A->ops->ishermitian)(A,tol,flg);
8277:     if (!tol) {
8278:       A->hermitian_set = PETSC_TRUE;
8279:       A->hermitian     = *flg;
8280:       if (A->hermitian) {
8281:         A->structurally_symmetric_set = PETSC_TRUE;
8282:         A->structurally_symmetric     = PETSC_TRUE;
8283:       }
8284:     }
8285:   } else if (A->hermitian) {
8286:     *flg = PETSC_TRUE;
8287:   } else if (!tol) {
8288:     *flg = PETSC_FALSE;
8289:   } else {
8290:     if (!A->ops->ishermitian) {
8291:       MatType mattype;
8292:       MatGetType(A,&mattype);
8293:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8294:     }
8295:     (*A->ops->ishermitian)(A,tol,flg);
8296:   }
8297:   return(0);
8298: }

8302: /*@
8303:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

8305:    Not Collective

8307:    Input Parameter:
8308: .  A - the matrix to check

8310:    Output Parameters:
8311: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8312: -  flg - the result

8314:    Level: advanced

8316:    Concepts: matrix^symmetry

8318:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8319:          if you want it explicitly checked

8321: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8322: @*/
8323: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8324: {
8329:   if (A->symmetric_set) {
8330:     *set = PETSC_TRUE;
8331:     *flg = A->symmetric;
8332:   } else {
8333:     *set = PETSC_FALSE;
8334:   }
8335:   return(0);
8336: }

8340: /*@
8341:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8343:    Not Collective

8345:    Input Parameter:
8346: .  A - the matrix to check

8348:    Output Parameters:
8349: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8350: -  flg - the result

8352:    Level: advanced

8354:    Concepts: matrix^symmetry

8356:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8357:          if you want it explicitly checked

8359: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8360: @*/
8361: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8362: {
8367:   if (A->hermitian_set) {
8368:     *set = PETSC_TRUE;
8369:     *flg = A->hermitian;
8370:   } else {
8371:     *set = PETSC_FALSE;
8372:   }
8373:   return(0);
8374: }

8378: /*@
8379:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8381:    Collective on Mat

8383:    Input Parameter:
8384: .  A - the matrix to test

8386:    Output Parameters:
8387: .  flg - the result

8389:    Level: intermediate

8391:    Concepts: matrix^symmetry

8393: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8394: @*/
8395: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8396: {

8402:   if (!A->structurally_symmetric_set) {
8403:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8404:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);

8406:     A->structurally_symmetric_set = PETSC_TRUE;
8407:   }
8408:   *flg = A->structurally_symmetric;
8409:   return(0);
8410: }

8414: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8415: /*@
8416:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8417:        to be communicated to other processors during the MatAssemblyBegin/End() process

8419:     Not collective

8421:    Input Parameter:
8422: .   vec - the vector

8424:    Output Parameters:
8425: +   nstash   - the size of the stash
8426: .   reallocs - the number of additional mallocs incurred.
8427: .   bnstash   - the size of the block stash
8428: -   breallocs - the number of additional mallocs incurred.in the block stash

8430:    Level: advanced

8432: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()

8434: @*/
8435: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8436: {

8440:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8441:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8442:   return(0);
8443: }

8447: /*@C
8448:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8449:      parallel layout

8451:    Collective on Mat

8453:    Input Parameter:
8454: .  mat - the matrix

8456:    Output Parameter:
8457: +   right - (optional) vector that the matrix can be multiplied against
8458: -   left - (optional) vector that the matrix vector product can be stored in

8460:    Notes:
8461:     The blocksize of the returned vectors is determined by the row and column block sizes set with MatSetBlockSizes() or the single blocksize (same for both) set by MatSetBlockSize().

8463:   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed

8465:   Level: advanced

8467: .seealso: MatCreate(), VecDestroy()
8468: @*/
8469: PetscErrorCode  MatCreateVecs(Mat mat,Vec *right,Vec *left)
8470: {

8476:   MatCheckPreallocated(mat,1);
8477:   if (mat->ops->getvecs) {
8478:     (*mat->ops->getvecs)(mat,right,left);
8479:   } else {
8480:     PetscMPIInt size;
8481:     PetscInt    rbs,cbs;
8482:     MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8483:     MatGetBlockSizes(mat,&rbs,&cbs);
8484:     if (right) {
8485:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8486:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8487:       VecSetBlockSize(*right,cbs);
8488:       VecSetType(*right,VECSTANDARD);
8489:       PetscLayoutReference(mat->cmap,&(*right)->map);
8490:     }
8491:     if (left) {
8492:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8493:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8494:       VecSetBlockSize(*left,rbs);
8495:       VecSetType(*left,VECSTANDARD);
8496:       PetscLayoutReference(mat->rmap,&(*left)->map);
8497:     }
8498:   }
8499:   return(0);
8500: }

8504: /*@C
8505:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8506:      with default values.

8508:    Not Collective

8510:    Input Parameters:
8511: .    info - the MatFactorInfo data structure


8514:    Notes: The solvers are generally used through the KSP and PC objects, for example
8515:           PCLU, PCILU, PCCHOLESKY, PCICC

8517:    Level: developer

8519: .seealso: MatFactorInfo

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

8524: @*/

8526: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8527: {

8531:   PetscMemzero(info,sizeof(MatFactorInfo));
8532:   return(0);
8533: }

8537: /*@
8538:    MatPtAP - Creates the matrix product C = P^T * A * P

8540:    Neighbor-wise Collective on Mat

8542:    Input Parameters:
8543: +  A - the matrix
8544: .  P - the projection matrix
8545: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8546: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

8548:    Output Parameters:
8549: .  C - the product matrix

8551:    Notes:
8552:    C will be created and must be destroyed by the user with MatDestroy().

8554:    This routine is currently only implemented for pairs of AIJ matrices and classes
8555:    which inherit from AIJ.

8557:    Level: intermediate

8559: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8560: @*/
8561: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8562: {
8564:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8565:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8566:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8567:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

8570:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8571:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

8575:   MatCheckPreallocated(A,1);
8576:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8577:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8580:   MatCheckPreallocated(P,2);
8581:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8582:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8584:   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);
8585:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8587:   if (scall == MAT_REUSE_MATRIX) {
8590:     if (viatranspose || viamatmatmatmult) {
8591:       Mat Pt;
8592:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8593:       if (viamatmatmatmult) {
8594:         MatMatMatMult(Pt,A,P,scall,fill,C);
8595:       } else {
8596:         Mat AP;
8597:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8598:         MatMatMult(Pt,AP,scall,fill,C);
8599:         MatDestroy(&AP);
8600:       }
8601:       MatDestroy(&Pt);
8602:     } else {
8603:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8604:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8605:       (*(*C)->ops->ptapnumeric)(A,P,*C);
8606:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8607:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8608:     }
8609:     return(0);
8610:   }

8612:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8613:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8615:   fA = A->ops->ptap;
8616:   fP = P->ops->ptap;
8617:   if (fP == fA) {
8618:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8619:     ptap = fA;
8620:   } else {
8621:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8622:     char ptapname[256];
8623:     PetscStrcpy(ptapname,"MatPtAP_");
8624:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
8625:     PetscStrcat(ptapname,"_");
8626:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
8627:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8628:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8629:     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);
8630:   }

8632:   if (viatranspose || viamatmatmatmult) {
8633:     Mat Pt;
8634:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8635:     if (viamatmatmatmult) {
8636:       MatMatMatMult(Pt,A,P,scall,fill,C);
8637:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8638:     } else {
8639:       Mat AP;
8640:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8641:       MatMatMult(Pt,AP,scall,fill,C);
8642:       MatDestroy(&AP);
8643:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8644:     }
8645:     MatDestroy(&Pt);
8646:   } else {
8647:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8648:     (*ptap)(A,P,scall,fill,C);
8649:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8650:   }
8651:   return(0);
8652: }

8656: /*@
8657:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

8659:    Neighbor-wise Collective on Mat

8661:    Input Parameters:
8662: +  A - the matrix
8663: -  P - the projection matrix

8665:    Output Parameters:
8666: .  C - the product matrix

8668:    Notes:
8669:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8670:    the user using MatDeatroy().

8672:    This routine is currently only implemented for pairs of AIJ matrices and classes
8673:    which inherit from AIJ.  C will be of type MATAIJ.

8675:    Level: intermediate

8677: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8678: @*/
8679: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8680: {

8686:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8687:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8690:   MatCheckPreallocated(P,2);
8691:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8692:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8695:   MatCheckPreallocated(C,3);
8696:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8697:   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);
8698:   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);
8699:   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);
8700:   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);
8701:   MatCheckPreallocated(A,1);

8703:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8704:   (*C->ops->ptapnumeric)(A,P,C);
8705:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8706:   return(0);
8707: }

8711: /*@
8712:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

8714:    Neighbor-wise Collective on Mat

8716:    Input Parameters:
8717: +  A - the matrix
8718: -  P - the projection matrix

8720:    Output Parameters:
8721: .  C - the (i,j) structure of the product matrix

8723:    Notes:
8724:    C will be created and must be destroyed by the user with MatDestroy().

8726:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8727:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8728:    this (i,j) structure by calling MatPtAPNumeric().

8730:    Level: intermediate

8732: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8733: @*/
8734: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8735: {

8741:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8742:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8743:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8746:   MatCheckPreallocated(P,2);
8747:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8748:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8751:   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);
8752:   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);
8753:   MatCheckPreallocated(A,1);
8754:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8755:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8756:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

8758:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8759:   return(0);
8760: }

8764: /*@
8765:    MatRARt - Creates the matrix product C = R * A * R^T

8767:    Neighbor-wise Collective on Mat

8769:    Input Parameters:
8770: +  A - the matrix
8771: .  R - the projection matrix
8772: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8773: -  fill - expected fill as ratio of nnz(C)/nnz(A)

8775:    Output Parameters:
8776: .  C - the product matrix

8778:    Notes:
8779:    C will be created and must be destroyed by the user with MatDestroy().

8781:    This routine is currently only implemented for pairs of AIJ matrices and classes
8782:    which inherit from AIJ.

8784:    Level: intermediate

8786: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8787: @*/
8788: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8789: {

8795:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8796:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8799:   MatCheckPreallocated(R,2);
8800:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8801:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8803:   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);
8804:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8805:   MatCheckPreallocated(A,1);

8807:   if (!A->ops->rart) {
8808:     MatType mattype;
8809:     MatGetType(A,&mattype);
8810:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8811:   }
8812:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
8813:   (*A->ops->rart)(A,R,scall,fill,C);
8814:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
8815:   return(0);
8816: }

8820: /*@
8821:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

8823:    Neighbor-wise Collective on Mat

8825:    Input Parameters:
8826: +  A - the matrix
8827: -  R - the projection matrix

8829:    Output Parameters:
8830: .  C - the product matrix

8832:    Notes:
8833:    C must have been created by calling MatRARtSymbolic and must be destroyed by
8834:    the user using MatDeatroy().

8836:    This routine is currently only implemented for pairs of AIJ matrices and classes
8837:    which inherit from AIJ.  C will be of type MATAIJ.

8839:    Level: intermediate

8841: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8842: @*/
8843: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8844: {

8850:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8851:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8854:   MatCheckPreallocated(R,2);
8855:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8856:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8859:   MatCheckPreallocated(C,3);
8860:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8861:   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);
8862:   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);
8863:   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);
8864:   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);
8865:   MatCheckPreallocated(A,1);

8867:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8868:   (*A->ops->rartnumeric)(A,R,C);
8869:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8870:   return(0);
8871: }

8875: /*@
8876:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

8878:    Neighbor-wise Collective on Mat

8880:    Input Parameters:
8881: +  A - the matrix
8882: -  R - the projection matrix

8884:    Output Parameters:
8885: .  C - the (i,j) structure of the product matrix

8887:    Notes:
8888:    C will be created and must be destroyed by the user with MatDestroy().

8890:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8891:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8892:    this (i,j) structure by calling MatRARtNumeric().

8894:    Level: intermediate

8896: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8897: @*/
8898: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8899: {

8905:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8906:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8907:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8910:   MatCheckPreallocated(R,2);
8911:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8912:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8915:   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);
8916:   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);
8917:   MatCheckPreallocated(A,1);
8918:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8919:   (*A->ops->rartsymbolic)(A,R,fill,C);
8920:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

8922:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
8923:   return(0);
8924: }

8928: /*@
8929:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

8931:    Neighbor-wise Collective on Mat

8933:    Input Parameters:
8934: +  A - the left matrix
8935: .  B - the right matrix
8936: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8937: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8938:           if the result is a dense matrix this is irrelevent

8940:    Output Parameters:
8941: .  C - the product matrix

8943:    Notes:
8944:    Unless scall is MAT_REUSE_MATRIX C will be created.

8946:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8948:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8949:    actually needed.

8951:    If you have many matrices with the same non-zero structure to multiply, you
8952:    should either
8953: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8954: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

8956:    Level: intermediate

8958: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8959: @*/
8960: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8961: {
8963:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8964:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8965:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

8970:   MatCheckPreallocated(A,1);
8971:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8972:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8975:   MatCheckPreallocated(B,2);
8976:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8977:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8979:   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);
8980:   if (scall == MAT_REUSE_MATRIX) {
8983:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8984:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8985:     (*(*C)->ops->matmultnumeric)(A,B,*C);
8986:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8987:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8988:     return(0);
8989:   }
8990:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8991:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8993:   fA = A->ops->matmult;
8994:   fB = B->ops->matmult;
8995:   if (fB == fA) {
8996:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8997:     mult = fB;
8998:   } else {
8999:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9000:     char multname[256];
9001:     PetscStrcpy(multname,"MatMatMult_");
9002:     PetscStrcat(multname,((PetscObject)A)->type_name);
9003:     PetscStrcat(multname,"_");
9004:     PetscStrcat(multname,((PetscObject)B)->type_name);
9005:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9006:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9007:     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);
9008:   }
9009:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9010:   (*mult)(A,B,scall,fill,C);
9011:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9012:   return(0);
9013: }

9017: /*@
9018:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9019:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

9021:    Neighbor-wise Collective on Mat

9023:    Input Parameters:
9024: +  A - the left matrix
9025: .  B - the right matrix
9026: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9027:       if C is a dense matrix this is irrelevent

9029:    Output Parameters:
9030: .  C - the product matrix

9032:    Notes:
9033:    Unless scall is MAT_REUSE_MATRIX C will be created.

9035:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9036:    actually needed.

9038:    This routine is currently implemented for
9039:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9040:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9041:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9043:    Level: intermediate

9045:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9046:      We should incorporate them into PETSc.

9048: .seealso: MatMatMult(), MatMatMultNumeric()
9049: @*/
9050: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9051: {
9053:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9054:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9055:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

9060:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9061:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9065:   MatCheckPreallocated(B,2);
9066:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9067:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9070:   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);
9071:   if (fill == PETSC_DEFAULT) fill = 2.0;
9072:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9073:   MatCheckPreallocated(A,1);

9075:   Asymbolic = A->ops->matmultsymbolic;
9076:   Bsymbolic = B->ops->matmultsymbolic;
9077:   if (Asymbolic == Bsymbolic) {
9078:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9079:     symbolic = Bsymbolic;
9080:   } else { /* dispatch based on the type of A and B */
9081:     char symbolicname[256];
9082:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9083:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9084:     PetscStrcat(symbolicname,"_");
9085:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9086:     PetscStrcat(symbolicname,"_C");
9087:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9088:     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);
9089:   }
9090:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9091:   (*symbolic)(A,B,fill,C);
9092:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9093:   return(0);
9094: }

9098: /*@
9099:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9100:    Call this routine after first calling MatMatMultSymbolic().

9102:    Neighbor-wise Collective on Mat

9104:    Input Parameters:
9105: +  A - the left matrix
9106: -  B - the right matrix

9108:    Output Parameters:
9109: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

9111:    Notes:
9112:    C must have been created with MatMatMultSymbolic().

9114:    This routine is currently implemented for
9115:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9116:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9117:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9119:    Level: intermediate

9121: .seealso: MatMatMult(), MatMatMultSymbolic()
9122: @*/
9123: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
9124: {

9128:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9129:   return(0);
9130: }

9134: /*@
9135:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

9137:    Neighbor-wise Collective on Mat

9139:    Input Parameters:
9140: +  A - the left matrix
9141: .  B - the right matrix
9142: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9143: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9145:    Output Parameters:
9146: .  C - the product matrix

9148:    Notes:
9149:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

9151:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9153:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9154:    actually needed.

9156:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

9158:    Level: intermediate

9160: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9161: @*/
9162: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9163: {
9165:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9166:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

9171:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9172:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9175:   MatCheckPreallocated(B,2);
9176:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9177:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9179:   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);
9180:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9181:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9182:   MatCheckPreallocated(A,1);

9184:   fA = A->ops->mattransposemult;
9185:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9186:   fB = B->ops->mattransposemult;
9187:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9188:   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);

9190:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9191:   if (scall == MAT_INITIAL_MATRIX) {
9192:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9193:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9194:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9195:   }
9196:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9197:   (*A->ops->mattransposemultnumeric)(A,B,*C);
9198:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9199:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9200:   return(0);
9201: }

9205: /*@
9206:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

9208:    Neighbor-wise Collective on Mat

9210:    Input Parameters:
9211: +  A - the left matrix
9212: .  B - the right matrix
9213: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9214: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9216:    Output Parameters:
9217: .  C - the product matrix

9219:    Notes:
9220:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

9222:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9224:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9225:    actually needed.

9227:    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9228:    which inherit from SeqAIJ.  C will be of same type as the input matrices.

9230:    Level: intermediate

9232: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9233: @*/
9234: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9235: {
9237:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9238:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9239:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

9244:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9245:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9248:   MatCheckPreallocated(B,2);
9249:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9250:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9252:   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);
9253:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9254:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9255:   MatCheckPreallocated(A,1);

9257:   fA = A->ops->transposematmult;
9258:   fB = B->ops->transposematmult;
9259:   if (fB==fA) {
9260:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9261:     transposematmult = fA;
9262:   } else {
9263:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9264:     char multname[256];
9265:     PetscStrcpy(multname,"MatTransposeMatMult_");
9266:     PetscStrcat(multname,((PetscObject)A)->type_name);
9267:     PetscStrcat(multname,"_");
9268:     PetscStrcat(multname,((PetscObject)B)->type_name);
9269:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9270:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9271:     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);
9272:   }
9273:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9274:   (*transposematmult)(A,B,scall,fill,C);
9275:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9276:   return(0);
9277: }

9281: /*@
9282:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

9284:    Neighbor-wise Collective on Mat

9286:    Input Parameters:
9287: +  A - the left matrix
9288: .  B - the middle matrix
9289: .  C - the right matrix
9290: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9291: -  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
9292:           if the result is a dense matrix this is irrelevent

9294:    Output Parameters:
9295: .  D - the product matrix

9297:    Notes:
9298:    Unless scall is MAT_REUSE_MATRIX D will be created.

9300:    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call

9302:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9303:    actually needed.

9305:    If you have many matrices with the same non-zero structure to multiply, you
9306:    should either
9307: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9308: $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed

9310:    Level: intermediate

9312: .seealso: MatMatMult, MatPtAP()
9313: @*/
9314: PetscErrorCode  MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9315: {
9317:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9318:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9319:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9320:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9325:   MatCheckPreallocated(A,1);
9326:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9327:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9330:   MatCheckPreallocated(B,2);
9331:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9332:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9335:   MatCheckPreallocated(C,3);
9336:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9337:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9338:   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);
9339:   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);
9340:   if (scall == MAT_REUSE_MATRIX) {
9343:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9344:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9345:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9346:     return(0);
9347:   }
9348:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9349:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9351:   fA = A->ops->matmatmult;
9352:   fB = B->ops->matmatmult;
9353:   fC = C->ops->matmatmult;
9354:   if (fA == fB && fA == fC) {
9355:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9356:     mult = fA;
9357:   } else {
9358:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9359:     char multname[256];
9360:     PetscStrcpy(multname,"MatMatMatMult_");
9361:     PetscStrcat(multname,((PetscObject)A)->type_name);
9362:     PetscStrcat(multname,"_");
9363:     PetscStrcat(multname,((PetscObject)B)->type_name);
9364:     PetscStrcat(multname,"_");
9365:     PetscStrcat(multname,((PetscObject)C)->type_name);
9366:     PetscStrcat(multname,"_C");
9367:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9368:     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);
9369:   }
9370:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9371:   (*mult)(A,B,C,scall,fill,D);
9372:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9373:   return(0);
9374: }

9378: /*@C
9379:    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

9381:    Collective on Mat

9383:    Input Parameters:
9384: +  mat - the matrix
9385: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9386: .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9387: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9389:    Output Parameter:
9390: .  matredundant - redundant matrix

9392:    Notes:
9393:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9394:    original matrix has not changed from that last call to MatCreateRedundantMatrix().

9396:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9397:    calling it.

9399:    Level: advanced

9401:    Concepts: subcommunicator
9402:    Concepts: duplicate matrix

9404: .seealso: MatDestroy()
9405: @*/
9406: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9407: {
9409:   MPI_Comm       comm;
9410:   PetscMPIInt    size;
9411:   PetscInt       mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9412:   Mat_Redundant  *redund=NULL;
9413:   PetscSubcomm   psubcomm=NULL;
9414:   MPI_Comm       subcomm_in=subcomm;
9415:   Mat            *matseq;
9416:   IS             isrow,iscol;
9417:   PetscBool      newsubcomm=PETSC_FALSE;
9418: 
9420:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
9421:   if (size == 1 || nsubcomm == 1) {
9422:     if (reuse == MAT_INITIAL_MATRIX) {
9423:       MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
9424:     } else {
9425:       MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
9426:     }
9427:     return(0);
9428:   }

9431:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9434:   }
9435:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9436:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9437:   MatCheckPreallocated(mat,1);

9439:   PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
9440:   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9441:     /* create psubcomm, then get subcomm */
9442:     PetscObjectGetComm((PetscObject)mat,&comm);
9443:     MPI_Comm_size(comm,&size);
9444:     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);

9446:     PetscSubcommCreate(comm,&psubcomm);
9447:     PetscSubcommSetNumber(psubcomm,nsubcomm);
9448:     PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
9449:     PetscSubcommSetFromOptions(psubcomm);
9450:     PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);
9451:     newsubcomm = PETSC_TRUE;
9452:     PetscSubcommDestroy(&psubcomm);
9453:   }

9455:   /* get isrow, iscol and a local sequential matrix matseq[0] */
9456:   if (reuse == MAT_INITIAL_MATRIX) {
9457:     mloc_sub = PETSC_DECIDE;
9458:     if (bs < 1) {
9459:       PetscSplitOwnership(subcomm,&mloc_sub,&M);
9460:     } else {
9461:       PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
9462:     }
9463:     MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
9464:     rstart = rend - mloc_sub;
9465:     ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
9466:     ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
9467:   } else { /* reuse == MAT_REUSE_MATRIX */
9468:     /* retrieve subcomm */
9469:     PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
9470:     redund = (*matredundant)->redundant;
9471:     isrow  = redund->isrow;
9472:     iscol  = redund->iscol;
9473:     matseq = redund->matseq;
9474:   }
9475:   MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);
9476: 
9477:   /* get matredundant over subcomm */
9478:   if (reuse == MAT_INITIAL_MATRIX) {
9479:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);

9481:     /* create a supporting struct and attach it to C for reuse */
9482:     PetscNewLog(*matredundant,&redund);
9483:     (*matredundant)->redundant = redund;
9484:     redund->isrow              = isrow;
9485:     redund->iscol              = iscol;
9486:     redund->matseq             = matseq;
9487:     if (newsubcomm) {
9488:       redund->subcomm          = subcomm;
9489:     } else {
9490:       redund->subcomm          = MPI_COMM_NULL;
9491:     }
9492:   } else {
9493:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
9494:   }
9495:   PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
9496:   return(0);
9497: }

9501: /*@C
9502:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9503:    a given 'mat' object. Each submatrix can span multiple procs.

9505:    Collective on Mat

9507:    Input Parameters:
9508: +  mat - the matrix
9509: .  subcomm - the subcommunicator obtained by com_split(comm)
9510: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9512:    Output Parameter:
9513: .  subMat - 'parallel submatrices each spans a given subcomm

9515:   Notes:
9516:   The submatrix partition across processors is dictated by 'subComm' a
9517:   communicator obtained by com_split(comm). The comm_split
9518:   is not restriced to be grouped with consecutive original ranks.

9520:   Due the comm_split() usage, the parallel layout of the submatrices
9521:   map directly to the layout of the original matrix [wrt the local
9522:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9523:   into the 'DiagonalMat' of the subMat, hence it is used directly from
9524:   the subMat. However the offDiagMat looses some columns - and this is
9525:   reconstructed with MatSetValues()

9527:   Level: advanced

9529:   Concepts: subcommunicator
9530:   Concepts: submatrices

9532: .seealso: MatGetSubMatrices()
9533: @*/
9534: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9535: {
9537:   PetscMPIInt    commsize,subCommSize;

9540:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9541:   MPI_Comm_size(subComm,&subCommSize);
9542:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

9544:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9545:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9546:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9547:   return(0);
9548: }

9552: /*@
9553:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

9555:    Not Collective

9557:    Input Arguments:
9558:    mat - matrix to extract local submatrix from
9559:    isrow - local row indices for submatrix
9560:    iscol - local column indices for submatrix

9562:    Output Arguments:
9563:    submat - the submatrix

9565:    Level: intermediate

9567:    Notes:
9568:    The submat should be returned with MatRestoreLocalSubMatrix().

9570:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9571:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

9573:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9574:    MatSetValuesBlockedLocal() will also be implemented.

9576: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9577: @*/
9578: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9579: {


9589:   if (mat->ops->getlocalsubmatrix) {
9590:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9591:   } else {
9592:     MatCreateLocalRef(mat,isrow,iscol,submat);
9593:   }
9594:   return(0);
9595: }

9599: /*@
9600:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

9602:    Not Collective

9604:    Input Arguments:
9605:    mat - matrix to extract local submatrix from
9606:    isrow - local row indices for submatrix
9607:    iscol - local column indices for submatrix
9608:    submat - the submatrix

9610:    Level: intermediate

9612: .seealso: MatGetLocalSubMatrix()
9613: @*/
9614: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9615: {

9624:   if (*submat) {
9626:   }

9628:   if (mat->ops->restorelocalsubmatrix) {
9629:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9630:   } else {
9631:     MatDestroy(submat);
9632:   }
9633:   *submat = NULL;
9634:   return(0);
9635: }

9637: /* --------------------------------------------------------*/
9640: /*@
9641:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

9643:    Collective on Mat

9645:    Input Parameter:
9646: .  mat - the matrix

9648:    Output Parameter:
9649: .  is - if any rows have zero diagonals this contains the list of them

9651:    Level: developer

9653:    Concepts: matrix-vector product

9655: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9656: @*/
9657: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9658: {

9664:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9665:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9667:   if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9668:   (*mat->ops->findzerodiagonals)(mat,is);
9669:   return(0);
9670: }

9674: /*@
9675:    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)

9677:    Collective on Mat

9679:    Input Parameter:
9680: .  mat - the matrix

9682:    Output Parameter:
9683: .  is - contains the list of rows with off block diagonal entries

9685:    Level: developer

9687:    Concepts: matrix-vector product

9689: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9690: @*/
9691: PetscErrorCode  MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
9692: {

9698:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9699:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9701:   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
9702:   (*mat->ops->findoffblockdiagonalentries)(mat,is);
9703:   return(0);
9704: }

9708: /*@C
9709:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

9711:   Collective on Mat

9713:   Input Parameters:
9714: . mat - the matrix

9716:   Output Parameters:
9717: . values - the block inverses in column major order (FORTRAN-like)

9719:    Note:
9720:    This routine is not available from Fortran.

9722:   Level: advanced
9723: @*/
9724: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9725: {

9730:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9731:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9732:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9733:   (*mat->ops->invertblockdiagonal)(mat,values);
9734:   return(0);
9735: }

9739: /*@C
9740:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9741:     via MatTransposeColoringCreate().

9743:     Collective on MatTransposeColoring

9745:     Input Parameter:
9746: .   c - coloring context

9748:     Level: intermediate

9750: .seealso: MatTransposeColoringCreate()
9751: @*/
9752: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9753: {
9754:   PetscErrorCode       ierr;
9755:   MatTransposeColoring matcolor=*c;

9758:   if (!matcolor) return(0);
9759:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

9761:   PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
9762:   PetscFree(matcolor->rows);
9763:   PetscFree(matcolor->den2sp);
9764:   PetscFree(matcolor->colorforcol);
9765:   PetscFree(matcolor->columns);
9766:   if (matcolor->brows>0) {
9767:     PetscFree(matcolor->lstart);
9768:   }
9769:   PetscHeaderDestroy(c);
9770:   return(0);
9771: }

9775: /*@C
9776:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9777:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9778:     MatTransposeColoring to sparse B.

9780:     Collective on MatTransposeColoring

9782:     Input Parameters:
9783: +   B - sparse matrix B
9784: .   Btdense - symbolic dense matrix B^T
9785: -   coloring - coloring context created with MatTransposeColoringCreate()

9787:     Output Parameter:
9788: .   Btdense - dense matrix B^T

9790:     Options Database Keys:
9791: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9792: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9793: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

9795:     Level: intermediate

9797: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

9799: .keywords: coloring
9800: @*/
9801: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9802: {


9810:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9811:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9812:   return(0);
9813: }

9817: /*@C
9818:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9819:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9820:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9821:     Csp from Cden.

9823:     Collective on MatTransposeColoring

9825:     Input Parameters:
9826: +   coloring - coloring context created with MatTransposeColoringCreate()
9827: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

9829:     Output Parameter:
9830: .   Csp - sparse matrix

9832:     Options Database Keys:
9833: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9834: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9835: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

9837:     Level: intermediate

9839: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

9841: .keywords: coloring
9842: @*/
9843: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9844: {


9852:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9853:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9854:   return(0);
9855: }

9859: /*@C
9860:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

9862:    Collective on Mat

9864:    Input Parameters:
9865: +  mat - the matrix product C
9866: -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()

9868:     Output Parameter:
9869: .   color - the new coloring context

9871:     Level: intermediate

9873: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9874:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9875: @*/
9876: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9877: {
9878:   MatTransposeColoring c;
9879:   MPI_Comm             comm;
9880:   PetscErrorCode       ierr;

9883:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9884:   PetscObjectGetComm((PetscObject)mat,&comm);
9885:   PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);

9887:   c->ctype = iscoloring->ctype;
9888:   if (mat->ops->transposecoloringcreate) {
9889:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9890:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

9892:   *color = c;
9893:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9894:   return(0);
9895: }

9899: /*@
9900:       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
9901:         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
9902:         same, otherwise it will be larger

9904:      Not Collective

9906:   Input Parameter:
9907: .    A  - the matrix

9909:   Output Parameter:
9910: .    state - the current state

9912:   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
9913:          different matrices

9915:   Level: intermediate

9917: @*/
9918: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
9919: {