Actual source code: matrix.c

petsc-master 2016-07-22
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/isimpl.h>
  8: #include <petsc/private/vecimpl.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,MAT_SetRandom;
 38: PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_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:      MatSetRandom(x,rctx);
 61:      PetscRandomDestroy(rctx);
 62: .ve

 64:    Level: intermediate

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

 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(MAT_SetRandom,x,rctx,0,0);
 90:   (*x->ops->setrandom)(x,rctx);
 91:   PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);

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

100: /*@
101:    MatFactorGetError - gets the error code from a factorization

103:    Logically Collective on Mat

105:    Input Parameters:
106: .  mat - the factored matrix

108:    Output Parameter:
109: .  err  - the error code

111:    Level: advanced

113: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic()
114: @*/
115: PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
116: {
119:   *err = mat->errortype;
120:   return(0);
121: }


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

129:   Input Parameter:
130: .    A  - the matrix

132:   Output Parameter:
133: .    keptrows - the rows that are not completely zero

135:   Level: intermediate

137:  @*/
138: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
139: {

144:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
145:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
146:   if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
147:   (*mat->ops->findnonzerorows)(mat,keptrows);
148:   return(0);
149: }

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

156:    Not Collective

158:    Input Parameters:
159: .   A - the matrix

161:    Output Parameters:
162: .   a - the diagonal part (which is a SEQUENTIAL matrix)

164:    Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
165:           Use caution, as the reference count on the returned matrix is not incremented and it is used as
166:           part of the containing MPI Mat's normal operation.

168:    Level: advanced

170: @*/
171: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
172: {
173:   PetscErrorCode ierr,(*f)(Mat,Mat*);
174:   PetscMPIInt    size;

180:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
181:   MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
182:   PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);
183:   if (f) {
184:     (*f)(A,a);
185:     return(0);
186:   } else if (size == 1) {
187:     *a = A;
188:   } else {
189:     MatType mattype;
190:     MatGetType(A,&mattype);
191:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
192:   }
193:   return(0);
194: }

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

201:    Collective on Mat

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

206:    Output Parameter:
207: .   trace - the sum of the diagonal entries

209:    Level: advanced

211: @*/
212: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
213: {
215:   Vec            diag;

218:   MatCreateVecs(mat,&diag,NULL);
219:   MatGetDiagonal(mat,diag);
220:   VecSum(diag,trace);
221:   VecDestroy(&diag);
222:   return(0);
223: }

227: /*@
228:    MatRealPart - Zeros out the imaginary part of the matrix

230:    Logically Collective on Mat

232:    Input Parameters:
233: .  mat - the matrix

235:    Level: advanced


238: .seealso: MatImaginaryPart()
239: @*/
240: PetscErrorCode MatRealPart(Mat mat)
241: {

247:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
248:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
249:   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
250:   MatCheckPreallocated(mat,1);
251:   (*mat->ops->realpart)(mat);
252: #if defined(PETSC_HAVE_CUSP)
253:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
254:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
255:   }
256: #elif defined(PETSC_HAVE_VIENNACL)
257:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
258:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
259:   }
260: #elif defined(PETSC_HAVE_VECCUDA)
261:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
262:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
263:   }
264: #endif
265:   return(0);
266: }

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

273:    Collective on Mat

275:    Input Parameter:
276: .  mat - the matrix

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

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

284:    Level: advanced

286: @*/
287: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
288: {

294:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
295:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
296:   if (!mat->ops->getghosts) {
297:     if (nghosts) *nghosts = 0;
298:     if (ghosts) *ghosts = 0;
299:   } else {
300:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
301:   }
302:   return(0);
303: }


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

311:    Logically Collective on Mat

313:    Input Parameters:
314: .  mat - the matrix

316:    Level: advanced


319: .seealso: MatRealPart()
320: @*/
321: PetscErrorCode MatImaginaryPart(Mat mat)
322: {

328:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
329:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
330:   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
331:   MatCheckPreallocated(mat,1);
332:   (*mat->ops->imaginarypart)(mat);
333: #if defined(PETSC_HAVE_CUSP)
334:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
335:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
336:   }
337: #elif defined(PETSC_HAVE_VIENNACL)
338:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
339:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
340:   }
341: #elif defined(PETSC_HAVE_VECCUDA)
342:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
343:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
344:   }
345: #endif
346:   return(0);
347: }

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

354:    Collective on Mat

356:    Input Parameter:
357: .  mat - the matrix

359:    Output Parameters:
360: +  missing - is any diagonal missing
361: -  dd - first diagonal entry that is missing (optional)

363:    Level: advanced


366: .seealso: MatRealPart()
367: @*/
368: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
369: {

375:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
376:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
377:   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
378:   (*mat->ops->missingdiagonal)(mat,missing,dd);
379:   return(0);
380: }

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

389:    Not Collective

391:    Input Parameters:
392: +  mat - the matrix
393: -  row - the row to get

395:    Output Parameters:
396: +  ncols -  if not NULL, the number of nonzeros in the row
397: .  cols - if not NULL, the column numbers
398: -  vals - if not NULL, the values

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

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

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

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

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

422:    Fortran Notes:
423:    The calling sequence from Fortran is
424: .vb
425:    MatGetRow(matrix,row,ncols,cols,values,ierr)
426:          Mat     matrix (input)
427:          integer row    (input)
428:          integer ncols  (output)
429:          integer cols(maxcols) (output)
430:          double precision (or double complex) values(maxcols) output
431: .ve
432:    where maxcols >= maximum nonzeros in any row of the matrix.


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

439:    Level: advanced

441:    Concepts: matrices^row access

443: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
444: @*/
445: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
446: {
448:   PetscInt       incols;

453:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
454:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
455:   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
456:   MatCheckPreallocated(mat,1);
457:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
458:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
459:   if (ncols) *ncols = incols;
460:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
461:   return(0);
462: }

466: /*@
467:    MatConjugate - replaces the matrix values with their complex conjugates

469:    Logically Collective on Mat

471:    Input Parameters:
472: .  mat - the matrix

474:    Level: advanced

476: .seealso:  VecConjugate()
477: @*/
478: PetscErrorCode MatConjugate(Mat mat)
479: {
480: #if defined(PETSC_USE_COMPLEX)

485:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
486:   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");
487:   (*mat->ops->conjugate)(mat);
488: #if defined(PETSC_HAVE_CUSP)
489:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
490:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
491:   }
492: #elif defined(PETSC_HAVE_VIENNACL)
493:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
494:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
495:   }
496: #elif defined(PETSC_HAVE_VECCUDA)
497:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
498:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
499:   }
500: #endif
501:   return(0);
502: #else
503:   return 0;
504: #endif
505: }

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

512:    Not Collective

514:    Input Parameters:
515: +  mat - the matrix
516: .  row - the row to get
517: .  ncols, cols - the number of nonzeros and their columns
518: -  vals - if nonzero the column values

520:    Notes:
521:    This routine should be called after you have finished examining the entries.

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

527:    Fortran Notes:
528:    The calling sequence from Fortran is
529: .vb
530:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
531:       Mat     matrix (input)
532:       integer row    (input)
533:       integer ncols  (output)
534:       integer cols(maxcols) (output)
535:       double precision (or double complex) values(maxcols) output
536: .ve
537:    Where maxcols >= maximum nonzeros in any row of the matrix.

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

542:    Level: advanced

544: .seealso:  MatGetRow()
545: @*/
546: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
547: {

553:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
554:   if (!mat->ops->restorerow) return(0);
555:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
556:   if (ncols) *ncols = 0;
557:   if (cols)  *cols = NULL;
558:   if (vals)  *vals = NULL;
559:   return(0);
560: }

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

568:    Not Collective

570:    Input Parameters:
571: +  mat - the matrix

573:    Notes:
574:    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.

576:    Level: advanced

578:    Concepts: matrices^row access

580: .seealso: MatRestoreRowRowUpperTriangular()
581: @*/
582: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
583: {

589:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
590:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
591:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
592:   MatCheckPreallocated(mat,1);
593:   (*mat->ops->getrowuppertriangular)(mat);
594:   return(0);
595: }

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

602:    Not Collective

604:    Input Parameters:
605: +  mat - the matrix

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


611:    Level: advanced

613: .seealso:  MatGetRowUpperTriangular()
614: @*/
615: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
616: {

621:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
622:   if (!mat->ops->restorerowuppertriangular) return(0);
623:   (*mat->ops->restorerowuppertriangular)(mat);
624:   return(0);
625: }

629: /*@C
630:    MatSetOptionsPrefix - Sets the prefix used for searching for all
631:    Mat options in the database.

633:    Logically Collective on Mat

635:    Input Parameter:
636: +  A - the Mat context
637: -  prefix - the prefix to prepend to all option names

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

643:    Level: advanced

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

647: .seealso: MatSetFromOptions()
648: @*/
649: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
650: {

655:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
656:   return(0);
657: }

661: /*@C
662:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
663:    Mat options in the database.

665:    Logically Collective on Mat

667:    Input Parameters:
668: +  A - the Mat context
669: -  prefix - the prefix to prepend to all option names

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

675:    Level: advanced

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

679: .seealso: MatGetOptionsPrefix()
680: @*/
681: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
682: {

687:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
688:   return(0);
689: }

693: /*@C
694:    MatGetOptionsPrefix - Sets the prefix used for searching for all
695:    Mat options in the database.

697:    Not Collective

699:    Input Parameter:
700: .  A - the Mat context

702:    Output Parameter:
703: .  prefix - pointer to the prefix string used

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

708:    Level: advanced

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

712: .seealso: MatAppendOptionsPrefix()
713: @*/
714: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
715: {

720:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
721:   return(0);
722: }

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

729:    Collective on Mat

731:    Input Parameters:
732: .  A - the Mat context

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

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

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

741:    Level: beginner

743: .keywords: Mat, setup

745: .seealso: MatCreate(), MatDestroy()
746: @*/
747: PetscErrorCode MatSetUp(Mat A)
748: {
749:   PetscMPIInt    size;

754:   if (!((PetscObject)A)->type_name) {
755:     MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
756:     if (size == 1) {
757:       MatSetType(A, MATSEQAIJ);
758:     } else {
759:       MatSetType(A, MATMPIAIJ);
760:     }
761:   }
762:   if (!A->preallocated && A->ops->setup) {
763:     PetscInfo(A,"Warning not preallocating matrix storage\n");
764:     (*A->ops->setup)(A);
765:   }
766:   if (A->rmap->n < 0 || A->rmap->N < 0) {
767:     PetscLayoutSetUp(A->rmap);
768:   }
769:   if (A->cmap->n < 0 || A->cmap->N < 0) {
770:     PetscLayoutSetUp(A->cmap);
771:   }
772:   A->preallocated = PETSC_TRUE;
773:   return(0);
774: }

776: #if defined(PETSC_HAVE_SAWS)
777: #include <petscviewersaws.h>
778: #endif
781: /*@C
782:    MatView - Visualizes a matrix object.

784:    Collective on Mat

786:    Input Parameters:
787: +  mat - the matrix
788: -  viewer - visualization context

790:   Notes:
791:   The available visualization contexts include
792: +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
793: .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
794: .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
795: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

797:    The user can open alternative visualization contexts with
798: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
799: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
800:          specified file; corresponding input uses MatLoad()
801: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
802:          an X window display
803: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
804:          Currently only the sequential dense and AIJ
805:          matrix types support the Socket viewer.

807:    The user can call PetscViewerPushFormat() to specify the output
808:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
809:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
810: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
811: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
812: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
813: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
814:          format common among all matrix types
815: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
816:          format (which is in many cases the same as the default)
817: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
818:          size and structure (not the matrix entries)
819: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
820:          the matrix structure

822:    Options Database Keys:
823: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
824: .  -mat_view ::ascii_info_detail - Prints more detailed info
825: .  -mat_view - Prints matrix in ASCII format
826: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
827: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
828: .  -display <name> - Sets display name (default is host)
829: .  -draw_pause <sec> - Sets number of seconds to pause after display
830: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 11 Using MATLAB with PETSc for details)
831: .  -viewer_socket_machine <machine> -
832: .  -viewer_socket_port <port> -
833: .  -mat_view binary - save matrix to file in binary format
834: -  -viewer_binary_filename <name> -
835:    Level: beginner

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

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

843:       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
844:       And then use the following mouse functions:
845:           left mouse: zoom in
846:           middle mouse: zoom out
847:           right mouse: continue with the simulation

849:    Concepts: matrices^viewing
850:    Concepts: matrices^plotting
851:    Concepts: matrices^printing

853: .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
854:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
855: @*/
856: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
857: {
858:   PetscErrorCode    ierr;
859:   PetscInt          rows,cols,rbs,cbs;
860:   PetscBool         iascii,ibinary;
861:   PetscViewerFormat format;
862: #if defined(PETSC_HAVE_SAWS)
863:   PetscBool         issaws;
864: #endif

869:   if (!viewer) {
870:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
871:   }
874:   MatCheckPreallocated(mat,1);
875:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
876:   if (ibinary) {
877:     PetscBool mpiio;
878:     PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
879:     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
880:   }

882:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
883:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
884:   PetscViewerGetFormat(viewer,&format);
885:   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
886:     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
887:   }

889: #if defined(PETSC_HAVE_SAWS)
890:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
891: #endif
892:   if (iascii) {
893:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
894:     PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
895:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
896:       PetscViewerASCIIPushTab(viewer);
897:       MatGetSize(mat,&rows,&cols);
898:       MatGetBlockSizes(mat,&rbs,&cbs);
899:       if (rbs != 1 || cbs != 1) {
900:         if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
901:         else            {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
902:       } else {
903:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
904:       }
905:       if (mat->factortype) {
906:         const MatSolverPackage solver;
907:         MatFactorGetSolverPackage(mat,&solver);
908:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
909:       }
910:       if (mat->ops->getinfo) {
911:         MatInfo info;
912:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
913:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
914:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
915:       }
916:       if (mat->nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached null space\n");}
917:       if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");}
918:     }
919: #if defined(PETSC_HAVE_SAWS)
920:   } else if (issaws) {
921:     PetscMPIInt rank;

923:     PetscObjectName((PetscObject)mat);
924:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
925:     if (!((PetscObject)mat)->amsmem && !rank) {
926:       PetscObjectViewSAWs((PetscObject)mat,viewer);
927:     }
928: #endif
929:   }
930:   if (mat->ops->view) {
931:     PetscViewerASCIIPushTab(viewer);
932:     (*mat->ops->view)(mat,viewer);
933:     PetscViewerASCIIPopTab(viewer);
934:   }
935:   if (iascii) {
936:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
937:     PetscViewerGetFormat(viewer,&format);
938:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
939:       PetscViewerASCIIPopTab(viewer);
940:     }
941:   }
942:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
943:   return(0);
944: }

946: #if defined(PETSC_USE_DEBUG)
947: #include <../src/sys/totalview/tv_data_display.h>
948: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
949: {
950:   TV_add_row("Local rows", "int", &mat->rmap->n);
951:   TV_add_row("Local columns", "int", &mat->cmap->n);
952:   TV_add_row("Global rows", "int", &mat->rmap->N);
953:   TV_add_row("Global columns", "int", &mat->cmap->N);
954:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
955:   return TV_format_OK;
956: }
957: #endif

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

967:    Collective on PetscViewer

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

974:    Options Database Keys:
975:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
976:    block size
977: .    -matload_block_size <bs>

979:    Level: beginner

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

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

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

994:    In parallel, each processor can load a subset of rows (or the
995:    entire matrix).  This routine is especially useful when a large
996:    matrix is stored on disk and only part of it is desired on each
997:    processor.  For example, a parallel solver may access only some of
998:    the rows from each processor.  The algorithm used here reads
999:    relatively small blocks of data rather than reading the entire
1000:    matrix and then subsetting it.

1002:    Notes for advanced users:
1003:    Most users should not need to know the details of the binary storage
1004:    format, since MatLoad() and MatView() completely hide these details.
1005:    But for anyone who's interested, the standard binary matrix storage
1006:    format is

1008: $    int    MAT_FILE_CLASSID
1009: $    int    number of rows
1010: $    int    number of columns
1011: $    int    total number of nonzeros
1012: $    int    *number nonzeros in each row
1013: $    int    *column indices of all nonzeros (starting index is zero)
1014: $    PetscScalar *values of all nonzeros

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

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

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

1026:  @*/
1027: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1028: {
1030:   PetscBool      isbinary,flg;

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

1038:   if (!((PetscObject)newmat)->type_name) {
1039:     MatSetType(newmat,MATAIJ);
1040:   }

1042:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1043:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1044:   (*newmat->ops->load)(newmat,viewer);
1045:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

1047:   flg  = PETSC_FALSE;
1048:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1049:   if (flg) {
1050:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1051:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1052:   }
1053:   flg  = PETSC_FALSE;
1054:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1055:   if (flg) {
1056:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1057:   }
1058:   return(0);
1059: }

1063: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1064: {
1066:   Mat_Redundant  *redund = *redundant;
1067:   PetscInt       i;

1070:   if (redund){
1071:     if (redund->matseq) { /* via MatGetSubMatrices()  */
1072:       ISDestroy(&redund->isrow);
1073:       ISDestroy(&redund->iscol);
1074:       MatDestroy(&redund->matseq[0]);
1075:       PetscFree(redund->matseq);
1076:     } else {
1077:       PetscFree2(redund->send_rank,redund->recv_rank);
1078:       PetscFree(redund->sbuf_j);
1079:       PetscFree(redund->sbuf_a);
1080:       for (i=0; i<redund->nrecvs; i++) {
1081:         PetscFree(redund->rbuf_j[i]);
1082:         PetscFree(redund->rbuf_a[i]);
1083:       }
1084:       PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1085:     }

1087:     if (redund->subcomm) {
1088:       PetscCommDestroy(&redund->subcomm);
1089:     }
1090:     PetscFree(redund);
1091:   }
1092:   return(0);
1093: }

1097: /*@
1098:    MatDestroy - Frees space taken by a matrix.

1100:    Collective on Mat

1102:    Input Parameter:
1103: .  A - the matrix

1105:    Level: beginner

1107: @*/
1108: PetscErrorCode MatDestroy(Mat *A)
1109: {

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

1117:   /* if memory was published with SAWs then destroy it */
1118:   PetscObjectSAWsViewOff((PetscObject)*A);
1119:   if ((*A)->ops->destroy) {
1120:     (*(*A)->ops->destroy)(*A);
1121:   }

1123:   PetscFree((*A)->solvertype);
1124:   MatDestroy_Redundant(&(*A)->redundant);
1125:   MatNullSpaceDestroy(&(*A)->nullsp);
1126:   MatNullSpaceDestroy(&(*A)->transnullsp);
1127:   MatNullSpaceDestroy(&(*A)->nearnullsp);
1128:   PetscLayoutDestroy(&(*A)->rmap);
1129:   PetscLayoutDestroy(&(*A)->cmap);
1130:   PetscHeaderDestroy(A);
1131:   return(0);
1132: }

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

1141:    Not Collective

1143:    Input Parameters:
1144: +  mat - the matrix
1145: .  v - a logically two-dimensional array of values
1146: .  m, idxm - the number of rows and their global indices
1147: .  n, idxn - the number of columns and their global indices
1148: -  addv - either ADD_VALUES or INSERT_VALUES, where
1149:    ADD_VALUES adds values to any existing entries, and
1150:    INSERT_VALUES replaces existing entries with new values

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

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

1158:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1159:    options cannot be mixed without intervening calls to the assembly
1160:    routines.

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

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

1170:    Efficiency Alert:
1171:    The routine MatSetValuesBlocked() may offer much better efficiency
1172:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1174:    Level: beginner

1176:    Concepts: matrices^putting entries in

1178: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1179:           InsertMode, INSERT_VALUES, ADD_VALUES
1180: @*/
1181: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1182: {
1184: #if defined(PETSC_USE_DEBUG)
1185:   PetscInt       i,j;
1186: #endif

1191:   if (!m || !n) return(0); /* no values to insert */
1195:   MatCheckPreallocated(mat,1);
1196:   if (mat->insertmode == NOT_SET_VALUES) {
1197:     mat->insertmode = addv;
1198:   }
1199: #if defined(PETSC_USE_DEBUG)
1200:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1201:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1202:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);

1204:   for (i=0; i<m; i++) {
1205:     for (j=0; j<n; j++) {
1206:       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1207: #if defined(PETSC_USE_COMPLEX)
1208:         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]);
1209: #else
1210:         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1211: #endif
1212:     }
1213:   }
1214: #endif

1216:   if (mat->assembled) {
1217:     mat->was_assembled = PETSC_TRUE;
1218:     mat->assembled     = PETSC_FALSE;
1219:   }
1220:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1221:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1222:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1223: #if defined(PETSC_HAVE_CUSP)
1224:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1225:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1226:   }
1227: #elif defined(PETSC_HAVE_VIENNACL)
1228:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1229:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1230:   }
1231: #elif defined(PETSC_HAVE_VECCUDA)
1232:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1233:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1234:   }
1235: #endif
1236:   return(0);
1237: }


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

1246:    Not Collective

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

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

1256:    All the nonzeros in the row must be provided

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

1260:    The row must belong to this process

1262:    Level: intermediate

1264:    Concepts: matrices^putting entries in

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

1278:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1279:   MatSetValuesRow(mat,globalrow,v);
1280: #if defined(PETSC_HAVE_CUSP)
1281:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1282:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1283:   }
1284: #elif defined(PETSC_HAVE_VIENNACL)
1285:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1286:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1287:   }
1288: #elif defined(PETSC_HAVE_VECCUDA)
1289:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1290:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1291:   }
1292: #endif
1293:   return(0);
1294: }

1298: /*@
1299:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1300:         values into a matrix

1302:    Not Collective

1304:    Input Parameters:
1305: +  mat - the matrix
1306: .  row - the (block) row to set
1307: -  v - a logically two-dimensional array of values

1309:    Notes:
1310:    The values, v, are column-oriented for the block version.

1312:    All the nonzeros in the row must be provided

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

1316:    The row must belong to this process

1318:    Level: advanced

1320:    Concepts: matrices^putting entries in

1322: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1323:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1324: @*/
1325: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1326: {

1332:   MatCheckPreallocated(mat,1);
1334: #if defined(PETSC_USE_DEBUG)
1335:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1336:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1337: #endif
1338:   mat->insertmode = INSERT_VALUES;

1340:   if (mat->assembled) {
1341:     mat->was_assembled = PETSC_TRUE;
1342:     mat->assembled     = PETSC_FALSE;
1343:   }
1344:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1345:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1346:   (*mat->ops->setvaluesrow)(mat,row,v);
1347:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1348: #if defined(PETSC_HAVE_CUSP)
1349:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1350:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1351:   }
1352: #elif defined(PETSC_HAVE_VIENNACL)
1353:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1354:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1355:   }
1356: #elif defined(PETSC_HAVE_VECCUDA)
1357:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1358:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1359:   }
1360: #endif
1361:   return(0);
1362: }

1366: /*@
1367:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1368:      Using structured grid indexing

1370:    Not Collective

1372:    Input Parameters:
1373: +  mat - the matrix
1374: .  m - number of rows being entered
1375: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1376: .  n - number of columns being entered
1377: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1378: .  v - a logically two-dimensional array of values
1379: -  addv - either ADD_VALUES or INSERT_VALUES, where
1380:    ADD_VALUES adds values to any existing entries, and
1381:    INSERT_VALUES replaces existing entries with new values

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

1386:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1387:    options cannot be mixed without intervening calls to the assembly
1388:    routines.

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

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

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

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

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

1406:    In Fortran idxm and idxn should be declared as
1407: $     MatStencil idxm(4,m),idxn(4,n)
1408:    and the values inserted using
1409: $    idxm(MatStencil_i,1) = i
1410: $    idxm(MatStencil_j,1) = j
1411: $    idxm(MatStencil_k,1) = k
1412: $    idxm(MatStencil_c,1) = c
1413:    etc

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

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

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

1426:    Efficiency Alert:
1427:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1428:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1430:    Level: beginner

1432:    Concepts: matrices^putting entries in

1434: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1435:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1436: @*/
1437: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1438: {
1440:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1441:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1442:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1452:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1453:     jdxm = buf; jdxn = buf+m;
1454:   } else {
1455:     PetscMalloc2(m,&bufm,n,&bufn);
1456:     jdxm = bufm; jdxn = bufn;
1457:   }
1458:   for (i=0; i<m; i++) {
1459:     for (j=0; j<3-sdim; j++) dxm++;
1460:     tmp = *dxm++ - starts[0];
1461:     for (j=0; j<dim-1; j++) {
1462:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1463:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1464:     }
1465:     if (mat->stencil.noc) dxm++;
1466:     jdxm[i] = tmp;
1467:   }
1468:   for (i=0; i<n; i++) {
1469:     for (j=0; j<3-sdim; j++) dxn++;
1470:     tmp = *dxn++ - starts[0];
1471:     for (j=0; j<dim-1; j++) {
1472:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1473:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1474:     }
1475:     if (mat->stencil.noc) dxn++;
1476:     jdxn[i] = tmp;
1477:   }
1478:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1479:   PetscFree2(bufm,bufn);
1480:   return(0);
1481: }

1485: /*@
1486:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1487:      Using structured grid indexing

1489:    Not Collective

1491:    Input Parameters:
1492: +  mat - the matrix
1493: .  m - number of rows being entered
1494: .  idxm - grid coordinates for matrix rows being entered
1495: .  n - number of columns being entered
1496: .  idxn - grid coordinates for matrix columns being entered
1497: .  v - a logically two-dimensional array of values
1498: -  addv - either ADD_VALUES or INSERT_VALUES, where
1499:    ADD_VALUES adds values to any existing entries, and
1500:    INSERT_VALUES replaces existing entries with new values

1502:    Notes:
1503:    By default the values, v, are row-oriented and unsorted.
1504:    See MatSetOption() for other options.

1506:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1507:    options cannot be mixed without intervening calls to the assembly
1508:    routines.

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

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

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

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

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

1526:    In Fortran idxm and idxn should be declared as
1527: $     MatStencil idxm(4,m),idxn(4,n)
1528:    and the values inserted using
1529: $    idxm(MatStencil_i,1) = i
1530: $    idxm(MatStencil_j,1) = j
1531: $    idxm(MatStencil_k,1) = k
1532:    etc

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

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

1542:    Level: beginner

1544:    Concepts: matrices^putting entries in

1546: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1547:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1548:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1549: @*/
1550: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1551: {
1553:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1554:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1555:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1565:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1566:     jdxm = buf; jdxn = buf+m;
1567:   } else {
1568:     PetscMalloc2(m,&bufm,n,&bufn);
1569:     jdxm = bufm; jdxn = bufn;
1570:   }
1571:   for (i=0; i<m; i++) {
1572:     for (j=0; j<3-sdim; j++) dxm++;
1573:     tmp = *dxm++ - starts[0];
1574:     for (j=0; j<sdim-1; j++) {
1575:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1576:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1577:     }
1578:     dxm++;
1579:     jdxm[i] = tmp;
1580:   }
1581:   for (i=0; i<n; i++) {
1582:     for (j=0; j<3-sdim; j++) dxn++;
1583:     tmp = *dxn++ - starts[0];
1584:     for (j=0; j<sdim-1; j++) {
1585:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1586:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1587:     }
1588:     dxn++;
1589:     jdxn[i] = tmp;
1590:   }
1591:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1592:   PetscFree2(bufm,bufn);
1593: #if defined(PETSC_HAVE_CUSP)
1594:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1595:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1596:   }
1597: #elif defined(PETSC_HAVE_VIENNACL)
1598:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1599:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1600:   }
1601: #elif defined(PETSC_HAVE_VECCUDA)
1602:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1603:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1604:   }
1605: #endif
1606:   return(0);
1607: }

1611: /*@
1612:    MatSetStencil - Sets the grid information for setting values into a matrix via
1613:         MatSetValuesStencil()

1615:    Not Collective

1617:    Input Parameters:
1618: +  mat - the matrix
1619: .  dim - dimension of the grid 1, 2, or 3
1620: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1621: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1622: -  dof - number of degrees of freedom per node


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

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

1631:    Level: beginner

1633:    Concepts: matrices^putting entries in

1635: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1636:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1637: @*/
1638: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1639: {
1640:   PetscInt i;


1647:   mat->stencil.dim = dim + (dof > 1);
1648:   for (i=0; i<dim; i++) {
1649:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1650:     mat->stencil.starts[i] = starts[dim-i-1];
1651:   }
1652:   mat->stencil.dims[dim]   = dof;
1653:   mat->stencil.starts[dim] = 0;
1654:   mat->stencil.noc         = (PetscBool)(dof == 1);
1655:   return(0);
1656: }

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

1663:    Not Collective

1665:    Input Parameters:
1666: +  mat - the matrix
1667: .  v - a logically two-dimensional array of values
1668: .  m, idxm - the number of block rows and their global block indices
1669: .  n, idxn - the number of block columns and their global block indices
1670: -  addv - either ADD_VALUES or INSERT_VALUES, where
1671:    ADD_VALUES adds values to any existing entries, and
1672:    INSERT_VALUES replaces existing entries with new values

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

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

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

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

1690:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1691:    options cannot be mixed without intervening calls to the assembly
1692:    routines.

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

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

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

1708:    Example:
1709: $   Suppose m=n=2 and block size(bs) = 2 The array is
1710: $
1711: $   1  2  | 3  4
1712: $   5  6  | 7  8
1713: $   - - - | - - -
1714: $   9  10 | 11 12
1715: $   13 14 | 15 16
1716: $
1717: $   v[] should be passed in like
1718: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1719: $
1720: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1721: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

1723:    Level: intermediate

1725:    Concepts: matrices^putting entries in blocked

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

1736:   if (!m || !n) return(0); /* no values to insert */
1740:   MatCheckPreallocated(mat,1);
1741:   if (mat->insertmode == NOT_SET_VALUES) {
1742:     mat->insertmode = addv;
1743:   }
1744: #if defined(PETSC_USE_DEBUG)
1745:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1746:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1747:   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1748: #endif

1750:   if (mat->assembled) {
1751:     mat->was_assembled = PETSC_TRUE;
1752:     mat->assembled     = PETSC_FALSE;
1753:   }
1754:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1755:   if (mat->ops->setvaluesblocked) {
1756:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1757:   } else {
1758:     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1759:     PetscInt i,j,bs,cbs;
1760:     MatGetBlockSizes(mat,&bs,&cbs);
1761:     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1762:       iidxm = buf; iidxn = buf + m*bs;
1763:     } else {
1764:       PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1765:       iidxm = bufr; iidxn = bufc;
1766:     }
1767:     for (i=0; i<m; i++) {
1768:       for (j=0; j<bs; j++) {
1769:         iidxm[i*bs+j] = bs*idxm[i] + j;
1770:       }
1771:     }
1772:     for (i=0; i<n; i++) {
1773:       for (j=0; j<cbs; j++) {
1774:         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1775:       }
1776:     }
1777:     MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1778:     PetscFree2(bufr,bufc);
1779:   }
1780:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1781: #if defined(PETSC_HAVE_CUSP)
1782:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1783:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1784:   }
1785: #elif defined(PETSC_HAVE_VIENNACL)
1786:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1787:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1788:   }
1789: #elif defined(PETSC_HAVE_VECCUDA)
1790:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1791:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1792:   }
1793: #endif
1794:   return(0);
1795: }

1799: /*@
1800:    MatGetValues - Gets a block of values from a matrix.

1802:    Not Collective; currently only returns a local block

1804:    Input Parameters:
1805: +  mat - the matrix
1806: .  v - a logically two-dimensional array for storing the values
1807: .  m, idxm - the number of rows and their global indices
1808: -  n, idxn - the number of columns and their global indices

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

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

1818:    MatGetValues() requires that the matrix has been assembled
1819:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1820:    MatSetValues() and MatGetValues() CANNOT be made in succession
1821:    without intermediate matrix assembly.

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

1826:    Level: advanced

1828:    Concepts: matrices^accessing values

1830: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1831: @*/
1832: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1833: {

1839:   if (!m || !n) return(0);
1843:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1844:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1845:   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1846:   MatCheckPreallocated(mat,1);

1848:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1849:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1850:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1851:   return(0);
1852: }

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

1860:   Not Collective

1862:   Input Parameters:
1863: + mat - the matrix
1864: . nb - the number of blocks
1865: . bs - the number of rows (and columns) in each block
1866: . rows - a concatenation of the rows for each block
1867: - v - a concatenation of logically two-dimensional arrays of values

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

1872:   Level: advanced

1874:   Concepts: matrices^putting entries in

1876: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1877:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1878: @*/
1879: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1880: {

1888: #if defined(PETSC_USE_DEBUG)
1889:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1890: #endif

1892:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1893:   if (mat->ops->setvaluesbatch) {
1894:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1895:   } else {
1896:     PetscInt b;
1897:     for (b = 0; b < nb; ++b) {
1898:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1899:     }
1900:   }
1901:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1902:   return(0);
1903: }

1907: /*@
1908:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1909:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1910:    using a local (per-processor) numbering.

1912:    Not Collective

1914:    Input Parameters:
1915: +  x - the matrix
1916: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1917: - cmapping - column mapping

1919:    Level: intermediate

1921:    Concepts: matrices^local to global mapping
1922:    Concepts: local to global mapping^for matrices

1924: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1925: @*/
1926: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1927: {


1936:   if (x->ops->setlocaltoglobalmapping) {
1937:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1938:   } else {
1939:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1940:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1941:   }
1942:   return(0);
1943: }


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

1951:    Not Collective

1953:    Input Parameters:
1954: .  A - the matrix

1956:    Output Parameters:
1957: + rmapping - row mapping
1958: - cmapping - column mapping

1960:    Level: advanced

1962:    Concepts: matrices^local to global mapping
1963:    Concepts: local to global mapping^for matrices

1965: .seealso:  MatSetValuesLocal()
1966: @*/
1967: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1968: {
1974:   if (rmapping) *rmapping = A->rmap->mapping;
1975:   if (cmapping) *cmapping = A->cmap->mapping;
1976:   return(0);
1977: }

1981: /*@
1982:    MatGetLayouts - Gets the PetscLayout objects for rows and columns

1984:    Not Collective

1986:    Input Parameters:
1987: .  A - the matrix

1989:    Output Parameters:
1990: + rmap - row layout
1991: - cmap - column layout

1993:    Level: advanced

1995: .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
1996: @*/
1997: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1998: {
2004:   if (rmap) *rmap = A->rmap;
2005:   if (cmap) *cmap = A->cmap;
2006:   return(0);
2007: }

2011: /*@
2012:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2013:    using a local ordering of the nodes.

2015:    Not Collective

2017:    Input Parameters:
2018: +  x - the matrix
2019: .  nrow, irow - number of rows and their local indices
2020: .  ncol, icol - number of columns and their local indices
2021: .  y -  a logically two-dimensional array of values
2022: -  addv - either INSERT_VALUES or ADD_VALUES, where
2023:    ADD_VALUES adds values to any existing entries, and
2024:    INSERT_VALUES replaces existing entries with new values

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

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

2032:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2033:    options cannot be mixed without intervening calls to the assembly
2034:    routines.

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

2039:    Level: intermediate

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

2043: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2044:            MatSetValueLocal()
2045: @*/
2046: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2047: {

2053:   MatCheckPreallocated(mat,1);
2054:   if (!nrow || !ncol) return(0); /* no values to insert */
2058:   if (mat->insertmode == NOT_SET_VALUES) {
2059:     mat->insertmode = addv;
2060:   }
2061: #if defined(PETSC_USE_DEBUG)
2062:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2063:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2064:   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2065: #endif

2067:   if (mat->assembled) {
2068:     mat->was_assembled = PETSC_TRUE;
2069:     mat->assembled     = PETSC_FALSE;
2070:   }
2071:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2072:   if (mat->ops->setvalueslocal) {
2073:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
2074:   } else {
2075:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2076:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2077:       irowm = buf; icolm = buf+nrow;
2078:     } else {
2079:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2080:       irowm = bufr; icolm = bufc;
2081:     }
2082:     ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
2083:     ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
2084:     MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
2085:     PetscFree2(bufr,bufc);
2086:   }
2087:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2088: #if defined(PETSC_HAVE_CUSP)
2089:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2090:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2091:   }
2092: #elif defined(PETSC_HAVE_VIENNACL)
2093:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2094:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2095:   }
2096: #elif defined(PETSC_HAVE_VECCUDA)
2097:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2098:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2099:   }
2100: #endif
2101:   return(0);
2102: }

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

2110:    Not Collective

2112:    Input Parameters:
2113: +  x - the matrix
2114: .  nrow, irow - number of rows and their local indices
2115: .  ncol, icol - number of columns and their local indices
2116: .  y -  a logically two-dimensional array of values
2117: -  addv - either INSERT_VALUES or ADD_VALUES, where
2118:    ADD_VALUES adds values to any existing entries, and
2119:    INSERT_VALUES replaces existing entries with new values

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

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

2128:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2129:    options cannot be mixed without intervening calls to the assembly
2130:    routines.

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

2135:    Level: intermediate

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

2139: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2140:            MatSetValuesLocal(),  MatSetValuesBlocked()
2141: @*/
2142: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2143: {

2149:   MatCheckPreallocated(mat,1);
2150:   if (!nrow || !ncol) return(0); /* no values to insert */
2154:   if (mat->insertmode == NOT_SET_VALUES) {
2155:     mat->insertmode = addv;
2156:   }
2157: #if defined(PETSC_USE_DEBUG)
2158:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2159:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2160:   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);
2161: #endif

2163:   if (mat->assembled) {
2164:     mat->was_assembled = PETSC_TRUE;
2165:     mat->assembled     = PETSC_FALSE;
2166:   }
2167:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2168:   if (mat->ops->setvaluesblockedlocal) {
2169:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2170:   } else {
2171:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2172:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2173:       irowm = buf; icolm = buf + nrow;
2174:     } else {
2175:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2176:       irowm = bufr; icolm = bufc;
2177:     }
2178:     ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2179:     ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2180:     MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2181:     PetscFree2(bufr,bufc);
2182:   }
2183:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2184: #if defined(PETSC_HAVE_CUSP)
2185:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2186:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2187:   }
2188: #elif defined(PETSC_HAVE_VIENNACL)
2189:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2190:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2191:   }
2192: #elif defined(PETSC_HAVE_VECCUDA)
2193:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2194:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2195:   }
2196: #endif
2197:   return(0);
2198: }

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

2205:    Collective on Mat and Vec

2207:    Input Parameters:
2208: +  mat - the matrix
2209: -  x   - the vector to be multiplied

2211:    Output Parameters:
2212: .  y - the result

2214:    Notes:
2215:    The vectors x and y cannot be the same.  I.e., one cannot
2216:    call MatMult(A,y,y).

2218:    Level: developer

2220:    Concepts: matrix-vector product

2222: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2223: @*/
2224: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2225: {


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

2239:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2240:   (*mat->ops->multdiagonalblock)(mat,x,y);
2241:   PetscObjectStateIncrease((PetscObject)y);
2242:   return(0);
2243: }

2245: /* --------------------------------------------------------*/
2248: /*@
2249:    MatMult - Computes the matrix-vector product, y = Ax.

2251:    Neighbor-wise Collective on Mat and Vec

2253:    Input Parameters:
2254: +  mat - the matrix
2255: -  x   - the vector to be multiplied

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

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

2264:    Level: beginner

2266:    Concepts: matrix-vector product

2268: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2269: @*/
2270: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2271: {

2279:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2280:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2281:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2282: #if !defined(PETSC_HAVE_CONSTRAINTS)
2283:   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);
2284:   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);
2285:   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);
2286: #endif
2287:   VecLocked(y,3);
2288:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2289:   MatCheckPreallocated(mat,1);

2291:   VecLockPush(x);
2292:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2293:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2294:   (*mat->ops->mult)(mat,x,y);
2295:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2296:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2297:   VecLockPop(x);
2298:   return(0);
2299: }

2303: /*@
2304:    MatMultTranspose - Computes matrix transpose times a vector.

2306:    Neighbor-wise Collective on Mat and Vec

2308:    Input Parameters:
2309: +  mat - the matrix
2310: -  x   - the vector to be multilplied

2312:    Output Parameters:
2313: .  y - the result

2315:    Notes:
2316:    The vectors x and y cannot be the same.  I.e., one cannot
2317:    call MatMultTranspose(A,y,y).

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

2322:    Level: beginner

2324:    Concepts: matrix vector product^transpose

2326: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2327: @*/
2328: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2329: {


2338:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2339:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2340:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2341: #if !defined(PETSC_HAVE_CONSTRAINTS)
2342:   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);
2343:   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);
2344: #endif
2345:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2346:   MatCheckPreallocated(mat,1);

2348:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2349:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2350:   VecLockPush(x);
2351:   (*mat->ops->multtranspose)(mat,x,y);
2352:   VecLockPop(x);
2353:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2354:   PetscObjectStateIncrease((PetscObject)y);
2355:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2356:   return(0);
2357: }

2361: /*@
2362:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2364:    Neighbor-wise Collective on Mat and Vec

2366:    Input Parameters:
2367: +  mat - the matrix
2368: -  x   - the vector to be multilplied

2370:    Output Parameters:
2371: .  y - the result

2373:    Notes:
2374:    The vectors x and y cannot be the same.  I.e., one cannot
2375:    call MatMultHermitianTranspose(A,y,y).

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

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

2381:    Level: beginner

2383:    Concepts: matrix vector product^transpose

2385: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2386: @*/
2387: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2388: {
2390:   Vec            w;


2398:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2399:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2400:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2401: #if !defined(PETSC_HAVE_CONSTRAINTS)
2402:   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);
2403:   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);
2404: #endif
2405:   MatCheckPreallocated(mat,1);

2407:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2408:   if (mat->ops->multhermitiantranspose) {
2409:     VecLockPush(x);
2410:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2411:     VecLockPop(x);
2412:   } else {
2413:     VecDuplicate(x,&w);
2414:     VecCopy(x,w);
2415:     VecConjugate(w);
2416:     MatMultTranspose(mat,w,y);
2417:     VecDestroy(&w);
2418:     VecConjugate(y);
2419:   }
2420:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2421:   PetscObjectStateIncrease((PetscObject)y);
2422:   return(0);
2423: }

2427: /*@
2428:     MatMultAdd -  Computes v3 = v2 + A * v1.

2430:     Neighbor-wise Collective on Mat and Vec

2432:     Input Parameters:
2433: +   mat - the matrix
2434: -   v1, v2 - the vectors

2436:     Output Parameters:
2437: .   v3 - the result

2439:     Notes:
2440:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2441:     call MatMultAdd(A,v1,v2,v1).

2443:     Level: beginner

2445:     Concepts: matrix vector product^addition

2447: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2448: @*/
2449: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2450: {


2460:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2461:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2462:   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);
2463:   /* 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);
2464:      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); */
2465:   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);
2466:   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);
2467:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2468:   MatCheckPreallocated(mat,1);

2470:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2471:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2472:   VecLockPush(v1);
2473:   (*mat->ops->multadd)(mat,v1,v2,v3);
2474:   VecLockPop(v1);
2475:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2476:   PetscObjectStateIncrease((PetscObject)v3);
2477:   return(0);
2478: }

2482: /*@
2483:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2485:    Neighbor-wise Collective on Mat and Vec

2487:    Input Parameters:
2488: +  mat - the matrix
2489: -  v1, v2 - the vectors

2491:    Output Parameters:
2492: .  v3 - the result

2494:    Notes:
2495:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2496:    call MatMultTransposeAdd(A,v1,v2,v1).

2498:    Level: beginner

2500:    Concepts: matrix vector product^transpose and addition

2502: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2503: @*/
2504: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2505: {


2515:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2516:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2517:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2518:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2519:   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);
2520:   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);
2521:   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);
2522:   MatCheckPreallocated(mat,1);

2524:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2525:   VecLockPush(v1);
2526:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2527:   VecLockPop(v1);
2528:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2529:   PetscObjectStateIncrease((PetscObject)v3);
2530:   return(0);
2531: }

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

2538:    Neighbor-wise Collective on Mat and Vec

2540:    Input Parameters:
2541: +  mat - the matrix
2542: -  v1, v2 - the vectors

2544:    Output Parameters:
2545: .  v3 - the result

2547:    Notes:
2548:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2549:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2551:    Level: beginner

2553:    Concepts: matrix vector product^transpose and addition

2555: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2556: @*/
2557: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2558: {


2568:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2569:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2570:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2571:   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);
2572:   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);
2573:   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);
2574:   MatCheckPreallocated(mat,1);

2576:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2577:   VecLockPush(v1);
2578:   if (mat->ops->multhermitiantransposeadd) {
2579:     (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2580:    } else {
2581:     Vec w,z;
2582:     VecDuplicate(v1,&w);
2583:     VecCopy(v1,w);
2584:     VecConjugate(w);
2585:     VecDuplicate(v3,&z);
2586:     MatMultTranspose(mat,w,z);
2587:     VecDestroy(&w);
2588:     VecConjugate(z);
2589:     VecWAXPY(v3,1.0,v2,z);
2590:     VecDestroy(&z);
2591:   }
2592:   VecLockPop(v1);
2593:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2594:   PetscObjectStateIncrease((PetscObject)v3);
2595:   return(0);
2596: }

2600: /*@
2601:    MatMultConstrained - The inner multiplication routine for a
2602:    constrained matrix P^T A P.

2604:    Neighbor-wise Collective on Mat and Vec

2606:    Input Parameters:
2607: +  mat - the matrix
2608: -  x   - the vector to be multilplied

2610:    Output Parameters:
2611: .  y - the result

2613:    Notes:
2614:    The vectors x and y cannot be the same.  I.e., one cannot
2615:    call MatMult(A,y,y).

2617:    Level: beginner

2619: .keywords: matrix, multiply, matrix-vector product, constraint
2620: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2621: @*/
2622: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2623: {

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

2637:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2638:   VecLockPush(x);
2639:   (*mat->ops->multconstrained)(mat,x,y);
2640:   VecLockPop(x);
2641:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2642:   PetscObjectStateIncrease((PetscObject)y);
2643:   return(0);
2644: }

2648: /*@
2649:    MatMultTransposeConstrained - The inner multiplication routine for a
2650:    constrained matrix P^T A^T P.

2652:    Neighbor-wise Collective on Mat and Vec

2654:    Input Parameters:
2655: +  mat - the matrix
2656: -  x   - the vector to be multilplied

2658:    Output Parameters:
2659: .  y - the result

2661:    Notes:
2662:    The vectors x and y cannot be the same.  I.e., one cannot
2663:    call MatMult(A,y,y).

2665:    Level: beginner

2667: .keywords: matrix, multiply, matrix-vector product, constraint
2668: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2669: @*/
2670: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2671: {

2678:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2679:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2680:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2681:   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);
2682:   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);

2684:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2685:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2686:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2687:   PetscObjectStateIncrease((PetscObject)y);
2688:   return(0);
2689: }

2693: /*@C
2694:    MatGetFactorType - gets the type of factorization it is

2696:    Note Collective
2697:    as the flag

2699:    Input Parameters:
2700: .  mat - the matrix

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

2705:     Level: intermediate

2707: .seealso:    MatFactorType, MatGetFactor()
2708: @*/
2709: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2710: {
2714:   *t = mat->factortype;
2715:   return(0);
2716: }

2718: /* ------------------------------------------------------------*/
2721: /*@C
2722:    MatGetInfo - Returns information about matrix storage (number of
2723:    nonzeros, memory, etc.).

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

2727:    Input Parameters:
2728: .  mat - the matrix

2730:    Output Parameters:
2731: +  flag - flag indicating the type of parameters to be returned
2732:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2733:    MAT_GLOBAL_SUM - sum over all processors)
2734: -  info - matrix information context

2736:    Notes:
2737:    The MatInfo context contains a variety of matrix data, including
2738:    number of nonzeros allocated and used, number of mallocs during
2739:    matrix assembly, etc.  Additional information for factored matrices
2740:    is provided (such as the fill ratio, number of mallocs during
2741:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2742:    when using the runtime options
2743: $       -info -mat_view ::ascii_info

2745:    Example for C/C++ Users:
2746:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2747:    data within the MatInfo context.  For example,
2748: .vb
2749:       MatInfo info;
2750:       Mat     A;
2751:       double  mal, nz_a, nz_u;

2753:       MatGetInfo(A,MAT_LOCAL,&info);
2754:       mal  = info.mallocs;
2755:       nz_a = info.nz_allocated;
2756: .ve

2758:    Example for Fortran Users:
2759:    Fortran users should declare info as a double precision
2760:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2761:    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2762:    a complete list of parameter names.
2763: .vb
2764:       double  precision info(MAT_INFO_SIZE)
2765:       double  precision mal, nz_a
2766:       Mat     A
2767:       integer ierr

2769:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2770:       mal = info(MAT_INFO_MALLOCS)
2771:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2772: .ve

2774:     Level: intermediate

2776:     Concepts: matrices^getting information on

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

2781: .seealso: MatStashGetInfo()

2783: @*/
2784: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2785: {

2792:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2793:   MatCheckPreallocated(mat,1);
2794:   (*mat->ops->getinfo)(mat,flag,info);
2795:   return(0);
2796: }

2800: /*
2801:    This is used by external packages where it is not easy to get the info from the actual 
2802:    matrix factorization.
2803: */
2804: PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2805: {

2809:   PetscMemzero(info,sizeof(MatInfo));
2810:   return(0);
2811: }

2813: /* ----------------------------------------------------------*/

2817: /*@C
2818:    MatLUFactor - Performs in-place LU factorization of matrix.

2820:    Collective on Mat

2822:    Input Parameters:
2823: +  mat - the matrix
2824: .  row - row permutation
2825: .  col - column permutation
2826: -  info - options for factorization, includes
2827: $          fill - expected fill as ratio of original fill.
2828: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2829: $                   Run with the option -info to determine an optimal value to use

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

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

2839:    Level: developer

2841:    Concepts: matrices^LU factorization

2843: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2844:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2849: @*/
2850: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2851: {
2853:   MatFactorInfo  tinfo;

2861:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2862:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2863:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2864:   MatCheckPreallocated(mat,1);
2865:   if (!info) {
2866:     MatFactorInfoInitialize(&tinfo);
2867:     info = &tinfo;
2868:   }

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

2879: /*@C
2880:    MatILUFactor - Performs in-place ILU factorization of matrix.

2882:    Collective on Mat

2884:    Input Parameters:
2885: +  mat - the matrix
2886: .  row - row permutation
2887: .  col - column permutation
2888: -  info - structure containing
2889: $      levels - number of levels of fill.
2890: $      expected fill - as ratio of original fill.
2891: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2892:                 missing diagonal entries)

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

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

2902:    Level: developer

2904:    Concepts: matrices^ILU factorization

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

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

2911: @*/
2912: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2913: {

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

2928:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2929:   (*mat->ops->ilufactor)(mat,row,col,info);
2930:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2931:   PetscObjectStateIncrease((PetscObject)mat);
2932:   return(0);
2933: }

2937: /*@C
2938:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2939:    Call this routine before calling MatLUFactorNumeric().

2941:    Collective on Mat

2943:    Input Parameters:
2944: +  fact - the factor matrix obtained with MatGetFactor()
2945: .  mat - the matrix
2946: .  row, col - row and column permutations
2947: -  info - options for factorization, includes
2948: $          fill - expected fill as ratio of original fill.
2949: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2950: $                   Run with the option -info to determine an optimal value to use


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

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

2959:    Level: developer

2961:    Concepts: matrices^LU symbolic factorization

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

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

2968: @*/
2969: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2970: {

2980:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2981:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2982:   if (!(fact)->ops->lufactorsymbolic) {
2983:     const MatSolverPackage spackage;
2984:     MatFactorGetSolverPackage(fact,&spackage);
2985:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2986:   }
2987:   MatCheckPreallocated(mat,2);

2989:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2990:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2991:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2992:   PetscObjectStateIncrease((PetscObject)fact);
2993:   return(0);
2994: }

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

3002:    Collective on Mat

3004:    Input Parameters:
3005: +  fact - the factor matrix obtained with MatGetFactor()
3006: .  mat - the matrix
3007: -  info - options for factorization

3009:    Notes:
3010:    See MatLUFactor() for in-place factorization.  See
3011:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

3017:    Level: developer

3019:    Concepts: matrices^LU numeric factorization

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

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

3026: @*/
3027: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3028: {

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

3039:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3040:   MatCheckPreallocated(mat,2);
3041:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
3042:   (fact->ops->lufactornumeric)(fact,mat,info);
3043:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
3044:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3045:   PetscObjectStateIncrease((PetscObject)fact);
3046:   return(0);
3047: }

3051: /*@C
3052:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3053:    symmetric matrix.

3055:    Collective on Mat

3057:    Input Parameters:
3058: +  mat - the matrix
3059: .  perm - row and column permutations
3060: -  f - expected fill as ratio of original fill

3062:    Notes:
3063:    See MatLUFactor() for the nonsymmetric case.  See also
3064:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

3070:    Level: developer

3072:    Concepts: matrices^Cholesky factorization

3074: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3075:           MatGetOrdering()

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

3080: @*/
3081: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3082: {

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

3096:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3097:   (*mat->ops->choleskyfactor)(mat,perm,info);
3098:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3099:   PetscObjectStateIncrease((PetscObject)mat);
3100:   return(0);
3101: }

3105: /*@C
3106:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3107:    of a symmetric matrix.

3109:    Collective on Mat

3111:    Input Parameters:
3112: +  fact - the factor matrix obtained with MatGetFactor()
3113: .  mat - the matrix
3114: .  perm - row and column permutations
3115: -  info - options for factorization, includes
3116: $          fill - expected fill as ratio of original fill.
3117: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3118: $                   Run with the option -info to determine an optimal value to use

3120:    Notes:
3121:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3122:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

3128:    Level: developer

3130:    Concepts: matrices^Cholesky symbolic factorization

3132: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3133:           MatGetOrdering()

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

3138: @*/
3139: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3140: {

3149:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3150:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3151:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3152:   if (!(fact)->ops->choleskyfactorsymbolic) {
3153:     const MatSolverPackage spackage;
3154:     MatFactorGetSolverPackage(fact,&spackage);
3155:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3156:   }
3157:   MatCheckPreallocated(mat,2);

3159:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3160:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3161:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3162:   PetscObjectStateIncrease((PetscObject)fact);
3163:   return(0);
3164: }

3168: /*@C
3169:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3170:    of a symmetric matrix. Call this routine after first calling
3171:    MatCholeskyFactorSymbolic().

3173:    Collective on Mat

3175:    Input Parameters:
3176: +  fact - the factor matrix obtained with MatGetFactor()
3177: .  mat - the initial matrix
3178: .  info - options for factorization
3179: -  fact - the symbolic factor of mat


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

3187:    Level: developer

3189:    Concepts: matrices^Cholesky numeric factorization

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

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

3196: @*/
3197: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3198: {

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

3211:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3212:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3213:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3214:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3215:   PetscObjectStateIncrease((PetscObject)fact);
3216:   return(0);
3217: }

3219: /* ----------------------------------------------------------------*/
3222: /*@
3223:    MatSolve - Solves A x = b, given a factored matrix.

3225:    Neighbor-wise Collective on Mat and Vec

3227:    Input Parameters:
3228: +  mat - the factored matrix
3229: -  b - the right-hand-side vector

3231:    Output Parameter:
3232: .  x - the result vector

3234:    Notes:
3235:    The vectors b and x cannot be the same.  I.e., one cannot
3236:    call MatSolve(A,x,x).

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

3243:    Level: developer

3245:    Concepts: matrices^triangular solves

3247: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3248: @*/
3249: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3250: {

3260:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3261:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3262:   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);
3263:   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);
3264:   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);
3265:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3266:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3267:   MatCheckPreallocated(mat,1);

3269:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3270:   if (mat->errortype) {
3271:     PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3272:     VecSetInf(x);
3273:   } else {
3274:     (*mat->ops->solve)(mat,b,x);
3275:   }
3276:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3277:   PetscObjectStateIncrease((PetscObject)x);
3278:   return(0);
3279: }

3283: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3284: {
3286:   Vec            b,x;
3287:   PetscInt       m,N,i;
3288:   PetscScalar    *bb,*xx;
3289:   PetscBool      flg;

3292:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3293:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3294:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3295:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3297:   MatDenseGetArray(B,&bb);
3298:   MatDenseGetArray(X,&xx);
3299:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3300:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3301:   MatCreateVecs(A,&x,&b);
3302:   for (i=0; i<N; i++) {
3303:     VecPlaceArray(b,bb + i*m);
3304:     VecPlaceArray(x,xx + i*m);
3305:     MatSolve(A,b,x);
3306:     VecResetArray(x);
3307:     VecResetArray(b);
3308:   }
3309:   VecDestroy(&b);
3310:   VecDestroy(&x);
3311:   MatDenseRestoreArray(B,&bb);
3312:   MatDenseRestoreArray(X,&xx);
3313:   return(0);
3314: }

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

3321:    Neighbor-wise Collective on Mat

3323:    Input Parameters:
3324: +  A - the factored matrix
3325: -  B - the right-hand-side matrix  (dense matrix)

3327:    Output Parameter:
3328: .  X - the result matrix (dense matrix)

3330:    Notes:
3331:    The matrices b and x cannot be the same.  I.e., one cannot
3332:    call MatMatSolve(A,x,x).

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

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

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

3345:    Level: developer

3347:    Concepts: matrices^triangular solves

3349: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3350: @*/
3351: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3352: {

3362:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3363:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3364:   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);
3365:   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);
3366:   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);
3367:   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");
3368:   if (!A->rmap->N && !A->cmap->N) return(0);
3369:   MatCheckPreallocated(A,1);

3371:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3372:   if (!A->ops->matsolve) {
3373:     PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3374:     MatMatSolve_Basic(A,B,X);
3375:   } else {
3376:     (*A->ops->matsolve)(A,B,X);
3377:   }
3378:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3379:   PetscObjectStateIncrease((PetscObject)X);
3380:   return(0);
3381: }


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

3390:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

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

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

3416:    Level: developer

3418:    Concepts: matrices^forward solves

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

3433:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3434:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3435:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3436:   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);
3437:   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);
3438:   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);
3439:   MatCheckPreallocated(mat,1);
3440:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3441:   (*mat->ops->forwardsolve)(mat,b,x);
3442:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3443:   PetscObjectStateIncrease((PetscObject)x);
3444:   return(0);
3445: }

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

3453:    Neighbor-wise Collective on Mat and Vec

3455:    Input Parameters:
3456: +  mat - the factored matrix
3457: -  b - the right-hand-side vector

3459:    Output Parameter:
3460: .  x - the result vector

3462:    Notes:
3463:    MatSolve() should be used for most applications, as it performs
3464:    a forward solve followed by a backward solve.

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

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

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

3479:    Level: developer

3481:    Concepts: matrices^backward solves

3483: .seealso: MatSolve(), MatForwardSolve()
3484: @*/
3485: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3486: {

3496:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3497:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3498:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3499:   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);
3500:   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);
3501:   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);
3502:   MatCheckPreallocated(mat,1);

3504:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3505:   (*mat->ops->backwardsolve)(mat,b,x);
3506:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3507:   PetscObjectStateIncrease((PetscObject)x);
3508:   return(0);
3509: }

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

3516:    Neighbor-wise Collective on Mat and Vec

3518:    Input Parameters:
3519: +  mat - the factored matrix
3520: .  b - the right-hand-side vector
3521: -  y - the vector to be added to

3523:    Output Parameter:
3524: .  x - the result vector

3526:    Notes:
3527:    The vectors b and x cannot be the same.  I.e., one cannot
3528:    call MatSolveAdd(A,x,y,x).

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

3534:    Level: developer

3536:    Concepts: matrices^triangular solves

3538: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3539: @*/
3540: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3541: {
3542:   PetscScalar    one = 1.0;
3543:   Vec            tmp;

3555:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3556:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3557:   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);
3558:   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);
3559:   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);
3560:   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);
3561:   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);
3562:   MatCheckPreallocated(mat,1);

3564:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3565:   if (mat->ops->solveadd) {
3566:     (*mat->ops->solveadd)(mat,b,y,x);
3567:   } else {
3568:     /* do the solve then the add manually */
3569:     if (x != y) {
3570:       MatSolve(mat,b,x);
3571:       VecAXPY(x,one,y);
3572:     } else {
3573:       VecDuplicate(x,&tmp);
3574:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3575:       VecCopy(x,tmp);
3576:       MatSolve(mat,b,x);
3577:       VecAXPY(x,one,tmp);
3578:       VecDestroy(&tmp);
3579:     }
3580:   }
3581:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3582:   PetscObjectStateIncrease((PetscObject)x);
3583:   return(0);
3584: }

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

3591:    Neighbor-wise Collective on Mat and Vec

3593:    Input Parameters:
3594: +  mat - the factored matrix
3595: -  b - the right-hand-side vector

3597:    Output Parameter:
3598: .  x - the result vector

3600:    Notes:
3601:    The vectors b and x cannot be the same.  I.e., one cannot
3602:    call MatSolveTranspose(A,x,x).

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

3608:    Level: developer

3610:    Concepts: matrices^triangular solves

3612: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3613: @*/
3614: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3615: {

3625:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3626:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3627:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3628:   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);
3629:   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);
3630:   MatCheckPreallocated(mat,1);
3631:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3632:   if (mat->errortype) {
3633:     PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3634:     VecSetInf(x);
3635:   } else {
3636:     (*mat->ops->solvetranspose)(mat,b,x);
3637:   }
3638:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3639:   PetscObjectStateIncrease((PetscObject)x);
3640:   return(0);
3641: }

3645: /*@
3646:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3647:                       factored matrix.

3649:    Neighbor-wise Collective on Mat and Vec

3651:    Input Parameters:
3652: +  mat - the factored matrix
3653: .  b - the right-hand-side vector
3654: -  y - the vector to be added to

3656:    Output Parameter:
3657: .  x - the result vector

3659:    Notes:
3660:    The vectors b and x cannot be the same.  I.e., one cannot
3661:    call MatSolveTransposeAdd(A,x,y,x).

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

3667:    Level: developer

3669:    Concepts: matrices^triangular solves

3671: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3672: @*/
3673: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3674: {
3675:   PetscScalar    one = 1.0;
3677:   Vec            tmp;

3688:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3689:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3690:   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);
3691:   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);
3692:   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);
3693:   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);
3694:   MatCheckPreallocated(mat,1);

3696:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3697:   if (mat->ops->solvetransposeadd) {
3698:     if (mat->errortype) {
3699:       PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3700:       VecSetInf(x);
3701:     } else {
3702:       (*mat->ops->solvetransposeadd)(mat,b,y,x);
3703:     }
3704:   } else {
3705:     /* do the solve then the add manually */
3706:     if (x != y) {
3707:       MatSolveTranspose(mat,b,x);
3708:       VecAXPY(x,one,y);
3709:     } else {
3710:       VecDuplicate(x,&tmp);
3711:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3712:       VecCopy(x,tmp);
3713:       MatSolveTranspose(mat,b,x);
3714:       VecAXPY(x,one,tmp);
3715:       VecDestroy(&tmp);
3716:     }
3717:   }
3718:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3719:   PetscObjectStateIncrease((PetscObject)x);
3720:   return(0);
3721: }
3722: /* ----------------------------------------------------------------*/

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

3729:    Neighbor-wise Collective on Mat and Vec

3731:    Input Parameters:
3732: +  mat - the matrix
3733: .  b - the right hand side
3734: .  omega - the relaxation factor
3735: .  flag - flag indicating the type of SOR (see below)
3736: .  shift -  diagonal shift
3737: .  its - the number of iterations
3738: -  lits - the number of local iterations

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

3743:    SOR Flags:
3744: .     SOR_FORWARD_SWEEP - forward SOR
3745: .     SOR_BACKWARD_SWEEP - backward SOR
3746: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3747: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3748: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3749: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3750: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3751:          upper/lower triangular part of matrix to
3752:          vector (with omega)
3753: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3755:    Notes:
3756:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3757:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3758:    on each processor.

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

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

3765:    Notes for Advanced Users:
3766:    The flags are implemented as bitwise inclusive or operations.
3767:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3768:    to specify a zero initial guess for SSOR.

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

3774:    Vectors x and b CANNOT be the same

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

3778:    Level: developer

3780:    Concepts: matrices^relaxation
3781:    Concepts: matrices^SOR
3782:    Concepts: matrices^Gauss-Seidel

3784: @*/
3785: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3786: {

3796:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3797:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3798:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3799:   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);
3800:   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);
3801:   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);
3802:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3803:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3804:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3806:   MatCheckPreallocated(mat,1);
3807:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3808:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3809:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3810:   PetscObjectStateIncrease((PetscObject)x);
3811:   return(0);
3812: }

3816: /*
3817:       Default matrix copy routine.
3818: */
3819: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3820: {
3821:   PetscErrorCode    ierr;
3822:   PetscInt          i,rstart = 0,rend = 0,nz;
3823:   const PetscInt    *cwork;
3824:   const PetscScalar *vwork;

3827:   if (B->assembled) {
3828:     MatZeroEntries(B);
3829:   }
3830:   MatGetOwnershipRange(A,&rstart,&rend);
3831:   for (i=rstart; i<rend; i++) {
3832:     MatGetRow(A,i,&nz,&cwork,&vwork);
3833:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3834:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3835:   }
3836:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3837:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3838:   PetscObjectStateIncrease((PetscObject)B);
3839:   return(0);
3840: }

3844: /*@
3845:    MatCopy - Copys a matrix to another matrix.

3847:    Collective on Mat

3849:    Input Parameters:
3850: +  A - the matrix
3851: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3853:    Output Parameter:
3854: .  B - where the copy is put

3856:    Notes:
3857:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3858:    same nonzero pattern or the routine will crash.

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

3864:    Level: intermediate

3866:    Concepts: matrices^copying

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

3870: @*/
3871: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3872: {
3874:   PetscInt       i;

3882:   MatCheckPreallocated(B,2);
3883:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3884:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3885:   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);
3886:   MatCheckPreallocated(A,1);

3888:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3889:   if (A->ops->copy) {
3890:     (*A->ops->copy)(A,B,str);
3891:   } else { /* generic conversion */
3892:     MatCopy_Basic(A,B,str);
3893:   }

3895:   B->stencil.dim = A->stencil.dim;
3896:   B->stencil.noc = A->stencil.noc;
3897:   for (i=0; i<=A->stencil.dim; i++) {
3898:     B->stencil.dims[i]   = A->stencil.dims[i];
3899:     B->stencil.starts[i] = A->stencil.starts[i];
3900:   }

3902:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3903:   PetscObjectStateIncrease((PetscObject)B);
3904:   return(0);
3905: }

3909: /*@C
3910:    MatConvert - Converts a matrix to another matrix, either of the same
3911:    or different type.

3913:    Collective on Mat

3915:    Input Parameters:
3916: +  mat - the matrix
3917: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3918:    same type as the original matrix.
3919: -  reuse - denotes if the destination matrix is to be created or reused.
3920:    Use MAT_INPLACE_MATRIX for inplace conversion, otherwise use
3921:    MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX.

3923:    Output Parameter:
3924: .  M - pointer to place new matrix

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

3931:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3932:    the MPI communicator of the generated matrix is always the same as the communicator
3933:    of the input matrix.

3935:    Level: intermediate

3937:    Concepts: matrices^converting between storage formats

3939: .seealso: MatCopy(), MatDuplicate()
3940: @*/
3941: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3942: {
3944:   PetscBool      sametype,issame,flg;
3945:   char           convname[256],mtype[256];
3946:   Mat            B;

3952:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3953:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3954:   MatCheckPreallocated(mat,1);
3955:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

3957:   PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3958:   if (flg) {
3959:     newtype = mtype;
3960:   }
3961:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3962:   PetscStrcmp(newtype,"same",&issame);
3963:   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");

3965:   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) return(0);

3967:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3968:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3969:   } else {
3970:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3971:     const char     *prefix[3] = {"seq","mpi",""};
3972:     PetscInt       i;
3973:     /*
3974:        Order of precedence:
3975:        1) See if a specialized converter is known to the current matrix.
3976:        2) See if a specialized converter is known to the desired matrix class.
3977:        3) See if a good general converter is registered for the desired class
3978:           (as of 6/27/03 only MATMPIADJ falls into this category).
3979:        4) See if a good general converter is known for the current matrix.
3980:        5) Use a really basic converter.
3981:     */

3983:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3984:     for (i=0; i<3; i++) {
3985:       PetscStrcpy(convname,"MatConvert_");
3986:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3987:       PetscStrcat(convname,"_");
3988:       PetscStrcat(convname,prefix[i]);
3989:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3990:       PetscStrcat(convname,"_C");
3991:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3992:       if (conv) goto foundconv;
3993:     }

3995:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3996:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
3997:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3998:     MatSetType(B,newtype);
3999:     for (i=0; i<3; i++) {
4000:       PetscStrcpy(convname,"MatConvert_");
4001:       PetscStrcat(convname,((PetscObject)mat)->type_name);
4002:       PetscStrcat(convname,"_");
4003:       PetscStrcat(convname,prefix[i]);
4004:       PetscStrcat(convname,newtype);
4005:       PetscStrcat(convname,"_C");
4006:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
4007:       if (conv) {
4008:         MatDestroy(&B);
4009:         goto foundconv;
4010:       }
4011:     }

4013:     /* 3) See if a good general converter is registered for the desired class */
4014:     conv = B->ops->convertfrom;
4015:     MatDestroy(&B);
4016:     if (conv) goto foundconv;

4018:     /* 4) See if a good general converter is known for the current matrix */
4019:     if (mat->ops->convert) {
4020:       conv = mat->ops->convert;
4021:     }
4022:     if (conv) goto foundconv;

4024:     /* 5) Use a really basic converter. */
4025:     conv = MatConvert_Basic;

4027: foundconv:
4028:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4029:     (*conv)(mat,newtype,reuse,M);
4030:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4031:   }
4032:   PetscObjectStateIncrease((PetscObject)*M);

4034:   /* Copy Mat options */
4035:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
4036:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
4037:   return(0);
4038: }

4042: /*@C
4043:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

4045:    Not Collective

4047:    Input Parameter:
4048: .  mat - the matrix, must be a factored matrix

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

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

4057:    Level: intermediate

4059: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4060: @*/
4061: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4062: {
4063:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

4068:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4069:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
4070:   if (!conv) {
4071:     *type = MATSOLVERPETSC;
4072:   } else {
4073:     (*conv)(mat,type);
4074:   }
4075:   return(0);
4076: }

4078: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4079: struct _MatSolverPackageForSpecifcType {
4080:   MatType                        mtype;
4081:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4082:   MatSolverPackageForSpecifcType next;
4083: };

4085: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4086: struct _MatSolverPackageHolder {
4087:   char                           *name;
4088:   MatSolverPackageForSpecifcType handlers;
4089:   MatSolverPackageHolder         next;
4090: };

4092: static MatSolverPackageHolder MatSolverPackageHolders = NULL;

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

4099:    Input Parameters:
4100: +    package - name of the package, for example petsc or superlu
4101: .    mtype - the matrix type that works with this package
4102: .    ftype - the type of factorization supported by the package
4103: -    getfactor - routine that will create the factored matrix ready to be used

4105:     Level: intermediate

4107: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4108: @*/
4109: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4110: {
4111:   PetscErrorCode                 ierr;
4112:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4113:   PetscBool                      flg;
4114:   MatSolverPackageForSpecifcType inext,iprev = NULL;

4117:   if (!next) {
4118:     PetscNew(&MatSolverPackageHolders);
4119:     PetscStrallocpy(package,&MatSolverPackageHolders->name);
4120:     PetscNew(&MatSolverPackageHolders->handlers);
4121:     PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4122:     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4123:     return(0);
4124:   }
4125:   while (next) {
4126:     PetscStrcasecmp(package,next->name,&flg);
4127:     if (flg) {
4128:       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverPackageHolder is missing handlers");
4129:       inext = next->handlers;
4130:       while (inext) {
4131:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4132:         if (flg) {
4133:           inext->getfactor[(int)ftype-1] = getfactor;
4134:           return(0);
4135:         }
4136:         iprev = inext;
4137:         inext = inext->next;
4138:       }
4139:       PetscNew(&iprev->next);
4140:       PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4141:       iprev->next->getfactor[(int)ftype-1] = getfactor;
4142:       return(0);
4143:     }
4144:     prev = next;
4145:     next = next->next;
4146:   }
4147:   PetscNew(&prev->next);
4148:   PetscStrallocpy(package,&prev->next->name);
4149:   PetscNew(&prev->next->handlers);
4150:   PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4151:   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4152:   return(0);
4153: }

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

4160:    Input Parameters:
4161: +    package - name of the package, for example petsc or superlu
4162: .    ftype - the type of factorization supported by the package
4163: -    mtype - the matrix type that works with this package

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

4170:     Level: intermediate

4172: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4173: @*/
4174: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4175: {
4176:   PetscErrorCode                 ierr;
4177:   MatSolverPackageHolder         next = MatSolverPackageHolders;
4178:   PetscBool                      flg;
4179:   MatSolverPackageForSpecifcType inext;

4182:   if (foundpackage) *foundpackage = PETSC_FALSE;
4183:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4184:   if (getfactor)    *getfactor    = NULL;

4186:   if (package) {
4187:     while (next) {
4188:       PetscStrcasecmp(package,next->name,&flg);
4189:       if (flg) {
4190:         if (foundpackage) *foundpackage = PETSC_TRUE;
4191:         inext = next->handlers;
4192:         while (inext) {
4193:           PetscStrcasecmp(mtype,inext->mtype,&flg);
4194:           if (flg) {
4195:             if (foundmtype) *foundmtype = PETSC_TRUE;
4196:             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4197:             return(0);
4198:           }
4199:           inext = inext->next;
4200:         }
4201:       }
4202:       next = next->next;
4203:     }
4204:   } else {
4205:     while (next) {
4206:       inext = next->handlers;
4207:       while (inext) {
4208:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4209:         if (flg && inext->getfactor[(int)ftype-1]) {
4210:           if (foundpackage) *foundpackage = PETSC_TRUE;
4211:           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4212:           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4213:           return(0);
4214:         }
4215:         inext = inext->next;
4216:       }
4217:       next = next->next;
4218:     }
4219:   }
4220:   return(0);
4221: }

4225: PetscErrorCode MatSolverPackageDestroy(void)
4226: {
4227:   PetscErrorCode                 ierr;
4228:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4229:   MatSolverPackageForSpecifcType inext,iprev;

4232:   while (next) {
4233:     PetscFree(next->name);
4234:     inext = next->handlers;
4235:     while (inext) {
4236:       PetscFree(inext->mtype);
4237:       iprev = inext;
4238:       inext = inext->next;
4239:       PetscFree(iprev);
4240:     }
4241:     prev = next;
4242:     next = next->next;
4243:     PetscFree(prev);
4244:   }
4245:   MatSolverPackageHolders = NULL;
4246:   return(0);
4247: }

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

4254:    Collective on Mat

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

4261:    Output Parameters:
4262: .  f - the factor matrix used with MatXXFactorSymbolic() calls

4264:    Notes:
4265:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4266:      such as pastix, superlu, mumps etc.

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

4270:    Level: intermediate

4272: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4273: @*/
4274: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4275: {
4276:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4277:   PetscBool      foundpackage,foundmtype;


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

4286:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4287:   if (!foundpackage) {
4288:     if (type) {
4289:       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4290:     } else {
4291:       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4292:     }
4293:   }
4294: 
4295:   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4296:   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);

4298:   (*conv)(mat,ftype,f);
4299:   return(0);
4300: }

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

4307:    Not Collective

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

4314:    Output Parameter:
4315: .    flg - PETSC_TRUE if the factorization is available

4317:    Notes:
4318:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4319:      such as pastix, superlu, mumps etc.

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

4323:    Level: intermediate

4325: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4326: @*/
4327: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4328: {
4329:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);


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

4338:   *flg = PETSC_FALSE;
4339:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4340:   if (gconv) {
4341:     *flg = PETSC_TRUE;
4342:   }
4343:   return(0);
4344: }

4346: #include <petscdmtypes.h>

4350: /*@
4351:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4353:    Collective on Mat

4355:    Input Parameters:
4356: +  mat - the matrix
4357: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4358:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

4360:    Output Parameter:
4361: .  M - pointer to place new matrix

4363:    Level: intermediate

4365:    Concepts: matrices^duplicating

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

4369: .seealso: MatCopy(), MatConvert()
4370: @*/
4371: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4372: {
4374:   Mat            B;
4375:   PetscInt       i;
4376:   DM             dm;

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

4386:   *M = 0;
4387:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4388:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4389:   (*mat->ops->duplicate)(mat,op,M);
4390:   B    = *M;

4392:   B->stencil.dim = mat->stencil.dim;
4393:   B->stencil.noc = mat->stencil.noc;
4394:   for (i=0; i<=mat->stencil.dim; i++) {
4395:     B->stencil.dims[i]   = mat->stencil.dims[i];
4396:     B->stencil.starts[i] = mat->stencil.starts[i];
4397:   }

4399:   B->nooffproczerorows = mat->nooffproczerorows;
4400:   B->nooffprocentries  = mat->nooffprocentries;

4402:   PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4403:   if (dm) {
4404:     PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4405:   }
4406:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4407:   PetscObjectStateIncrease((PetscObject)B);
4408:   return(0);
4409: }

4413: /*@
4414:    MatGetDiagonal - Gets the diagonal of a matrix.

4416:    Logically Collective on Mat and Vec

4418:    Input Parameters:
4419: +  mat - the matrix
4420: -  v - the vector for storing the diagonal

4422:    Output Parameter:
4423: .  v - the diagonal of the matrix

4425:    Level: intermediate

4427:    Note:
4428:    Currently only correct in parallel for square matrices.

4430:    Concepts: matrices^accessing diagonals

4432: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4433: @*/
4434: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4435: {

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

4446:   (*mat->ops->getdiagonal)(mat,v);
4447:   PetscObjectStateIncrease((PetscObject)v);
4448:   return(0);
4449: }

4453: /*@C
4454:    MatGetRowMin - Gets the minimum value (of the real part) of each
4455:         row of the matrix

4457:    Logically Collective on Mat and Vec

4459:    Input Parameters:
4460: .  mat - the matrix

4462:    Output Parameter:
4463: +  v - the vector for storing the maximums
4464: -  idx - the indices of the column found for each row (optional)

4466:    Level: intermediate

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

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

4473:    Concepts: matrices^getting row maximums

4475: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4476:           MatGetRowMax()
4477: @*/
4478: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4479: {

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

4490:   (*mat->ops->getrowmin)(mat,v,idx);
4491:   PetscObjectStateIncrease((PetscObject)v);
4492:   return(0);
4493: }

4497: /*@C
4498:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4499:         row of the matrix

4501:    Logically Collective on Mat and Vec

4503:    Input Parameters:
4504: .  mat - the matrix

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

4510:    Level: intermediate

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

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

4517:    Concepts: matrices^getting row maximums

4519: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4520: @*/
4521: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4522: {

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

4534:   (*mat->ops->getrowminabs)(mat,v,idx);
4535:   PetscObjectStateIncrease((PetscObject)v);
4536:   return(0);
4537: }

4541: /*@C
4542:    MatGetRowMax - Gets the maximum value (of the real part) of each
4543:         row of the matrix

4545:    Logically Collective on Mat and Vec

4547:    Input Parameters:
4548: .  mat - the matrix

4550:    Output Parameter:
4551: +  v - the vector for storing the maximums
4552: -  idx - the indices of the column found for each row (optional)

4554:    Level: intermediate

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

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

4561:    Concepts: matrices^getting row maximums

4563: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4564: @*/
4565: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4566: {

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

4577:   (*mat->ops->getrowmax)(mat,v,idx);
4578:   PetscObjectStateIncrease((PetscObject)v);
4579:   return(0);
4580: }

4584: /*@C
4585:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4586:         row of the matrix

4588:    Logically Collective on Mat and Vec

4590:    Input Parameters:
4591: .  mat - the matrix

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

4597:    Level: intermediate

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

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

4604:    Concepts: matrices^getting row maximums

4606: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4607: @*/
4608: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4609: {

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

4621:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4622:   PetscObjectStateIncrease((PetscObject)v);
4623:   return(0);
4624: }

4628: /*@
4629:    MatGetRowSum - Gets the sum of each row of the matrix

4631:    Logically Collective on Mat and Vec

4633:    Input Parameters:
4634: .  mat - the matrix

4636:    Output Parameter:
4637: .  v - the vector for storing the sum of rows

4639:    Level: intermediate

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

4643:    Concepts: matrices^getting row sums

4645: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4646: @*/
4647: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4648: {
4649:   PetscInt       start = 0, end = 0, row;
4650:   PetscScalar    *array;

4657:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4658:   MatCheckPreallocated(mat,1);
4659:   MatGetOwnershipRange(mat, &start, &end);
4660:   VecGetArray(v, &array);
4661:   for (row = start; row < end; ++row) {
4662:     PetscInt          ncols, col;
4663:     const PetscInt    *cols;
4664:     const PetscScalar *vals;

4666:     array[row - start] = 0.0;

4668:     MatGetRow(mat, row, &ncols, &cols, &vals);
4669:     for (col = 0; col < ncols; col++) {
4670:       array[row - start] += vals[col];
4671:     }
4672:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4673:   }
4674:   VecRestoreArray(v, &array);
4675:   PetscObjectStateIncrease((PetscObject) v);
4676:   return(0);
4677: }

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

4684:    Collective on Mat

4686:    Input Parameter:
4687: +  mat - the matrix to transpose
4688: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4690:    Output Parameters:
4691: .  B - the transpose

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

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

4698:    Level: intermediate

4700:    Concepts: matrices^transposing

4702: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4703: @*/
4704: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4705: {

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

4716:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4717:   (*mat->ops->transpose)(mat,reuse,B);
4718:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4719:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4720:   return(0);
4721: }

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

4729:    Collective on Mat

4731:    Input Parameter:
4732: +  A - the matrix to test
4733: -  B - the matrix to test against, this can equal the first parameter

4735:    Output Parameters:
4736: .  flg - the result

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

4743:    Level: intermediate

4745:    Concepts: matrices^transposing, matrix^symmetry

4747: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4748: @*/
4749: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4750: {
4751:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4757:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4758:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4759:   *flg = PETSC_FALSE;
4760:   if (f && g) {
4761:     if (f == g) {
4762:       (*f)(A,B,tol,flg);
4763:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4764:   } else {
4765:     MatType mattype;
4766:     if (!f) {
4767:       MatGetType(A,&mattype);
4768:     } else {
4769:       MatGetType(B,&mattype);
4770:     }
4771:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4772:   }
4773:   return(0);
4774: }

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

4781:    Collective on Mat

4783:    Input Parameter:
4784: +  mat - the matrix to transpose and complex conjugate
4785: -  reuse - store the transpose matrix in the provided B

4787:    Output Parameters:
4788: .  B - the Hermitian

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

4793:    Level: intermediate

4795:    Concepts: matrices^transposing, complex conjugatex

4797: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4798: @*/
4799: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4800: {

4804:   MatTranspose(mat,reuse,B);
4805: #if defined(PETSC_USE_COMPLEX)
4806:   MatConjugate(*B);
4807: #endif
4808:   return(0);
4809: }

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

4816:    Collective on Mat

4818:    Input Parameter:
4819: +  A - the matrix to test
4820: -  B - the matrix to test against, this can equal the first parameter

4822:    Output Parameters:
4823: .  flg - the result

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

4830:    Level: intermediate

4832:    Concepts: matrices^transposing, matrix^symmetry

4834: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4835: @*/
4836: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4837: {
4838:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4844:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4845:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4846:   if (f && g) {
4847:     if (f==g) {
4848:       (*f)(A,B,tol,flg);
4849:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4850:   }
4851:   return(0);
4852: }

4856: /*@
4857:    MatPermute - Creates a new matrix with rows and columns permuted from the
4858:    original.

4860:    Collective on Mat

4862:    Input Parameters:
4863: +  mat - the matrix to permute
4864: .  row - row permutation, each processor supplies only the permutation for its rows
4865: -  col - column permutation, each processor supplies only the permutation for its columns

4867:    Output Parameters:
4868: .  B - the permuted matrix

4870:    Level: advanced

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

4876:    Concepts: matrices^permuting

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

4880: @*/
4881: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4882: {

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

4896:   (*mat->ops->permute)(mat,row,col,B);
4897:   PetscObjectStateIncrease((PetscObject)*B);
4898:   return(0);
4899: }

4903: /*@
4904:    MatEqual - Compares two matrices.

4906:    Collective on Mat

4908:    Input Parameters:
4909: +  A - the first matrix
4910: -  B - the second matrix

4912:    Output Parameter:
4913: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4915:    Level: intermediate

4917:    Concepts: matrices^equality between
4918: @*/
4919: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4920: {

4930:   MatCheckPreallocated(B,2);
4931:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4932:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4933:   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);
4934:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4935:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4936:   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);
4937:   MatCheckPreallocated(A,1);

4939:   (*A->ops->equal)(A,B,flg);
4940:   return(0);
4941: }

4945: /*@
4946:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4947:    matrices that are stored as vectors.  Either of the two scaling
4948:    matrices can be NULL.

4950:    Collective on Mat

4952:    Input Parameters:
4953: +  mat - the matrix to be scaled
4954: .  l - the left scaling vector (or NULL)
4955: -  r - the right scaling vector (or NULL)

4957:    Notes:
4958:    MatDiagonalScale() computes A = LAR, where
4959:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4960:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4962:    Level: intermediate

4964:    Concepts: matrices^diagonal scaling
4965:    Concepts: diagonal scaling of matrices

4967: .seealso: MatScale()
4968: @*/
4969: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4970: {

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

4983:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4984:   (*mat->ops->diagonalscale)(mat,l,r);
4985:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4986:   PetscObjectStateIncrease((PetscObject)mat);
4987: #if defined(PETSC_HAVE_CUSP)
4988:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4989:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4990:   }
4991: #elif defined(PETSC_HAVE_VIENNACL)
4992:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4993:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4994:   }
4995: #elif defined(PETSC_HAVE_VECCUDA)
4996:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4997:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4998:   }
4999: #endif
5000:   return(0);
5001: }

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

5008:     Logically Collective on Mat

5010:     Input Parameters:
5011: +   mat - the matrix to be scaled
5012: -   a  - the scaling value

5014:     Output Parameter:
5015: .   mat - the scaled matrix

5017:     Level: intermediate

5019:     Concepts: matrices^scaling all entries

5021: .seealso: MatDiagonalScale()
5022: @*/
5023: PetscErrorCode MatScale(Mat mat,PetscScalar a)
5024: {

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

5036:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5037:   if (a != (PetscScalar)1.0) {
5038:     (*mat->ops->scale)(mat,a);
5039:     PetscObjectStateIncrease((PetscObject)mat);
5040:   }
5041:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5042: #if defined(PETSC_HAVE_CUSP)
5043:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5044:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5045:   }
5046: #elif defined(PETSC_HAVE_VIENNACL)
5047:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5048:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5049:   }
5050: #elif defined(PETSC_HAVE_VECCUDA)
5051:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5052:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5053:   }
5054: #endif
5055:   return(0);
5056: }

5060: /*@
5061:    MatNorm - Calculates various norms of a matrix.

5063:    Collective on Mat

5065:    Input Parameters:
5066: +  mat - the matrix
5067: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

5069:    Output Parameters:
5070: .  nrm - the resulting norm

5072:    Level: intermediate

5074:    Concepts: matrices^norm
5075:    Concepts: norm^of matrix
5076: @*/
5077: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5078: {


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

5091:   (*mat->ops->norm)(mat,type,nrm);
5092:   return(0);
5093: }

5095: /*
5096:      This variable is used to prevent counting of MatAssemblyBegin() that
5097:    are called from within a MatAssemblyEnd().
5098: */
5099: static PetscInt MatAssemblyEnd_InUse = 0;
5102: /*@
5103:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5104:    be called after completing all calls to MatSetValues().

5106:    Collective on Mat

5108:    Input Parameters:
5109: +  mat - the matrix
5110: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5112:    Notes:
5113:    MatSetValues() generally caches the values.  The matrix is ready to
5114:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5115:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5116:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5117:    using the matrix.

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

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

5127:    Level: beginner

5129:    Concepts: matrices^assembling

5131: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5132: @*/
5133: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5134: {

5140:   MatCheckPreallocated(mat,1);
5141:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5142:   if (mat->assembled) {
5143:     mat->was_assembled = PETSC_TRUE;
5144:     mat->assembled     = PETSC_FALSE;
5145:   }
5146:   if (!MatAssemblyEnd_InUse) {
5147:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5148:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5149:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5150:   } else if (mat->ops->assemblybegin) {
5151:     (*mat->ops->assemblybegin)(mat,type);
5152:   }
5153:   return(0);
5154: }

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

5162:    Not Collective

5164:    Input Parameter:
5165: .  mat - the matrix

5167:    Output Parameter:
5168: .  assembled - PETSC_TRUE or PETSC_FALSE

5170:    Level: advanced

5172:    Concepts: matrices^assembled?

5174: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5175: @*/
5176: PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5177: {
5182:   *assembled = mat->assembled;
5183:   return(0);
5184: }

5188: /*@
5189:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5190:    be called after MatAssemblyBegin().

5192:    Collective on Mat

5194:    Input Parameters:
5195: +  mat - the matrix
5196: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5198:    Options Database Keys:
5199: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5200: .  -mat_view ::ascii_info_detail - Prints more detailed info
5201: .  -mat_view - Prints matrix in ASCII format
5202: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5203: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5204: .  -display <name> - Sets display name (default is host)
5205: .  -draw_pause <sec> - Sets number of seconds to pause after display
5206: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 11 Using MATLAB with PETSc )
5207: .  -viewer_socket_machine <machine> - Machine to use for socket
5208: .  -viewer_socket_port <port> - Port number to use for socket
5209: -  -mat_view binary:filename[:append] - Save matrix to file in binary format

5211:    Notes:
5212:    MatSetValues() generally caches the values.  The matrix is ready to
5213:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5214:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5215:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5216:    using the matrix.

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

5222:    Level: beginner

5224: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5225: @*/
5226: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5227: {
5228:   PetscErrorCode  ierr;
5229:   static PetscInt inassm = 0;
5230:   PetscBool       flg    = PETSC_FALSE;


5236:   inassm++;
5237:   MatAssemblyEnd_InUse++;
5238:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5239:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5240:     if (mat->ops->assemblyend) {
5241:       (*mat->ops->assemblyend)(mat,type);
5242:     }
5243:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5244:   } else if (mat->ops->assemblyend) {
5245:     (*mat->ops->assemblyend)(mat,type);
5246:   }

5248:   /* Flush assembly is not a true assembly */
5249:   if (type != MAT_FLUSH_ASSEMBLY) {
5250:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5251:   }
5252:   mat->insertmode = NOT_SET_VALUES;
5253:   MatAssemblyEnd_InUse--;
5254:   PetscObjectStateIncrease((PetscObject)mat);
5255:   if (!mat->symmetric_eternal) {
5256:     mat->symmetric_set              = PETSC_FALSE;
5257:     mat->hermitian_set              = PETSC_FALSE;
5258:     mat->structurally_symmetric_set = PETSC_FALSE;
5259:   }
5260: #if defined(PETSC_HAVE_CUSP)
5261:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5262:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5263:   }
5264: #elif defined(PETSC_HAVE_VIENNACL)
5265:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5266:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5267:   }
5268: #elif defined(PETSC_HAVE_VECCUDA)
5269:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5270:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5271:   }
5272: #endif
5273:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5274:     MatViewFromOptions(mat,NULL,"-mat_view");

5276:     if (mat->checksymmetryonassembly) {
5277:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5278:       if (flg) {
5279:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5280:       } else {
5281:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5282:       }
5283:     }
5284:     if (mat->nullsp && mat->checknullspaceonassembly) {
5285:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5286:     }
5287:   }
5288:   inassm--;
5289:   return(0);
5290: }

5294: /*@
5295:    MatSetOption - Sets a parameter option for a matrix. Some options
5296:    may be specific to certain storage formats.  Some options
5297:    determine how values will be inserted (or added). Sorted,
5298:    row-oriented input will generally assemble the fastest. The default
5299:    is row-oriented.

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

5303:    Input Parameters:
5304: +  mat - the matrix
5305: .  option - the option, one of those listed below (and possibly others),
5306: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5308:   Options Describing Matrix Structure:
5309: +    MAT_SPD - symmetric positive definite
5310: .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5311: .    MAT_HERMITIAN - transpose is the complex conjugation
5312: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5313: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5314:                             you set to be kept with all future use of the matrix
5315:                             including after MatAssemblyBegin/End() which could
5316:                             potentially change the symmetry structure, i.e. you
5317:                             KNOW the matrix will ALWAYS have the property you set.


5320:    Options For Use with MatSetValues():
5321:    Insert a logically dense subblock, which can be
5322: .    MAT_ROW_ORIENTED - row-oriented (default)

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

5328:    When (re)assembling a matrix, we can restrict the input for
5329:    efficiency/debugging purposes.  These options include:
5330: +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5331: .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5332: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5333: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5334: .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5335: .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5336:         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5337:         performance for very large process counts.
5338: -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5339:         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5340:         functions, instead sending only neighbor messages.

5342:    Notes:
5343:    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!

5345:    Some options are relevant only for particular matrix types and
5346:    are thus ignored by others.  Other options are not supported by
5347:    certain matrix types and will generate an error message if set.

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

5353:    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5354:    that would generate a new entry in the nonzero structure is instead
5355:    ignored.  Thus, if memory has not alredy been allocated for this particular
5356:    data, then the insertion is ignored. For dense matrices, in which
5357:    the entire array is allocated, no entries are ever ignored.
5358:    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction

5360:    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5361:    that would generate a new entry in the nonzero structure instead produces
5362:    an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction

5364:    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5365:    that would generate a new entry that has not been preallocated will
5366:    instead produce an error. (Currently supported for AIJ and BAIJ formats
5367:    only.) This is a useful flag when debugging matrix memory preallocation.
5368:    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction

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

5376:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5377:    searches during matrix assembly. When this flag is set, the hash table
5378:    is created during the first Matrix Assembly. This hash table is
5379:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5380:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5381:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5382:    supported by MATMPIBAIJ format only.

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

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

5390:    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types

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

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

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

5400:    Level: intermediate

5402:    Concepts: matrices^setting options

5404: .seealso:  MatOption, Mat

5406: @*/
5407: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5408: {

5414:   if (op > 0) {
5417:   }

5419:   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);
5420:   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()");

5422:   switch (op) {
5423:   case MAT_NO_OFF_PROC_ENTRIES:
5424:     mat->nooffprocentries = flg;
5425:     return(0);
5426:     break;
5427:   case MAT_SUBSET_OFF_PROC_ENTRIES:
5428:     mat->subsetoffprocentries = flg;
5429:     return(0);
5430:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5431:     mat->nooffproczerorows = flg;
5432:     return(0);
5433:     break;
5434:   case MAT_SPD:
5435:     mat->spd_set = PETSC_TRUE;
5436:     mat->spd     = flg;
5437:     if (flg) {
5438:       mat->symmetric                  = PETSC_TRUE;
5439:       mat->structurally_symmetric     = PETSC_TRUE;
5440:       mat->symmetric_set              = PETSC_TRUE;
5441:       mat->structurally_symmetric_set = PETSC_TRUE;
5442:     }
5443:     break;
5444:   case MAT_SYMMETRIC:
5445:     mat->symmetric = flg;
5446:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5447:     mat->symmetric_set              = PETSC_TRUE;
5448:     mat->structurally_symmetric_set = flg;
5449:     break;
5450:   case MAT_HERMITIAN:
5451:     mat->hermitian = flg;
5452:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5453:     mat->hermitian_set              = PETSC_TRUE;
5454:     mat->structurally_symmetric_set = flg;
5455:     break;
5456:   case MAT_STRUCTURALLY_SYMMETRIC:
5457:     mat->structurally_symmetric     = flg;
5458:     mat->structurally_symmetric_set = PETSC_TRUE;
5459:     break;
5460:   case MAT_SYMMETRY_ETERNAL:
5461:     mat->symmetric_eternal = flg;
5462:     break;
5463:   default:
5464:     break;
5465:   }
5466:   if (mat->ops->setoption) {
5467:     (*mat->ops->setoption)(mat,op,flg);
5468:   }
5469:   return(0);
5470: }

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

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

5479:    Input Parameters:
5480: +  mat - the matrix
5481: -  option - the option, this only responds to certain options, check the code for which ones

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

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

5488:    Level: intermediate

5490:    Concepts: matrices^setting options

5492: .seealso:  MatOption, MatSetOption()

5494: @*/
5495: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5496: {

5501:   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);
5502:   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()");

5504:   switch (op) {
5505:   case MAT_NO_OFF_PROC_ENTRIES:
5506:     *flg = mat->nooffprocentries;
5507:     break;
5508:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5509:     *flg = mat->nooffproczerorows;
5510:     break;
5511:   case MAT_SYMMETRIC:
5512:     *flg = mat->symmetric;
5513:     break;
5514:   case MAT_HERMITIAN:
5515:     *flg = mat->hermitian;
5516:     break;
5517:   case MAT_STRUCTURALLY_SYMMETRIC:
5518:     *flg = mat->structurally_symmetric;
5519:     break;
5520:   case MAT_SYMMETRY_ETERNAL:
5521:     *flg = mat->symmetric_eternal;
5522:     break;
5523:   default:
5524:     break;
5525:   }
5526:   return(0);
5527: }

5531: /*@
5532:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5533:    this routine retains the old nonzero structure.

5535:    Logically Collective on Mat

5537:    Input Parameters:
5538: .  mat - the matrix

5540:    Level: intermediate

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

5545:    Concepts: matrices^zeroing

5547: .seealso: MatZeroRows()
5548: @*/
5549: PetscErrorCode MatZeroEntries(Mat mat)
5550: {

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

5561:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5562:   (*mat->ops->zeroentries)(mat);
5563:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5564:   PetscObjectStateIncrease((PetscObject)mat);
5565: #if defined(PETSC_HAVE_CUSP)
5566:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5567:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5568:   }
5569: #elif defined(PETSC_HAVE_VIENNACL)
5570:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5571:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5572:   }
5573: #elif defined(PETSC_HAVE_VECCUDA)
5574:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5575:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5576:   }
5577: #endif
5578:   return(0);
5579: }

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

5587:    Collective on Mat

5589:    Input Parameters:
5590: +  mat - the matrix
5591: .  numRows - the number of rows to remove
5592: .  rows - the global row indices
5593: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5594: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5595: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5614:    Level: intermediate

5616:    Concepts: matrices^zeroing rows

5618: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5619: @*/
5620: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5621: {

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

5633:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5634:   MatViewFromOptions(mat,NULL,"-mat_view");
5635:   PetscObjectStateIncrease((PetscObject)mat);
5636: #if defined(PETSC_HAVE_CUSP)
5637:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5638:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5639:   }
5640: #elif defined(PETSC_HAVE_VIENNACL)
5641:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5642:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5643:   }
5644: #elif defined(PETSC_HAVE_VECCUDA)
5645:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5646:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5647:   }
5648: #endif
5649:   return(0);
5650: }

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

5658:    Collective on Mat

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

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

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

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

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

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

5684:    Level: intermediate

5686:    Concepts: matrices^zeroing rows

5688: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5689: @*/
5690: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5691: {
5693:   PetscInt       numRows;
5694:   const PetscInt *rows;

5701:   ISGetLocalSize(is,&numRows);
5702:   ISGetIndices(is,&rows);
5703:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5704:   ISRestoreIndices(is,&rows);
5705:   return(0);
5706: }

5710: /*@C
5711:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5712:    of a set of rows of a matrix.

5714:    Collective on Mat

5716:    Input Parameters:
5717: +  mat - the matrix
5718: .  numRows - the number of rows to remove
5719: .  rows - the global row indices
5720: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5721: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5722: -  b - optional vector of right hand side, that will be adjusted by provided solution

5724:    Notes:
5725:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5726:    but does not release memory.  For the dense and block diagonal
5727:    formats this does not alter the nonzero structure.

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

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

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

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

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

5748:    Level: intermediate

5750:    Concepts: matrices^zeroing rows

5752: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5753: @*/
5754: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5755: {

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

5767:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5768:   MatViewFromOptions(mat,NULL,"-mat_view");
5769:   PetscObjectStateIncrease((PetscObject)mat);
5770: #if defined(PETSC_HAVE_CUSP)
5771:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5772:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5773:   }
5774: #elif defined(PETSC_HAVE_VIENNACL)
5775:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5776:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5777:   }
5778: #elif defined(PETSC_HAVE_VECCUDA)
5779:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5780:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5781:   }
5782: #endif
5783:   return(0);
5784: }

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

5792:    Collective on Mat

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

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

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

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

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

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

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

5825:    Level: intermediate

5827:    Concepts: matrices^zeroing rows

5829: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5830: @*/
5831: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5832: {
5833:   PetscInt       numRows;
5834:   const PetscInt *rows;

5841:   ISGetLocalSize(is,&numRows);
5842:   ISGetIndices(is,&rows);
5843:   MatZeroRows(mat,numRows,rows,diag,x,b);
5844:   ISRestoreIndices(is,&rows);
5845:   return(0);
5846: }

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

5854:    Collective on Mat

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

5864:    Notes:
5865:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5866:    but does not release memory.  For the dense and block diagonal
5867:    formats this does not alter the nonzero structure.

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

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

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

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

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

5887:    In Fortran idxm and idxn should be declared as
5888: $     MatStencil idxm(4,m)
5889:    and the values inserted using
5890: $    idxm(MatStencil_i,1) = i
5891: $    idxm(MatStencil_j,1) = j
5892: $    idxm(MatStencil_k,1) = k
5893: $    idxm(MatStencil_c,1) = c
5894:    etc

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

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

5904:    Level: intermediate

5906:    Concepts: matrices^zeroing rows

5908: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5909: @*/
5910: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5911: {
5912:   PetscInt       dim     = mat->stencil.dim;
5913:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5914:   PetscInt       *dims   = mat->stencil.dims+1;
5915:   PetscInt       *starts = mat->stencil.starts;
5916:   PetscInt       *dxm    = (PetscInt*) rows;
5917:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5925:   PetscMalloc1(numRows, &jdxm);
5926:   for (i = 0; i < numRows; ++i) {
5927:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5928:     for (j = 0; j < 3-sdim; ++j) dxm++;
5929:     /* Local index in X dir */
5930:     tmp = *dxm++ - starts[0];
5931:     /* Loop over remaining dimensions */
5932:     for (j = 0; j < dim-1; ++j) {
5933:       /* If nonlocal, set index to be negative */
5934:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5935:       /* Update local index */
5936:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5937:     }
5938:     /* Skip component slot if necessary */
5939:     if (mat->stencil.noc) dxm++;
5940:     /* Local row number */
5941:     if (tmp >= 0) {
5942:       jdxm[numNewRows++] = tmp;
5943:     }
5944:   }
5945:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5946:   PetscFree(jdxm);
5947:   return(0);
5948: }

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

5956:    Collective on Mat

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

5966:    Notes:
5967:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5968:    but does not release memory.  For the dense and block diagonal
5969:    formats this does not alter the nonzero structure.

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

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

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

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

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

5989:    In Fortran idxm and idxn should be declared as
5990: $     MatStencil idxm(4,m)
5991:    and the values inserted using
5992: $    idxm(MatStencil_i,1) = i
5993: $    idxm(MatStencil_j,1) = j
5994: $    idxm(MatStencil_k,1) = k
5995: $    idxm(MatStencil_c,1) = c
5996:    etc

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

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

6006:    Level: intermediate

6008:    Concepts: matrices^zeroing rows

6010: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
6011: @*/
6012: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6013: {
6014:   PetscInt       dim     = mat->stencil.dim;
6015:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6016:   PetscInt       *dims   = mat->stencil.dims+1;
6017:   PetscInt       *starts = mat->stencil.starts;
6018:   PetscInt       *dxm    = (PetscInt*) rows;
6019:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


6027:   PetscMalloc1(numRows, &jdxm);
6028:   for (i = 0; i < numRows; ++i) {
6029:     /* Skip unused dimensions (they are ordered k, j, i, c) */
6030:     for (j = 0; j < 3-sdim; ++j) dxm++;
6031:     /* Local index in X dir */
6032:     tmp = *dxm++ - starts[0];
6033:     /* Loop over remaining dimensions */
6034:     for (j = 0; j < dim-1; ++j) {
6035:       /* If nonlocal, set index to be negative */
6036:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6037:       /* Update local index */
6038:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6039:     }
6040:     /* Skip component slot if necessary */
6041:     if (mat->stencil.noc) dxm++;
6042:     /* Local row number */
6043:     if (tmp >= 0) {
6044:       jdxm[numNewRows++] = tmp;
6045:     }
6046:   }
6047:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
6048:   PetscFree(jdxm);
6049:   return(0);
6050: }

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

6058:    Collective on Mat

6060:    Input Parameters:
6061: +  mat - the matrix
6062: .  numRows - the number of rows to remove
6063: .  rows - the global row indices
6064: .  diag - value put in all diagonals of eliminated rows
6065: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6066: -  b - optional vector of right hand side, that will be adjusted by provided solution

6068:    Notes:
6069:    Before calling MatZeroRowsLocal(), the user must first set the
6070:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6072:    For the AIJ matrix formats this removes the old nonzero structure,
6073:    but does not release memory.  For the dense and block diagonal
6074:    formats this does not alter the nonzero structure.

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

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

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

6087:    Level: intermediate

6089:    Concepts: matrices^zeroing

6091: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6092: @*/
6093: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6094: {

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

6105:   if (mat->ops->zerorowslocal) {
6106:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6107:   } else {
6108:     IS             is, newis;
6109:     const PetscInt *newRows;

6111:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6112:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6113:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6114:     ISGetIndices(newis,&newRows);
6115:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6116:     ISRestoreIndices(newis,&newRows);
6117:     ISDestroy(&newis);
6118:     ISDestroy(&is);
6119:   }
6120:   PetscObjectStateIncrease((PetscObject)mat);
6121: #if defined(PETSC_HAVE_CUSP)
6122:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6123:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6124:   }
6125: #elif defined(PETSC_HAVE_VIENNACL)
6126:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6127:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6128:   }
6129: #elif defined(PETSC_HAVE_VECCUDA)
6130:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6131:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6132:   }
6133: #endif
6134:   return(0);
6135: }

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

6143:    Collective on Mat

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

6152:    Notes:
6153:    Before calling MatZeroRowsLocalIS(), the user must first set the
6154:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6156:    For the AIJ matrix formats this removes the old nonzero structure,
6157:    but does not release memory.  For the dense and block diagonal
6158:    formats this does not alter the nonzero structure.

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

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

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

6171:    Level: intermediate

6173:    Concepts: matrices^zeroing

6175: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6176: @*/
6177: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6178: {
6180:   PetscInt       numRows;
6181:   const PetscInt *rows;

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

6191:   ISGetLocalSize(is,&numRows);
6192:   ISGetIndices(is,&rows);
6193:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6194:   ISRestoreIndices(is,&rows);
6195:   return(0);
6196: }

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

6204:    Collective on Mat

6206:    Input Parameters:
6207: +  mat - the matrix
6208: .  numRows - the number of rows to remove
6209: .  rows - the global row indices
6210: .  diag - value put in all diagonals of eliminated rows
6211: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6212: -  b - optional vector of right hand side, that will be adjusted by provided solution

6214:    Notes:
6215:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6216:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6222:    Level: intermediate

6224:    Concepts: matrices^zeroing

6226: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6227: @*/
6228: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6229: {
6231:   IS             is, newis;
6232:   const PetscInt *newRows;

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

6242:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6243:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6244:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6245:   ISGetIndices(newis,&newRows);
6246:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6247:   ISRestoreIndices(newis,&newRows);
6248:   ISDestroy(&newis);
6249:   ISDestroy(&is);
6250:   PetscObjectStateIncrease((PetscObject)mat);
6251: #if defined(PETSC_HAVE_CUSP)
6252:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6253:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6254:   }
6255: #elif defined(PETSC_HAVE_VIENNACL)
6256:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6257:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6258:   }
6259: #elif defined(PETSC_HAVE_VECCUDA)
6260:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6261:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6262:   }
6263: #endif
6264:   return(0);
6265: }

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

6273:    Collective on Mat

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

6282:    Notes:
6283:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6284:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6290:    Level: intermediate

6292:    Concepts: matrices^zeroing

6294: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6295: @*/
6296: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6297: {
6299:   PetscInt       numRows;
6300:   const PetscInt *rows;

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

6310:   ISGetLocalSize(is,&numRows);
6311:   ISGetIndices(is,&rows);
6312:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6313:   ISRestoreIndices(is,&rows);
6314:   return(0);
6315: }

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

6322:    Not Collective

6324:    Input Parameter:
6325: .  mat - the matrix

6327:    Output Parameters:
6328: +  m - the number of global rows
6329: -  n - the number of global columns

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

6333:    Level: beginner

6335:    Concepts: matrices^size

6337: .seealso: MatGetLocalSize()
6338: @*/
6339: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6340: {
6343:   if (m) *m = mat->rmap->N;
6344:   if (n) *n = mat->cmap->N;
6345:   return(0);
6346: }

6350: /*@
6351:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6352:    stored locally.  This information may be implementation dependent, so
6353:    use with care.

6355:    Not Collective

6357:    Input Parameters:
6358: .  mat - the matrix

6360:    Output Parameters:
6361: +  m - the number of local rows
6362: -  n - the number of local columns

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

6366:    Level: beginner

6368:    Concepts: matrices^local size

6370: .seealso: MatGetSize()
6371: @*/
6372: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6373: {
6378:   if (m) *m = mat->rmap->n;
6379:   if (n) *n = mat->cmap->n;
6380:   return(0);
6381: }

6385: /*@
6386:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6387:    this processor. (The columns of the "diagonal block")

6389:    Not Collective, unless matrix has not been allocated, then collective on Mat

6391:    Input Parameters:
6392: .  mat - the matrix

6394:    Output Parameters:
6395: +  m - the global index of the first local column
6396: -  n - one more than the global index of the last local column

6398:    Notes: both output parameters can be NULL on input.

6400:    Level: developer

6402:    Concepts: matrices^column ownership

6404: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

6406: @*/
6407: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6408: {
6414:   MatCheckPreallocated(mat,1);
6415:   if (m) *m = mat->cmap->rstart;
6416:   if (n) *n = mat->cmap->rend;
6417:   return(0);
6418: }

6422: /*@
6423:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6424:    this processor, assuming that the matrix is laid out with the first
6425:    n1 rows on the first processor, the next n2 rows on the second, etc.
6426:    For certain parallel layouts this range may not be well defined.

6428:    Not Collective

6430:    Input Parameters:
6431: .  mat - the matrix

6433:    Output Parameters:
6434: +  m - the global index of the first local row
6435: -  n - one more than the global index of the last local row

6437:    Note: Both output parameters can be NULL on input.
6438: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6439: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6440: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

6442:    Level: beginner

6444:    Concepts: matrices^row ownership

6446: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

6448: @*/
6449: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6450: {
6456:   MatCheckPreallocated(mat,1);
6457:   if (m) *m = mat->rmap->rstart;
6458:   if (n) *n = mat->rmap->rend;
6459:   return(0);
6460: }

6464: /*@C
6465:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6466:    each process

6468:    Not Collective, unless matrix has not been allocated, then collective on Mat

6470:    Input Parameters:
6471: .  mat - the matrix

6473:    Output Parameters:
6474: .  ranges - start of each processors portion plus one more than the total length at the end

6476:    Level: beginner

6478:    Concepts: matrices^row ownership

6480: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6482: @*/
6483: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6484: {

6490:   MatCheckPreallocated(mat,1);
6491:   PetscLayoutGetRanges(mat->rmap,ranges);
6492:   return(0);
6493: }

6497: /*@C
6498:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6499:    this processor. (The columns of the "diagonal blocks" for each process)

6501:    Not Collective, unless matrix has not been allocated, then collective on Mat

6503:    Input Parameters:
6504: .  mat - the matrix

6506:    Output Parameters:
6507: .  ranges - start of each processors portion plus one more then the total length at the end

6509:    Level: beginner

6511:    Concepts: matrices^column ownership

6513: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6515: @*/
6516: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6517: {

6523:   MatCheckPreallocated(mat,1);
6524:   PetscLayoutGetRanges(mat->cmap,ranges);
6525:   return(0);
6526: }

6530: /*@C
6531:    MatGetOwnershipIS - Get row and column ownership as index sets

6533:    Not Collective

6535:    Input Arguments:
6536: .  A - matrix of type Elemental

6538:    Output Arguments:
6539: +  rows - rows in which this process owns elements
6540: .  cols - columns in which this process owns elements

6542:    Level: intermediate

6544: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6545: @*/
6546: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6547: {
6548:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6551:   MatCheckPreallocated(A,1);
6552:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6553:   if (f) {
6554:     (*f)(A,rows,cols);
6555:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6556:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6557:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6558:   }
6559:   return(0);
6560: }

6564: /*@C
6565:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6566:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6567:    to complete the factorization.

6569:    Collective on Mat

6571:    Input Parameters:
6572: +  mat - the matrix
6573: .  row - row permutation
6574: .  column - column permutation
6575: -  info - structure containing
6576: $      levels - number of levels of fill.
6577: $      expected fill - as ratio of original fill.
6578: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6579:                 missing diagonal entries)

6581:    Output Parameters:
6582: .  fact - new matrix that has been symbolically factored

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

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

6590:    Level: developer

6592:   Concepts: matrices^symbolic LU factorization
6593:   Concepts: matrices^factorization
6594:   Concepts: LU^symbolic factorization

6596: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6597:           MatGetOrdering(), MatFactorInfo

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

6602: @*/
6603: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6604: {

6614:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6615:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6616:   if (!(fact)->ops->ilufactorsymbolic) {
6617:     const MatSolverPackage spackage;
6618:     MatFactorGetSolverPackage(fact,&spackage);
6619:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6620:   }
6621:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6622:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6623:   MatCheckPreallocated(mat,2);

6625:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6626:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6627:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6628:   return(0);
6629: }

6633: /*@C
6634:    MatICCFactorSymbolic - Performs symbolic incomplete
6635:    Cholesky factorization for a symmetric matrix.  Use
6636:    MatCholeskyFactorNumeric() to complete the factorization.

6638:    Collective on Mat

6640:    Input Parameters:
6641: +  mat - the matrix
6642: .  perm - row and column permutation
6643: -  info - structure containing
6644: $      levels - number of levels of fill.
6645: $      expected fill - as ratio of original fill.

6647:    Output Parameter:
6648: .  fact - the factored matrix

6650:    Notes:
6651:    Most users should employ the KSP interface for linear solvers
6652:    instead of working directly with matrix algebra routines such as this.
6653:    See, e.g., KSPCreate().

6655:    Level: developer

6657:   Concepts: matrices^symbolic incomplete Cholesky factorization
6658:   Concepts: matrices^factorization
6659:   Concepts: Cholsky^symbolic factorization

6661: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

6666: @*/
6667: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6668: {

6677:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6678:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6679:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6680:   if (!(fact)->ops->iccfactorsymbolic) {
6681:     const MatSolverPackage spackage;
6682:     MatFactorGetSolverPackage(fact,&spackage);
6683:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6684:   }
6685:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6686:   MatCheckPreallocated(mat,2);

6688:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6689:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6690:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6691:   return(0);
6692: }

6696: /*@C
6697:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6698:    points to an array of valid matrices, they may be reused to store the new
6699:    submatrices.

6701:    Collective on Mat

6703:    Input Parameters:
6704: +  mat - the matrix
6705: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6706: .  irow, icol - index sets of rows and columns to extract
6707: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6709:    Output Parameter:
6710: .  submat - the array of submatrices

6712:    Notes:
6713:    MatGetSubMatrices() can extract ONLY sequential submatrices
6714:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6715:    to extract a parallel submatrix.

6717:    Some matrix types place restrictions on the row and column
6718:    indices, such as that they be sorted or that they be equal to each other.

6720:    The index sets may not have duplicate entries.

6722:    When extracting submatrices from a parallel matrix, each processor can
6723:    form a different submatrix by setting the rows and columns of its
6724:    individual index sets according to the local submatrix desired.

6726:    When finished using the submatrices, the user should destroy
6727:    them with MatDestroyMatrices().

6729:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6730:    original matrix has not changed from that last call to MatGetSubMatrices().

6732:    This routine creates the matrices in submat; you should NOT create them before
6733:    calling it. It also allocates the array of matrix pointers submat.

6735:    For BAIJ matrices the index sets must respect the block structure, that is if they
6736:    request one row/column in a block, they must request all rows/columns that are in
6737:    that block. For example, if the block size is 2 you cannot request just row 0 and
6738:    column 0.

6740:    Fortran Note:
6741:    The Fortran interface is slightly different from that given below; it
6742:    requires one to pass in  as submat a Mat (integer) array of size at least m.

6744:    Level: advanced

6746:    Concepts: matrices^accessing submatrices
6747:    Concepts: submatrices

6749: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6750: @*/
6751: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6752: {
6754:   PetscInt       i;
6755:   PetscBool      eq;

6760:   if (n) {
6765:   }
6767:   if (n && scall == MAT_REUSE_MATRIX) {
6770:   }
6771:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6772:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6773:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6774:   MatCheckPreallocated(mat,1);

6776:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6777:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6778:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6779:   for (i=0; i<n; i++) {
6780:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6781:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6782:       ISEqual(irow[i],icol[i],&eq);
6783:       if (eq) {
6784:         if (mat->symmetric) {
6785:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6786:         } else if (mat->hermitian) {
6787:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6788:         } else if (mat->structurally_symmetric) {
6789:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6790:         }
6791:       }
6792:     }
6793:   }
6794:   return(0);
6795: }

6799: PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6800: {
6802:   PetscInt       i;
6803:   PetscBool      eq;

6808:   if (n) {
6813:   }
6815:   if (n && scall == MAT_REUSE_MATRIX) {
6818:   }
6819:   if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6820:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6821:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6822:   MatCheckPreallocated(mat,1);

6824:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6825:   (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6826:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6827:   for (i=0; i<n; i++) {
6828:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6829:       ISEqual(irow[i],icol[i],&eq);
6830:       if (eq) {
6831:         if (mat->symmetric) {
6832:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6833:         } else if (mat->hermitian) {
6834:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6835:         } else if (mat->structurally_symmetric) {
6836:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6837:         }
6838:       }
6839:     }
6840:   }
6841:   return(0);
6842: }

6846: /*@C
6847:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().

6849:    Collective on Mat

6851:    Input Parameters:
6852: +  n - the number of local matrices
6853: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6854:                        sequence of MatGetSubMatrices())

6856:    Level: advanced

6858:     Notes: Frees not only the matrices, but also the array that contains the matrices
6859:            In Fortran will not free the array.

6861: .seealso: MatGetSubMatrices()
6862: @*/
6863: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6864: {
6866:   PetscInt       i;

6869:   if (!*mat) return(0);
6870:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6872:   for (i=0; i<n; i++) {
6873:     MatDestroy(&(*mat)[i]);
6874:   }
6875:   /* memory is allocated even if n = 0 */
6876:   PetscFree(*mat);
6877:   *mat = NULL;
6878:   return(0);
6879: }

6883: /*@C
6884:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.

6886:    Collective on Mat

6888:    Input Parameters:
6889: .  mat - the matrix

6891:    Output Parameter:
6892: .  matstruct - the sequential matrix with the nonzero structure of mat

6894:   Level: intermediate

6896: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6897: @*/
6898: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6899: {


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

6910:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6911:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6912:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6913:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6914:   return(0);
6915: }

6919: /*@C
6920:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6922:    Collective on Mat

6924:    Input Parameters:
6925: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6926:                        sequence of MatGetSequentialNonzeroStructure())

6928:    Level: advanced

6930:     Notes: Frees not only the matrices, but also the array that contains the matrices

6932: .seealso: MatGetSeqNonzeroStructure()
6933: @*/
6934: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6935: {

6940:   MatDestroy(mat);
6941:   return(0);
6942: }

6946: /*@
6947:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6948:    replaces the index sets by larger ones that represent submatrices with
6949:    additional overlap.

6951:    Collective on Mat

6953:    Input Parameters:
6954: +  mat - the matrix
6955: .  n   - the number of index sets
6956: .  is  - the array of index sets (these index sets will changed during the call)
6957: -  ov  - the additional overlap requested

6959:    Options Database:
6960: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

6962:    Level: developer

6964:    Concepts: overlap
6965:    Concepts: ASM^computing overlap

6967: .seealso: MatGetSubMatrices()
6968: @*/
6969: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6970: {

6976:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6977:   if (n) {
6980:   }
6981:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6982:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6983:   MatCheckPreallocated(mat,1);

6985:   if (!ov) return(0);
6986:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6987:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6988:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6989:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6990:   return(0);
6991: }


6994: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);

6998: /*@
6999:    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7000:    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7001:    additional overlap.

7003:    Collective on Mat

7005:    Input Parameters:
7006: +  mat - the matrix
7007: .  n   - the number of index sets
7008: .  is  - the array of index sets (these index sets will changed during the call)
7009: -  ov  - the additional overlap requested

7011:    Options Database:
7012: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

7014:    Level: developer

7016:    Concepts: overlap
7017:    Concepts: ASM^computing overlap

7019: .seealso: MatGetSubMatrices()
7020: @*/
7021: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7022: {
7023:   PetscInt       i;

7029:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7030:   if (n) {
7033:   }
7034:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7035:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7036:   MatCheckPreallocated(mat,1);
7037:   if (!ov) return(0);
7038:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
7039:   for(i=0; i<n; i++){
7040:          MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
7041:   }
7042:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
7043:   return(0);
7044: }




7051: /*@
7052:    MatGetBlockSize - Returns the matrix block size.

7054:    Not Collective

7056:    Input Parameter:
7057: .  mat - the matrix

7059:    Output Parameter:
7060: .  bs - block size

7062:    Notes:
7063:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

7065:    If the block size has not been set yet this routine returns 1.

7067:    Level: intermediate

7069:    Concepts: matrices^block size

7071: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7072: @*/
7073: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7074: {
7078:   *bs = PetscAbs(mat->rmap->bs);
7079:   return(0);
7080: }

7084: /*@
7085:    MatGetBlockSizes - Returns the matrix block row and column sizes.

7087:    Not Collective

7089:    Input Parameter:
7090: .  mat - the matrix

7092:    Output Parameter:
7093: .  rbs - row block size
7094: .  cbs - coumn block size

7096:    Notes:
7097:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7098:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

7100:    If a block size has not been set yet this routine returns 1.

7102:    Level: intermediate

7104:    Concepts: matrices^block size

7106: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7107: @*/
7108: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7109: {
7114:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7115:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7116:   return(0);
7117: }

7121: /*@
7122:    MatSetBlockSize - Sets the matrix block size.

7124:    Logically Collective on Mat

7126:    Input Parameters:
7127: +  mat - the matrix
7128: -  bs - block size

7130:    Notes:
7131:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

7133:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

7135:    Level: intermediate

7137:    Concepts: matrices^block size

7139: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7140: @*/
7141: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7142: {

7148:   PetscLayoutSetBlockSize(mat->rmap,bs);
7149:   PetscLayoutSetBlockSize(mat->cmap,bs);
7150:   return(0);
7151: }

7155: /*@
7156:    MatSetBlockSizes - Sets the matrix block row and column sizes.

7158:    Logically Collective on Mat

7160:    Input Parameters:
7161: +  mat - the matrix
7162: -  rbs - row block size
7163: -  cbs - column block size

7165:    Notes:
7166:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7167:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

7169:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

7171:     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().

7173:    Level: intermediate

7175:    Concepts: matrices^block size

7177: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7178: @*/
7179: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7180: {

7187:   PetscLayoutSetBlockSize(mat->rmap,rbs);
7188:   PetscLayoutSetBlockSize(mat->cmap,cbs);
7189:   return(0);
7190: }

7194: /*@
7195:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

7197:    Logically Collective on Mat

7199:    Input Parameters:
7200: +  mat - the matrix
7201: .  fromRow - matrix from which to copy row block size
7202: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

7204:    Level: developer

7206:    Concepts: matrices^block size

7208: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7209: @*/
7210: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7211: {

7218:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7219:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7220:   return(0);
7221: }

7225: /*@
7226:    MatResidual - Default routine to calculate the residual.

7228:    Collective on Mat and Vec

7230:    Input Parameters:
7231: +  mat - the matrix
7232: .  b   - the right-hand-side
7233: -  x   - the approximate solution

7235:    Output Parameter:
7236: .  r - location to store the residual

7238:    Level: developer

7240: .keywords: MG, default, multigrid, residual

7242: .seealso: PCMGSetResidual()
7243: @*/
7244: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7245: {

7254:   MatCheckPreallocated(mat,1);
7255:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7256:   if (!mat->ops->residual) {
7257:     MatMult(mat,x,r);
7258:     VecAYPX(r,-1.0,b);
7259:   } else {
7260:     (*mat->ops->residual)(mat,b,x,r);
7261:   }
7262:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7263:   return(0);
7264: }

7268: /*@C
7269:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.

7271:    Collective on Mat

7273:     Input Parameters:
7274: +   mat - the matrix
7275: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7276: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7277: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7278:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7279:                  always used.

7281:     Output Parameters:
7282: +   n - number of rows in the (possibly compressed) matrix
7283: .   ia - the row pointers [of length n+1]
7284: .   ja - the column indices
7285: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7286:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

7288:     Level: developer

7290:     Notes: You CANNOT change any of the ia[] or ja[] values.

7292:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

7294:     Fortran Node

7296:            In Fortran use
7297: $           PetscInt ia(1), ja(1)
7298: $           PetscOffset iia, jja
7299: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7300: $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7301: $
7302: $          or
7303: $
7304: $           PetscInt, pointer :: ia(:),ja(:)
7305: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7306: $      Acess the ith and jth entries via ia(i) and ja(j)



7310: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7311: @*/
7312: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7313: {

7323:   MatCheckPreallocated(mat,1);
7324:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7325:   else {
7326:     *done = PETSC_TRUE;
7327:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7328:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7329:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7330:   }
7331:   return(0);
7332: }

7336: /*@C
7337:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.

7339:     Collective on Mat

7341:     Input Parameters:
7342: +   mat - the matrix
7343: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7344: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7345:                 symmetrized
7346: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7347:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7348:                  always used.
7349: .   n - number of columns in the (possibly compressed) matrix
7350: .   ia - the column pointers
7351: -   ja - the row indices

7353:     Output Parameters:
7354: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

7356:     Note:
7357:     This routine zeros out n, ia, and ja. This is to prevent accidental
7358:     us of the array after it has been restored. If you pass NULL, it will
7359:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

7361:     Level: developer

7363: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7364: @*/
7365: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7366: {

7376:   MatCheckPreallocated(mat,1);
7377:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7378:   else {
7379:     *done = PETSC_TRUE;
7380:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7381:   }
7382:   return(0);
7383: }

7387: /*@C
7388:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7389:     MatGetRowIJ().

7391:     Collective on Mat

7393:     Input Parameters:
7394: +   mat - the matrix
7395: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7396: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7397:                 symmetrized
7398: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7399:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7400:                  always used.
7401: .   n - size of (possibly compressed) matrix
7402: .   ia - the row pointers
7403: -   ja - the column indices

7405:     Output Parameters:
7406: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7408:     Note:
7409:     This routine zeros out n, ia, and ja. This is to prevent accidental
7410:     us of the array after it has been restored. If you pass NULL, it will
7411:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

7413:     Level: developer

7415: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7416: @*/
7417: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7418: {

7427:   MatCheckPreallocated(mat,1);

7429:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7430:   else {
7431:     *done = PETSC_TRUE;
7432:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7433:     if (n)  *n = 0;
7434:     if (ia) *ia = NULL;
7435:     if (ja) *ja = NULL;
7436:   }
7437:   return(0);
7438: }

7442: /*@C
7443:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7444:     MatGetColumnIJ().

7446:     Collective on Mat

7448:     Input Parameters:
7449: +   mat - the matrix
7450: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7451: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7452:                 symmetrized
7453: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7454:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7455:                  always used.

7457:     Output Parameters:
7458: +   n - size of (possibly compressed) matrix
7459: .   ia - the column pointers
7460: .   ja - the row indices
7461: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7463:     Level: developer

7465: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7466: @*/
7467: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7468: {

7477:   MatCheckPreallocated(mat,1);

7479:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7480:   else {
7481:     *done = PETSC_TRUE;
7482:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7483:     if (n)  *n = 0;
7484:     if (ia) *ia = NULL;
7485:     if (ja) *ja = NULL;
7486:   }
7487:   return(0);
7488: }

7492: /*@C
7493:     MatColoringPatch -Used inside matrix coloring routines that
7494:     use MatGetRowIJ() and/or MatGetColumnIJ().

7496:     Collective on Mat

7498:     Input Parameters:
7499: +   mat - the matrix
7500: .   ncolors - max color value
7501: .   n   - number of entries in colorarray
7502: -   colorarray - array indicating color for each column

7504:     Output Parameters:
7505: .   iscoloring - coloring generated using colorarray information

7507:     Level: developer

7509: .seealso: MatGetRowIJ(), MatGetColumnIJ()

7511: @*/
7512: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7513: {

7521:   MatCheckPreallocated(mat,1);

7523:   if (!mat->ops->coloringpatch) {
7524:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7525:   } else {
7526:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7527:   }
7528:   return(0);
7529: }


7534: /*@
7535:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.

7537:    Logically Collective on Mat

7539:    Input Parameter:
7540: .  mat - the factored matrix to be reset

7542:    Notes:
7543:    This routine should be used only with factored matrices formed by in-place
7544:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7545:    format).  This option can save memory, for example, when solving nonlinear
7546:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7547:    ILU(0) preconditioner.

7549:    Note that one can specify in-place ILU(0) factorization by calling
7550: .vb
7551:      PCType(pc,PCILU);
7552:      PCFactorSeUseInPlace(pc);
7553: .ve
7554:    or by using the options -pc_type ilu -pc_factor_in_place

7556:    In-place factorization ILU(0) can also be used as a local
7557:    solver for the blocks within the block Jacobi or additive Schwarz
7558:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7559:    for details on setting local solver options.

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

7565:    Level: developer

7567: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()

7569:    Concepts: matrices^unfactored

7571: @*/
7572: PetscErrorCode MatSetUnfactored(Mat mat)
7573: {

7579:   MatCheckPreallocated(mat,1);
7580:   mat->factortype = MAT_FACTOR_NONE;
7581:   if (!mat->ops->setunfactored) return(0);
7582:   (*mat->ops->setunfactored)(mat);
7583:   return(0);
7584: }

7586: /*MC
7587:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7589:     Synopsis:
7590:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7592:     Not collective

7594:     Input Parameter:
7595: .   x - matrix

7597:     Output Parameters:
7598: +   xx_v - the Fortran90 pointer to the array
7599: -   ierr - error code

7601:     Example of Usage:
7602: .vb
7603:       PetscScalar, pointer xx_v(:,:)
7604:       ....
7605:       call MatDenseGetArrayF90(x,xx_v,ierr)
7606:       a = xx_v(3)
7607:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7608: .ve

7610:     Level: advanced

7612: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()

7614:     Concepts: matrices^accessing array

7616: M*/

7618: /*MC
7619:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7620:     accessed with MatDenseGetArrayF90().

7622:     Synopsis:
7623:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7625:     Not collective

7627:     Input Parameters:
7628: +   x - matrix
7629: -   xx_v - the Fortran90 pointer to the array

7631:     Output Parameter:
7632: .   ierr - error code

7634:     Example of Usage:
7635: .vb
7636:        PetscScalar, pointer xx_v(:,:)
7637:        ....
7638:        call MatDenseGetArrayF90(x,xx_v,ierr)
7639:        a = xx_v(3)
7640:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7641: .ve

7643:     Level: advanced

7645: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()

7647: M*/


7650: /*MC
7651:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7653:     Synopsis:
7654:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7656:     Not collective

7658:     Input Parameter:
7659: .   x - matrix

7661:     Output Parameters:
7662: +   xx_v - the Fortran90 pointer to the array
7663: -   ierr - error code

7665:     Example of Usage:
7666: .vb
7667:       PetscScalar, pointer xx_v(:)
7668:       ....
7669:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7670:       a = xx_v(3)
7671:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7672: .ve

7674:     Level: advanced

7676: .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()

7678:     Concepts: matrices^accessing array

7680: M*/

7682: /*MC
7683:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7684:     accessed with MatSeqAIJGetArrayF90().

7686:     Synopsis:
7687:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7689:     Not collective

7691:     Input Parameters:
7692: +   x - matrix
7693: -   xx_v - the Fortran90 pointer to the array

7695:     Output Parameter:
7696: .   ierr - error code

7698:     Example of Usage:
7699: .vb
7700:        PetscScalar, pointer xx_v(:)
7701:        ....
7702:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7703:        a = xx_v(3)
7704:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7705: .ve

7707:     Level: advanced

7709: .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()

7711: M*/


7716: /*@
7717:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7718:                       as the original matrix.

7720:     Collective on Mat

7722:     Input Parameters:
7723: +   mat - the original matrix
7724: .   isrow - parallel IS containing the rows this processor should obtain
7725: .   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.
7726: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7728:     Output Parameter:
7729: .   newmat - the new submatrix, of the same type as the old

7731:     Level: advanced

7733:     Notes:
7734:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7736:     Some matrix types place restrictions on the row and column indices, such
7737:     as that they be sorted or that they be equal to each other.

7739:     The index sets may not have duplicate entries.

7741:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7742:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7743:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7744:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7745:    you are finished using it.

7747:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7748:     the input matrix.

7750:     If iscol is NULL then all columns are obtained (not supported in Fortran).

7752:    Example usage:
7753:    Consider the following 8x8 matrix with 34 non-zero values, that is
7754:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7755:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7756:    as follows:

7758: .vb
7759:             1  2  0  |  0  3  0  |  0  4
7760:     Proc0   0  5  6  |  7  0  0  |  8  0
7761:             9  0 10  | 11  0  0  | 12  0
7762:     -------------------------------------
7763:            13  0 14  | 15 16 17  |  0  0
7764:     Proc1   0 18  0  | 19 20 21  |  0  0
7765:             0  0  0  | 22 23  0  | 24  0
7766:     -------------------------------------
7767:     Proc2  25 26 27  |  0  0 28  | 29  0
7768:            30  0  0  | 31 32 33  |  0 34
7769: .ve

7771:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7773: .vb
7774:             2  0  |  0  3  0  |  0
7775:     Proc0   5  6  |  7  0  0  |  8
7776:     -------------------------------
7777:     Proc1  18  0  | 19 20 21  |  0
7778:     -------------------------------
7779:     Proc2  26 27  |  0  0 28  | 29
7780:             0  0  | 31 32 33  |  0
7781: .ve


7784:     Concepts: matrices^submatrices

7786: .seealso: MatGetSubMatrices()
7787: @*/
7788: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7789: {
7791:   PetscMPIInt    size;
7792:   Mat            *local;
7793:   IS             iscoltmp;

7802:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7803:   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");

7805:   MatCheckPreallocated(mat,1);
7806:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7808:   if (!iscol || isrow == iscol) {
7809:     PetscBool   stride;
7810:     PetscMPIInt grabentirematrix = 0,grab;
7811:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7812:     if (stride) {
7813:       PetscInt first,step,n,rstart,rend;
7814:       ISStrideGetInfo(isrow,&first,&step);
7815:       if (step == 1) {
7816:         MatGetOwnershipRange(mat,&rstart,&rend);
7817:         if (rstart == first) {
7818:           ISGetLocalSize(isrow,&n);
7819:           if (n == rend-rstart) {
7820:             grabentirematrix = 1;
7821:           }
7822:         }
7823:       }
7824:     }
7825:     MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7826:     if (grab) {
7827:       PetscInfo(mat,"Getting entire matrix as submatrix\n");
7828:       if (cll == MAT_INITIAL_MATRIX) {
7829:         *newmat = mat;
7830:         PetscObjectReference((PetscObject)mat);
7831:       }
7832:       return(0);
7833:     }
7834:   }

7836:   if (!iscol) {
7837:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7838:   } else {
7839:     iscoltmp = iscol;
7840:   }

7842:   /* if original matrix is on just one processor then use submatrix generated */
7843:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7844:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7845:     if (!iscol) {ISDestroy(&iscoltmp);}
7846:     return(0);
7847:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7848:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7849:     *newmat = *local;
7850:     PetscFree(local);
7851:     if (!iscol) {ISDestroy(&iscoltmp);}
7852:     return(0);
7853:   } else if (!mat->ops->getsubmatrix) {
7854:     /* Create a new matrix type that implements the operation using the full matrix */
7855:     PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7856:     switch (cll) {
7857:     case MAT_INITIAL_MATRIX:
7858:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7859:       break;
7860:     case MAT_REUSE_MATRIX:
7861:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7862:       break;
7863:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7864:     }
7865:     PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7866:     if (!iscol) {ISDestroy(&iscoltmp);}
7867:     return(0);
7868:   }

7870:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7871:   PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7872:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7873:   PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7874:   if (!iscol) {ISDestroy(&iscoltmp);}
7875:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7876:   return(0);
7877: }

7881: /*@
7882:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7883:    used during the assembly process to store values that belong to
7884:    other processors.

7886:    Not Collective

7888:    Input Parameters:
7889: +  mat   - the matrix
7890: .  size  - the initial size of the stash.
7891: -  bsize - the initial size of the block-stash(if used).

7893:    Options Database Keys:
7894: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7895: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7897:    Level: intermediate

7899:    Notes:
7900:      The block-stash is used for values set with MatSetValuesBlocked() while
7901:      the stash is used for values set with MatSetValues()

7903:      Run with the option -info and look for output of the form
7904:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7905:      to determine the appropriate value, MM, to use for size and
7906:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7907:      to determine the value, BMM to use for bsize

7909:    Concepts: stash^setting matrix size
7910:    Concepts: matrices^stash

7912: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7914: @*/
7915: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7916: {

7922:   MatStashSetInitialSize_Private(&mat->stash,size);
7923:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7924:   return(0);
7925: }

7929: /*@
7930:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7931:      the matrix

7933:    Neighbor-wise Collective on Mat

7935:    Input Parameters:
7936: +  mat   - the matrix
7937: .  x,y - the vectors
7938: -  w - where the result is stored

7940:    Level: intermediate

7942:    Notes:
7943:     w may be the same vector as y.

7945:     This allows one to use either the restriction or interpolation (its transpose)
7946:     matrix to do the interpolation

7948:     Concepts: interpolation

7950: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7952: @*/
7953: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7954: {
7956:   PetscInt       M,N,Ny;

7964:   MatCheckPreallocated(A,1);
7965:   MatGetSize(A,&M,&N);
7966:   VecGetSize(y,&Ny);
7967:   if (M == Ny) {
7968:     MatMultAdd(A,x,y,w);
7969:   } else {
7970:     MatMultTransposeAdd(A,x,y,w);
7971:   }
7972:   return(0);
7973: }

7977: /*@
7978:    MatInterpolate - y = A*x or A'*x depending on the shape of
7979:      the matrix

7981:    Neighbor-wise Collective on Mat

7983:    Input Parameters:
7984: +  mat   - the matrix
7985: -  x,y - the vectors

7987:    Level: intermediate

7989:    Notes:
7990:     This allows one to use either the restriction or interpolation (its transpose)
7991:     matrix to do the interpolation

7993:    Concepts: matrices^interpolation

7995: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7997: @*/
7998: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7999: {
8001:   PetscInt       M,N,Ny;

8008:   MatCheckPreallocated(A,1);
8009:   MatGetSize(A,&M,&N);
8010:   VecGetSize(y,&Ny);
8011:   if (M == Ny) {
8012:     MatMult(A,x,y);
8013:   } else {
8014:     MatMultTranspose(A,x,y);
8015:   }
8016:   return(0);
8017: }

8021: /*@
8022:    MatRestrict - y = A*x or A'*x

8024:    Neighbor-wise Collective on Mat

8026:    Input Parameters:
8027: +  mat   - the matrix
8028: -  x,y - the vectors

8030:    Level: intermediate

8032:    Notes:
8033:     This allows one to use either the restriction or interpolation (its transpose)
8034:     matrix to do the restriction

8036:    Concepts: matrices^restriction

8038: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()

8040: @*/
8041: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8042: {
8044:   PetscInt       M,N,Ny;

8051:   MatCheckPreallocated(A,1);

8053:   MatGetSize(A,&M,&N);
8054:   VecGetSize(y,&Ny);
8055:   if (M == Ny) {
8056:     MatMult(A,x,y);
8057:   } else {
8058:     MatMultTranspose(A,x,y);
8059:   }
8060:   return(0);
8061: }

8065: /*@
8066:    MatGetNullSpace - retrieves the null space to a matrix.

8068:    Logically Collective on Mat and MatNullSpace

8070:    Input Parameters:
8071: +  mat - the matrix
8072: -  nullsp - the null space object

8074:    Level: developer

8076:    Concepts: null space^attaching to matrix

8078: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8079: @*/
8080: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8081: {
8086:   *nullsp = mat->nullsp;
8087:   return(0);
8088: }

8092: /*@
8093:    MatSetNullSpace - attaches a null space to a matrix.

8095:    Logically Collective on Mat and MatNullSpace

8097:    Input Parameters:
8098: +  mat - the matrix
8099: -  nullsp - the null space object

8101:    Level: advanced

8103:    Notes:
8104:       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached

8106:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8107:       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.

8109:       You can remove the null space by calling this routine with an nullsp of NULL


8112:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8113:    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8114:    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8115:    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8116:    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).

8118:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

8120:    Concepts: null space^attaching to matrix

8122: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8123: @*/
8124: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8125: {

8132:   MatCheckPreallocated(mat,1);
8133:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8134:   MatNullSpaceDestroy(&mat->nullsp);
8135:   mat->nullsp = nullsp;
8136:   return(0);
8137: }

8141: /*@
8142:    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.

8144:    Logically Collective on Mat and MatNullSpace

8146:    Input Parameters:
8147: +  mat - the matrix
8148: -  nullsp - the null space object

8150:    Level: developer

8152:    Concepts: null space^attaching to matrix

8154: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8155: @*/
8156: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8157: {
8162:   *nullsp = mat->transnullsp;
8163:   return(0);
8164: }

8168: /*@
8169:    MatSetTransposeNullSpace - attaches a null space to a matrix.

8171:    Logically Collective on Mat and MatNullSpace

8173:    Input Parameters:
8174: +  mat - the matrix
8175: -  nullsp - the null space object

8177:    Level: advanced

8179:    Notes:
8180:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) this allows the linear system to be solved in a least squares sense.
8181:       You must also call MatSetNullSpace()


8184:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8185:    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8186:    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8187:    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8188:    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).

8190:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

8192:    Concepts: null space^attaching to matrix

8194: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8195: @*/
8196: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8197: {

8204:   MatCheckPreallocated(mat,1);
8205:   PetscObjectReference((PetscObject)nullsp);
8206:   MatNullSpaceDestroy(&mat->transnullsp);
8207:   mat->transnullsp = nullsp;
8208:   return(0);
8209: }

8213: /*@
8214:    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8215:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

8217:    Logically Collective on Mat and MatNullSpace

8219:    Input Parameters:
8220: +  mat - the matrix
8221: -  nullsp - the null space object

8223:    Level: advanced

8225:    Notes:
8226:       Overwrites any previous near null space that may have been attached

8228:       You can remove the null space by calling this routine with an nullsp of NULL

8230:    Concepts: null space^attaching to matrix

8232: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8233: @*/
8234: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8235: {

8242:   MatCheckPreallocated(mat,1);
8243:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8244:   MatNullSpaceDestroy(&mat->nearnullsp);
8245:   mat->nearnullsp = nullsp;
8246:   return(0);
8247: }

8251: /*@
8252:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

8254:    Not Collective

8256:    Input Parameters:
8257: .  mat - the matrix

8259:    Output Parameters:
8260: .  nullsp - the null space object, NULL if not set

8262:    Level: developer

8264:    Concepts: null space^attaching to matrix

8266: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8267: @*/
8268: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8269: {
8274:   MatCheckPreallocated(mat,1);
8275:   *nullsp = mat->nearnullsp;
8276:   return(0);
8277: }

8281: /*@C
8282:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

8284:    Collective on Mat

8286:    Input Parameters:
8287: +  mat - the matrix
8288: .  row - row/column permutation
8289: .  fill - expected fill factor >= 1.0
8290: -  level - level of fill, for ICC(k)

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

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

8300:    Level: developer

8302:    Concepts: matrices^incomplete Cholesky factorization
8303:    Concepts: Cholesky factorization

8305: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

8310: @*/
8311: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8312: {

8320:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8321:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8322:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8323:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8324:   MatCheckPreallocated(mat,1);
8325:   (*mat->ops->iccfactor)(mat,row,info);
8326:   PetscObjectStateIncrease((PetscObject)mat);
8327:   return(0);
8328: }

8332: /*@
8333:    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.

8335:    Not Collective

8337:    Input Parameters:
8338: +  mat - the matrix
8339: .  nl - leading dimension of v
8340: -  v - the values compute with ADIFOR

8342:    Level: developer

8344:    Notes:
8345:      Must call MatSetColoring() before using this routine. Also this matrix must already
8346:      have its nonzero pattern determined.

8348: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8349:           MatSetValues(), MatSetColoring()
8350: @*/
8351: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8352: {


8360:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8361:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
8362:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8363:   (*mat->ops->setvaluesadifor)(mat,nl,v);
8364:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
8365:   PetscObjectStateIncrease((PetscObject)mat);
8366:   return(0);
8367: }

8371: /*@
8372:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8373:          ghosted ones.

8375:    Not Collective

8377:    Input Parameters:
8378: +  mat - the matrix
8379: -  diag = the diagonal values, including ghost ones

8381:    Level: developer

8383:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

8385: .seealso: MatDiagonalScale()
8386: @*/
8387: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8388: {
8390:   PetscMPIInt    size;


8397:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8398:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8399:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8400:   if (size == 1) {
8401:     PetscInt n,m;
8402:     VecGetSize(diag,&n);
8403:     MatGetSize(mat,0,&m);
8404:     if (m == n) {
8405:       MatDiagonalScale(mat,0,diag);
8406:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8407:   } else {
8408:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8409:   }
8410:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8411:   PetscObjectStateIncrease((PetscObject)mat);
8412:   return(0);
8413: }

8417: /*@
8418:    MatGetInertia - Gets the inertia from a factored matrix

8420:    Collective on Mat

8422:    Input Parameter:
8423: .  mat - the matrix

8425:    Output Parameters:
8426: +   nneg - number of negative eigenvalues
8427: .   nzero - number of zero eigenvalues
8428: -   npos - number of positive eigenvalues

8430:    Level: advanced

8432:    Notes: Matrix must have been factored by MatCholeskyFactor()


8435: @*/
8436: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8437: {

8443:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8444:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8445:   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8446:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8447:   return(0);
8448: }

8450: /* ----------------------------------------------------------------*/
8453: /*@C
8454:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

8456:    Neighbor-wise Collective on Mat and Vecs

8458:    Input Parameters:
8459: +  mat - the factored matrix
8460: -  b - the right-hand-side vectors

8462:    Output Parameter:
8463: .  x - the result vectors

8465:    Notes:
8466:    The vectors b and x cannot be the same.  I.e., one cannot
8467:    call MatSolves(A,x,x).

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

8474:    Level: developer

8476:    Concepts: matrices^triangular solves

8478: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8479: @*/
8480: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8481: {

8487:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8488:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8489:   if (!mat->rmap->N && !mat->cmap->N) return(0);

8491:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8492:   MatCheckPreallocated(mat,1);
8493:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8494:   (*mat->ops->solves)(mat,b,x);
8495:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8496:   return(0);
8497: }

8501: /*@
8502:    MatIsSymmetric - Test whether a matrix is symmetric

8504:    Collective on Mat

8506:    Input Parameter:
8507: +  A - the matrix to test
8508: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

8510:    Output Parameters:
8511: .  flg - the result

8513:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

8515:    Level: intermediate

8517:    Concepts: matrix^symmetry

8519: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8520: @*/
8521: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8522: {


8529:   if (!A->symmetric_set) {
8530:     if (!A->ops->issymmetric) {
8531:       MatType mattype;
8532:       MatGetType(A,&mattype);
8533:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8534:     }
8535:     (*A->ops->issymmetric)(A,tol,flg);
8536:     if (!tol) {
8537:       A->symmetric_set = PETSC_TRUE;
8538:       A->symmetric     = *flg;
8539:       if (A->symmetric) {
8540:         A->structurally_symmetric_set = PETSC_TRUE;
8541:         A->structurally_symmetric     = PETSC_TRUE;
8542:       }
8543:     }
8544:   } else if (A->symmetric) {
8545:     *flg = PETSC_TRUE;
8546:   } else if (!tol) {
8547:     *flg = PETSC_FALSE;
8548:   } else {
8549:     if (!A->ops->issymmetric) {
8550:       MatType mattype;
8551:       MatGetType(A,&mattype);
8552:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8553:     }
8554:     (*A->ops->issymmetric)(A,tol,flg);
8555:   }
8556:   return(0);
8557: }

8561: /*@
8562:    MatIsHermitian - Test whether a matrix is Hermitian

8564:    Collective on Mat

8566:    Input Parameter:
8567: +  A - the matrix to test
8568: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

8570:    Output Parameters:
8571: .  flg - the result

8573:    Level: intermediate

8575:    Concepts: matrix^symmetry

8577: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8578:           MatIsSymmetricKnown(), MatIsSymmetric()
8579: @*/
8580: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8581: {


8588:   if (!A->hermitian_set) {
8589:     if (!A->ops->ishermitian) {
8590:       MatType mattype;
8591:       MatGetType(A,&mattype);
8592:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8593:     }
8594:     (*A->ops->ishermitian)(A,tol,flg);
8595:     if (!tol) {
8596:       A->hermitian_set = PETSC_TRUE;
8597:       A->hermitian     = *flg;
8598:       if (A->hermitian) {
8599:         A->structurally_symmetric_set = PETSC_TRUE;
8600:         A->structurally_symmetric     = PETSC_TRUE;
8601:       }
8602:     }
8603:   } else if (A->hermitian) {
8604:     *flg = PETSC_TRUE;
8605:   } else if (!tol) {
8606:     *flg = PETSC_FALSE;
8607:   } else {
8608:     if (!A->ops->ishermitian) {
8609:       MatType mattype;
8610:       MatGetType(A,&mattype);
8611:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8612:     }
8613:     (*A->ops->ishermitian)(A,tol,flg);
8614:   }
8615:   return(0);
8616: }

8620: /*@
8621:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

8623:    Not Collective

8625:    Input Parameter:
8626: .  A - the matrix to check

8628:    Output Parameters:
8629: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8630: -  flg - the result

8632:    Level: advanced

8634:    Concepts: matrix^symmetry

8636:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8637:          if you want it explicitly checked

8639: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8640: @*/
8641: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8642: {
8647:   if (A->symmetric_set) {
8648:     *set = PETSC_TRUE;
8649:     *flg = A->symmetric;
8650:   } else {
8651:     *set = PETSC_FALSE;
8652:   }
8653:   return(0);
8654: }

8658: /*@
8659:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8661:    Not Collective

8663:    Input Parameter:
8664: .  A - the matrix to check

8666:    Output Parameters:
8667: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8668: -  flg - the result

8670:    Level: advanced

8672:    Concepts: matrix^symmetry

8674:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8675:          if you want it explicitly checked

8677: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8678: @*/
8679: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8680: {
8685:   if (A->hermitian_set) {
8686:     *set = PETSC_TRUE;
8687:     *flg = A->hermitian;
8688:   } else {
8689:     *set = PETSC_FALSE;
8690:   }
8691:   return(0);
8692: }

8696: /*@
8697:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8699:    Collective on Mat

8701:    Input Parameter:
8702: .  A - the matrix to test

8704:    Output Parameters:
8705: .  flg - the result

8707:    Level: intermediate

8709:    Concepts: matrix^symmetry

8711: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8712: @*/
8713: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8714: {

8720:   if (!A->structurally_symmetric_set) {
8721:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8722:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);

8724:     A->structurally_symmetric_set = PETSC_TRUE;
8725:   }
8726:   *flg = A->structurally_symmetric;
8727:   return(0);
8728: }

8732: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8733: /*@
8734:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8735:        to be communicated to other processors during the MatAssemblyBegin/End() process

8737:     Not collective

8739:    Input Parameter:
8740: .   vec - the vector

8742:    Output Parameters:
8743: +   nstash   - the size of the stash
8744: .   reallocs - the number of additional mallocs incurred.
8745: .   bnstash   - the size of the block stash
8746: -   breallocs - the number of additional mallocs incurred.in the block stash

8748:    Level: advanced

8750: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()

8752: @*/
8753: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8754: {

8758:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8759:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8760:   return(0);
8761: }

8765: /*@C
8766:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8767:      parallel layout

8769:    Collective on Mat

8771:    Input Parameter:
8772: .  mat - the matrix

8774:    Output Parameter:
8775: +   right - (optional) vector that the matrix can be multiplied against
8776: -   left - (optional) vector that the matrix vector product can be stored in

8778:    Notes:
8779:     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().

8781:   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed

8783:   Level: advanced

8785: .seealso: MatCreate(), VecDestroy()
8786: @*/
8787: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8788: {

8794:   if (mat->ops->getvecs) {
8795:     (*mat->ops->getvecs)(mat,right,left);
8796:   } else {
8797:     PetscInt rbs,cbs;
8798:     MatGetBlockSizes(mat,&rbs,&cbs);
8799:     if (right) {
8800:       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8801:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8802:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8803:       VecSetBlockSize(*right,cbs);
8804:       VecSetType(*right,VECSTANDARD);
8805:       PetscLayoutReference(mat->cmap,&(*right)->map);
8806:     }
8807:     if (left) {
8808:       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8809:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8810:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8811:       VecSetBlockSize(*left,rbs);
8812:       VecSetType(*left,VECSTANDARD);
8813:       PetscLayoutReference(mat->rmap,&(*left)->map);
8814:     }
8815:   }
8816:   return(0);
8817: }

8821: /*@C
8822:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8823:      with default values.

8825:    Not Collective

8827:    Input Parameters:
8828: .    info - the MatFactorInfo data structure


8831:    Notes: The solvers are generally used through the KSP and PC objects, for example
8832:           PCLU, PCILU, PCCHOLESKY, PCICC

8834:    Level: developer

8836: .seealso: MatFactorInfo

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

8841: @*/

8843: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8844: {

8848:   PetscMemzero(info,sizeof(MatFactorInfo));
8849:   return(0);
8850: }

8854: /*@
8855:    MatFactorSetSchurIS - Set indices corresponding to the Schur complement

8857:    Collective on Mat

8859:    Input Parameters:
8860: +  mat - the factored matrix
8861: -  is - the index set defining the Schur indices (0-based)

8863:    Notes:

8865:    Level: developer

8867:    Concepts:

8869: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()

8871: @*/
8872: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8873: {
8874:   PetscErrorCode ierr,(*f)(Mat,IS);

8882:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8883:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8884:   if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverPackage does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
8885:   (*f)(mat,is);
8886:   return(0);
8887: }

8891: /*@
8892:   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step

8894:    Logically Collective on Mat

8896:    Input Parameters:
8897: +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8898: .  *S - location where to return the Schur complement (MATDENSE)

8900:    Notes:
8901:    The routine provides a copy of the Schur data stored within solver's data strutures. The caller must destroy the object when it is no longer needed.
8902:    If MatFactorInvertSchurComplement has been called, the routine gets back the inverse

8904:    Level: advanced

8906:    References:

8908: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement()
8909: @*/
8910: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S)
8911: {

8916:   PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));
8917:   return(0);
8918: }

8922: /*@
8923:   MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data

8925:    Logically Collective on Mat

8927:    Input Parameters:
8928: +  F - the factored matrix obtained by calling MatGetFactor()
8929: .  *S - location where to return the Schur complement (in MATDENSE format)

8931:    Notes:
8932:    Schur complement mode is currently implemented for sequential matrices.
8933:    The routine returns a dense matrix pointing to the raw data of the Schur Complement stored within the data strutures of the solver; e.g. if MatFactorInvertSchurComplement has been called, the returned matrix is actually the inverse of the Schur complement.
8934:    The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.

8936:    Level: advanced

8938:    References:

8940: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8941: @*/
8942: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S)
8943: {

8948:   PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));
8949:   return(0);
8950: }

8954: /*@
8955:   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement

8957:    Logically Collective on Mat

8959:    Input Parameters:
8960: +  F - the factored matrix obtained by calling MatGetFactor()
8961: .  *S - location where the Schur complement is stored

8963:    Notes:

8965:    Level: advanced

8967:    References:

8969: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8970: @*/
8971: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S)
8972: {

8978:   MatDestroy(S);
8979:   return(0);
8980: }

8984: /*@
8985:   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step

8987:    Logically Collective on Mat

8989:    Input Parameters:
8990: +  F - the factored matrix obtained by calling MatGetFactor()
8991: .  rhs - location where the right hand side of the Schur complement system is stored
8992: -  sol - location where the solution of the Schur complement system has to be returned

8994:    Notes:
8995:    The sizes of the vectors should match the size of the Schur complement

8997:    Level: advanced

8999:    References:

9001: .seealso: MatGetFactor(), MatFactorSetSchurIS()
9002: @*/
9003: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9004: {

9013:   PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));
9014:   return(0);
9015: }

9019: /*@
9020:   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step

9022:    Logically Collective on Mat

9024:    Input Parameters:
9025: +  F - the factored matrix obtained by calling MatGetFactor()
9026: .  rhs - location where the right hand side of the Schur complement system is stored
9027: -  sol - location where the solution of the Schur complement system has to be returned

9029:    Notes:
9030:    The sizes of the vectors should match the size of the Schur complement

9032:    Level: advanced

9034:    References:

9036: .seealso: MatGetFactor(), MatFactorSetSchurIS()
9037: @*/
9038: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9039: {

9048:   PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));
9049:   return(0);
9050: }

9054: /*@
9055:   MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step

9057:    Logically Collective on Mat

9059:    Input Parameters:
9060: +  F - the factored matrix obtained by calling MatGetFactor()

9062:    Notes:

9064:    Level: advanced

9066:    References:

9068: .seealso: MatGetFactor(), MatFactorSetSchurIS()
9069: @*/
9070: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9071: {

9076:   PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));
9077:   return(0);
9078: }


9083: /*@
9084:    MatPtAP - Creates the matrix product C = P^T * A * P

9086:    Neighbor-wise Collective on Mat

9088:    Input Parameters:
9089: +  A - the matrix
9090: .  P - the projection matrix
9091: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9092: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9093:           if the result is a dense matrix this is irrelevent

9095:    Output Parameters:
9096: .  C - the product matrix

9098:    Notes:
9099:    C will be created and must be destroyed by the user with MatDestroy().

9101:    This routine is currently only implemented for pairs of AIJ matrices and classes
9102:    which inherit from AIJ.

9104:    Level: intermediate

9106: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9107: @*/
9108: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9109: {
9111:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9112:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9113:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9114:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

9117:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
9118:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

9122:   MatCheckPreallocated(A,1);
9123:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9124:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9127:   MatCheckPreallocated(P,2);
9128:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9129:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9131:   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);
9132:   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);
9133:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9134:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9136:   if (scall == MAT_REUSE_MATRIX) {
9139:     if (viatranspose || viamatmatmatmult) {
9140:       Mat Pt;
9141:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9142:       if (viamatmatmatmult) {
9143:         MatMatMatMult(Pt,A,P,scall,fill,C);
9144:       } else {
9145:         Mat AP;
9146:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9147:         MatMatMult(Pt,AP,scall,fill,C);
9148:         MatDestroy(&AP);
9149:       }
9150:       MatDestroy(&Pt);
9151:     } else {
9152:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9153:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9154:       (*(*C)->ops->ptapnumeric)(A,P,*C);
9155:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9156:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9157:     }
9158:     return(0);
9159:   }

9161:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9162:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9164:   fA = A->ops->ptap;
9165:   fP = P->ops->ptap;
9166:   if (fP == fA) {
9167:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9168:     ptap = fA;
9169:   } else {
9170:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9171:     char ptapname[256];
9172:     PetscStrcpy(ptapname,"MatPtAP_");
9173:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
9174:     PetscStrcat(ptapname,"_");
9175:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
9176:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9177:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9178:     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);
9179:   }

9181:   if (viatranspose || viamatmatmatmult) {
9182:     Mat Pt;
9183:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9184:     if (viamatmatmatmult) {
9185:       MatMatMatMult(Pt,A,P,scall,fill,C);
9186:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
9187:     } else {
9188:       Mat AP;
9189:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9190:       MatMatMult(Pt,AP,scall,fill,C);
9191:       MatDestroy(&AP);
9192:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
9193:     }
9194:     MatDestroy(&Pt);
9195:   } else {
9196:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9197:     (*ptap)(A,P,scall,fill,C);
9198:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9199:   }
9200:   return(0);
9201: }

9205: /*@
9206:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

9208:    Neighbor-wise Collective on Mat

9210:    Input Parameters:
9211: +  A - the matrix
9212: -  P - the projection matrix

9214:    Output Parameters:
9215: .  C - the product matrix

9217:    Notes:
9218:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9219:    the user using MatDeatroy().

9221:    This routine is currently only implemented for pairs of AIJ matrices and classes
9222:    which inherit from AIJ.  C will be of type MATAIJ.

9224:    Level: intermediate

9226: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9227: @*/
9228: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9229: {

9235:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9236:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9239:   MatCheckPreallocated(P,2);
9240:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9241:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9244:   MatCheckPreallocated(C,3);
9245:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9246:   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);
9247:   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);
9248:   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);
9249:   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);
9250:   MatCheckPreallocated(A,1);

9252:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9253:   (*C->ops->ptapnumeric)(A,P,C);
9254:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9255:   return(0);
9256: }

9260: /*@
9261:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

9263:    Neighbor-wise Collective on Mat

9265:    Input Parameters:
9266: +  A - the matrix
9267: -  P - the projection matrix

9269:    Output Parameters:
9270: .  C - the (i,j) structure of the product matrix

9272:    Notes:
9273:    C will be created and must be destroyed by the user with MatDestroy().

9275:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9276:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9277:    this (i,j) structure by calling MatPtAPNumeric().

9279:    Level: intermediate

9281: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9282: @*/
9283: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9284: {

9290:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9291:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9292:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9295:   MatCheckPreallocated(P,2);
9296:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9297:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9300:   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);
9301:   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);
9302:   MatCheckPreallocated(A,1);
9303:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9304:   (*A->ops->ptapsymbolic)(A,P,fill,C);
9305:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

9307:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
9308:   return(0);
9309: }

9313: /*@
9314:    MatRARt - Creates the matrix product C = R * A * R^T

9316:    Neighbor-wise Collective on Mat

9318:    Input Parameters:
9319: +  A - the matrix
9320: .  R - the projection matrix
9321: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9322: -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9323:           if the result is a dense matrix this is irrelevent

9325:    Output Parameters:
9326: .  C - the product matrix

9328:    Notes:
9329:    C will be created and must be destroyed by the user with MatDestroy().

9331:    This routine is currently only implemented for pairs of AIJ matrices and classes
9332:    which inherit from AIJ.

9334:    Level: intermediate

9336: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9337: @*/
9338: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9339: {

9345:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9346:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9349:   MatCheckPreallocated(R,2);
9350:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9351:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9353:   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);

9355:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9356:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9357:   MatCheckPreallocated(A,1);

9359:   if (!A->ops->rart) {
9360:     MatType mattype;
9361:     MatGetType(A,&mattype);
9362:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
9363:   }
9364:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
9365:   (*A->ops->rart)(A,R,scall,fill,C);
9366:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
9367:   return(0);
9368: }

9372: /*@
9373:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

9375:    Neighbor-wise Collective on Mat

9377:    Input Parameters:
9378: +  A - the matrix
9379: -  R - the projection matrix

9381:    Output Parameters:
9382: .  C - the product matrix

9384:    Notes:
9385:    C must have been created by calling MatRARtSymbolic and must be destroyed by
9386:    the user using MatDestroy().

9388:    This routine is currently only implemented for pairs of AIJ matrices and classes
9389:    which inherit from AIJ.  C will be of type MATAIJ.

9391:    Level: intermediate

9393: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9394: @*/
9395: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9396: {

9402:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9403:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9406:   MatCheckPreallocated(R,2);
9407:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9408:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9411:   MatCheckPreallocated(C,3);
9412:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9413:   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);
9414:   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);
9415:   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);
9416:   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);
9417:   MatCheckPreallocated(A,1);

9419:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
9420:   (*A->ops->rartnumeric)(A,R,C);
9421:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
9422:   return(0);
9423: }

9427: /*@
9428:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

9430:    Neighbor-wise Collective on Mat

9432:    Input Parameters:
9433: +  A - the matrix
9434: -  R - the projection matrix

9436:    Output Parameters:
9437: .  C - the (i,j) structure of the product matrix

9439:    Notes:
9440:    C will be created and must be destroyed by the user with MatDestroy().

9442:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9443:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9444:    this (i,j) structure by calling MatRARtNumeric().

9446:    Level: intermediate

9448: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9449: @*/
9450: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9451: {

9457:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9458:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9459:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9462:   MatCheckPreallocated(R,2);
9463:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9464:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9467:   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);
9468:   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);
9469:   MatCheckPreallocated(A,1);
9470:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9471:   (*A->ops->rartsymbolic)(A,R,fill,C);
9472:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

9474:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9475:   return(0);
9476: }

9480: /*@
9481:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

9483:    Neighbor-wise Collective on Mat

9485:    Input Parameters:
9486: +  A - the left matrix
9487: .  B - the right matrix
9488: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9489: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9490:           if the result is a dense matrix this is irrelevent

9492:    Output Parameters:
9493: .  C - the product matrix

9495:    Notes:
9496:    Unless scall is MAT_REUSE_MATRIX C will be created.

9498:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9500:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9501:    actually needed.

9503:    If you have many matrices with the same non-zero structure to multiply, you
9504:    should either
9505: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9506: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9507:    In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine
9508:    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.

9510:    Level: intermediate

9512: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9513: @*/
9514: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9515: {
9517:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9518:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9519:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9524:   MatCheckPreallocated(A,1);
9525:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9526:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9529:   MatCheckPreallocated(B,2);
9530:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9531:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9533:   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);
9534:   if (scall == MAT_REUSE_MATRIX) {
9537:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9538:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9539:     (*(*C)->ops->matmultnumeric)(A,B,*C);
9540:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9541:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9542:     return(0);
9543:   }
9544:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9545:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9547:   fA = A->ops->matmult;
9548:   fB = B->ops->matmult;
9549:   if (fB == fA) {
9550:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9551:     mult = fB;
9552:   } else {
9553:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9554:     char multname[256];
9555:     PetscStrcpy(multname,"MatMatMult_");
9556:     PetscStrcat(multname,((PetscObject)A)->type_name);
9557:     PetscStrcat(multname,"_");
9558:     PetscStrcat(multname,((PetscObject)B)->type_name);
9559:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9560:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9561:     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);
9562:   }
9563:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9564:   (*mult)(A,B,scall,fill,C);
9565:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9566:   return(0);
9567: }

9571: /*@
9572:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9573:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

9575:    Neighbor-wise Collective on Mat

9577:    Input Parameters:
9578: +  A - the left matrix
9579: .  B - the right matrix
9580: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9581:       if C is a dense matrix this is irrelevent

9583:    Output Parameters:
9584: .  C - the product matrix

9586:    Notes:
9587:    Unless scall is MAT_REUSE_MATRIX C will be created.

9589:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9590:    actually needed.

9592:    This routine is currently implemented for
9593:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9594:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9595:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9597:    Level: intermediate

9599:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9600:      We should incorporate them into PETSc.

9602: .seealso: MatMatMult(), MatMatMultNumeric()
9603: @*/
9604: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9605: {
9607:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9608:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9609:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

9614:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9615:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9619:   MatCheckPreallocated(B,2);
9620:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9621:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9624:   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);
9625:   if (fill == PETSC_DEFAULT) fill = 2.0;
9626:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9627:   MatCheckPreallocated(A,1);

9629:   Asymbolic = A->ops->matmultsymbolic;
9630:   Bsymbolic = B->ops->matmultsymbolic;
9631:   if (Asymbolic == Bsymbolic) {
9632:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9633:     symbolic = Bsymbolic;
9634:   } else { /* dispatch based on the type of A and B */
9635:     char symbolicname[256];
9636:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9637:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9638:     PetscStrcat(symbolicname,"_");
9639:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9640:     PetscStrcat(symbolicname,"_C");
9641:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9642:     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);
9643:   }
9644:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9645:   (*symbolic)(A,B,fill,C);
9646:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9647:   return(0);
9648: }

9652: /*@
9653:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9654:    Call this routine after first calling MatMatMultSymbolic().

9656:    Neighbor-wise Collective on Mat

9658:    Input Parameters:
9659: +  A - the left matrix
9660: -  B - the right matrix

9662:    Output Parameters:
9663: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

9665:    Notes:
9666:    C must have been created with MatMatMultSymbolic().

9668:    This routine is currently implemented for
9669:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9670:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9671:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9673:    Level: intermediate

9675: .seealso: MatMatMult(), MatMatMultSymbolic()
9676: @*/
9677: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9678: {

9682:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9683:   return(0);
9684: }

9688: /*@
9689:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

9691:    Neighbor-wise Collective on Mat

9693:    Input Parameters:
9694: +  A - the left matrix
9695: .  B - the right matrix
9696: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9697: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9699:    Output Parameters:
9700: .  C - the product matrix

9702:    Notes:
9703:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

9705:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9707:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9708:    actually needed.

9710:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

9712:    Level: intermediate

9714: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9715: @*/
9716: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9717: {
9719:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9720:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

9725:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9726:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9729:   MatCheckPreallocated(B,2);
9730:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9731:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9733:   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);
9734:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9735:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9736:   MatCheckPreallocated(A,1);

9738:   fA = A->ops->mattransposemult;
9739:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9740:   fB = B->ops->mattransposemult;
9741:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9742:   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);

9744:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9745:   if (scall == MAT_INITIAL_MATRIX) {
9746:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9747:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9748:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9749:   }
9750:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9751:   (*A->ops->mattransposemultnumeric)(A,B,*C);
9752:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9753:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9754:   return(0);
9755: }

9759: /*@
9760:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

9762:    Neighbor-wise Collective on Mat

9764:    Input Parameters:
9765: +  A - the left matrix
9766: .  B - the right matrix
9767: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9768: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9770:    Output Parameters:
9771: .  C - the product matrix

9773:    Notes:
9774:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

9776:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9778:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9779:    actually needed.

9781:    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9782:    which inherit from SeqAIJ.  C will be of same type as the input matrices.

9784:    Level: intermediate

9786: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9787: @*/
9788: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9789: {
9791:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9792:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9793:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

9798:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9799:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9802:   MatCheckPreallocated(B,2);
9803:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9804:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9806:   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);
9807:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9808:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9809:   MatCheckPreallocated(A,1);

9811:   fA = A->ops->transposematmult;
9812:   fB = B->ops->transposematmult;
9813:   if (fB==fA) {
9814:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9815:     transposematmult = fA;
9816:   } else {
9817:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9818:     char multname[256];
9819:     PetscStrcpy(multname,"MatTransposeMatMult_");
9820:     PetscStrcat(multname,((PetscObject)A)->type_name);
9821:     PetscStrcat(multname,"_");
9822:     PetscStrcat(multname,((PetscObject)B)->type_name);
9823:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9824:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9825:     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);
9826:   }
9827:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9828:   (*transposematmult)(A,B,scall,fill,C);
9829:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9830:   return(0);
9831: }

9835: /*@
9836:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

9838:    Neighbor-wise Collective on Mat

9840:    Input Parameters:
9841: +  A - the left matrix
9842: .  B - the middle matrix
9843: .  C - the right matrix
9844: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9845: -  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
9846:           if the result is a dense matrix this is irrelevent

9848:    Output Parameters:
9849: .  D - the product matrix

9851:    Notes:
9852:    Unless scall is MAT_REUSE_MATRIX D will be created.

9854:    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call

9856:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9857:    actually needed.

9859:    If you have many matrices with the same non-zero structure to multiply, you
9860:    should use MAT_REUSE_MATRIX in all calls but the first or

9862:    Level: intermediate

9864: .seealso: MatMatMult, MatPtAP()
9865: @*/
9866: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,