Actual source code: matrix.c

petsc-master 2017-01-20
Report Typos and Errors

  2: /*
  3:    This is where the abstract matrix operations are defined
  4: */

  6:  #include <petsc/private/matimpl.h>
  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};

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

 45:    Logically Collective on Vec

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

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

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

 62:    Level: intermediate

 64:    Concepts: matrix^setting to random
 65:    Concepts: random^matrix

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


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

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

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

 96: /*@
 97:    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 

 99:    Logically Collective on Mat

101:    Input Parameters:
102: .  mat - the factored matrix

104:    Output Parameter:
105: +  pivot - the pivot value computed
106: -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
107:          the share the matrix 

109:    Level: advanced

111:    Notes: This routine does not work for factorizations done with external packages.
112:    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT

114:    This can be called on non-factored matrices that come from, for example, matrices used in SOR.

116: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
117: @*/
118: PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
119: {
122:   *pivot = mat->factorerror_zeropivot_value;
123:   *row   = mat->factorerror_zeropivot_row;
124:   return(0);
125: }

127: /*@
128:    MatFactorGetError - gets the error code from a factorization

130:    Logically Collective on Mat

132:    Input Parameters:
133: .  mat - the factored matrix

135:    Output Parameter:
136: .  err  - the error code

138:    Level: advanced

140:    Notes:    This can be called on non-factored matrices that come from, for example, matrices used in SOR.

142: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
143: @*/
144: PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
145: {
148:   *err = mat->factorerrortype;
149:   return(0);
150: }

152: /*@
153:    MatFactorClearError - clears the error code in a factorization

155:    Logically Collective on Mat

157:    Input Parameter:
158: .  mat - the factored matrix

160:    Level: developer

162:    Notes: This can be called on non-factored matrices that come from, for example, matrices used in SOR.

164: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
165: @*/
166: PetscErrorCode MatFactorClearError(Mat mat)
167: {
170:   mat->factorerrortype             = MAT_FACTOR_NOERROR;
171:   mat->factorerror_zeropivot_value = 0.0;
172:   mat->factorerror_zeropivot_row   = 0;
173:   return(0);
174: }


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

180:   Input Parameter:
181: .    A  - the matrix

183:   Output Parameter:
184: .    keptrows - the rows that are not completely zero

186:   Notes: keptrows is set to NULL if all rows are nonzero.

188:   Level: intermediate

190:  @*/
191: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
192: {

197:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
198:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
199:   if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
200:   (*mat->ops->findnonzerorows)(mat,keptrows);
201:   return(0);
202: }

204: /*@
205:       MatFindZeroRows - Locate all rows that are completely zero in the matrix

207:   Input Parameter:
208: .    A  - the matrix

210:   Output Parameter:
211: .    zerorows - the rows that are completely zero

213:   Notes: zerorows is set to NULL if no rows are zero.

215:   Level: intermediate

217:  @*/
218: PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
219: {
221:   IS keptrows;
222:   PetscInt m, n;


227:   MatFindNonzeroRows(mat, &keptrows);
228:   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
229:      In keeping with this convention, we set zerorows to NULL if there are no zero
230:      rows. */
231:   if (keptrows == NULL) {
232:     *zerorows = NULL;
233:   } else {
234:     MatGetOwnershipRange(mat,&m,&n);
235:     ISComplement(keptrows,m,n,zerorows);
236:     ISDestroy(&keptrows);
237:   }
238:   return(0);
239: }

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

244:    Not Collective

246:    Input Parameters:
247: .   A - the matrix

249:    Output Parameters:
250: .   a - the diagonal part (which is a SEQUENTIAL matrix)

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

256:    Level: advanced

258: @*/
259: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
260: {

267:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
268:   if (!A->ops->getdiagonalblock) {
269:     PetscMPIInt size;
270:     MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
271:     if (size == 1) {
272:       *a = A;
273:       return(0);
274:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
275:   }
276:   (*A->ops->getdiagonalblock)(A,a);
277:   return(0);
278: }

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

283:    Collective on Mat

285:    Input Parameters:
286: .  mat - the matrix

288:    Output Parameter:
289: .   trace - the sum of the diagonal entries

291:    Level: advanced

293: @*/
294: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
295: {
297:   Vec            diag;

300:   MatCreateVecs(mat,&diag,NULL);
301:   MatGetDiagonal(mat,diag);
302:   VecSum(diag,trace);
303:   VecDestroy(&diag);
304:   return(0);
305: }

307: /*@
308:    MatRealPart - Zeros out the imaginary part of the matrix

310:    Logically Collective on Mat

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

315:    Level: advanced


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

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

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

351:    Collective on Mat

353:    Input Parameter:
354: .  mat - the matrix

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

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

362:    Level: advanced

364: @*/
365: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
366: {

372:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
373:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
374:   if (!mat->ops->getghosts) {
375:     if (nghosts) *nghosts = 0;
376:     if (ghosts) *ghosts = 0;
377:   } else {
378:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
379:   }
380:   return(0);
381: }


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

387:    Logically Collective on Mat

389:    Input Parameters:
390: .  mat - the matrix

392:    Level: advanced


395: .seealso: MatRealPart()
396: @*/
397: PetscErrorCode MatImaginaryPart(Mat mat)
398: {

404:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
405:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
406:   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
407:   MatCheckPreallocated(mat,1);
408:   (*mat->ops->imaginarypart)(mat);
409: #if defined(PETSC_HAVE_CUSP)
410:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
411:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
412:   }
413: #elif defined(PETSC_HAVE_VIENNACL)
414:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
415:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
416:   }
417: #elif defined(PETSC_HAVE_VECCUDA)
418:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
419:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
420:   }
421: #endif
422:   return(0);
423: }

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

428:    Not Collective

430:    Input Parameter:
431: .  mat - the matrix

433:    Output Parameters:
434: +  missing - is any diagonal missing
435: -  dd - first diagonal entry that is missing (optional) on this process

437:    Level: advanced


440: .seealso: MatRealPart()
441: @*/
442: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
443: {

449:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
450:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
451:   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
452:   (*mat->ops->missingdiagonal)(mat,missing,dd);
453:   return(0);
454: }

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

461:    Not Collective

463:    Input Parameters:
464: +  mat - the matrix
465: -  row - the row to get

467:    Output Parameters:
468: +  ncols -  if not NULL, the number of nonzeros in the row
469: .  cols - if not NULL, the column numbers
470: -  vals - if not NULL, the values

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

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

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

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

487:    You can only have one call to MatGetRow() outstanding for a particular
488:    matrix at a time, per processor. MatGetRow() can only obtain rows
489:    associated with the given processor, it cannot get rows from the
490:    other processors; for that we suggest using MatGetSubMatrices(), then
491:    MatGetRow() on the submatrix. The row index passed to MatGetRows()
492:    is in the global number of rows.

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


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

511:    Level: advanced

513:    Concepts: matrices^row access

515: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
516: @*/
517: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
518: {
520:   PetscInt       incols;

525:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
526:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
527:   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
528:   MatCheckPreallocated(mat,1);
529:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
530:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
531:   if (ncols) *ncols = incols;
532:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
533:   return(0);
534: }

536: /*@
537:    MatConjugate - replaces the matrix values with their complex conjugates

539:    Logically Collective on Mat

541:    Input Parameters:
542: .  mat - the matrix

544:    Level: advanced

546: .seealso:  VecConjugate()
547: @*/
548: PetscErrorCode MatConjugate(Mat mat)
549: {
550: #if defined(PETSC_USE_COMPLEX)

555:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
556:   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");
557:   (*mat->ops->conjugate)(mat);
558: #if defined(PETSC_HAVE_CUSP)
559:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
560:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
561:   }
562: #elif defined(PETSC_HAVE_VIENNACL)
563:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
564:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
565:   }
566: #elif defined(PETSC_HAVE_VECCUDA)
567:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
568:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
569:   }
570: #endif
571:   return(0);
572: #else
573:   return 0;
574: #endif
575: }

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

580:    Not Collective

582:    Input Parameters:
583: +  mat - the matrix
584: .  row - the row to get
585: .  ncols, cols - the number of nonzeros and their columns
586: -  vals - if nonzero the column values

588:    Notes:
589:    This routine should be called after you have finished examining the entries.

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

595:    Fortran Notes:
596:    The calling sequence from Fortran is
597: .vb
598:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
599:       Mat     matrix (input)
600:       integer row    (input)
601:       integer ncols  (output)
602:       integer cols(maxcols) (output)
603:       double precision (or double complex) values(maxcols) output
604: .ve
605:    Where maxcols >= maximum nonzeros in any row of the matrix.

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

610:    Level: advanced

612: .seealso:  MatGetRow()
613: @*/
614: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
615: {

621:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
622:   if (!mat->ops->restorerow) return(0);
623:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
624:   if (ncols) *ncols = 0;
625:   if (cols)  *cols = NULL;
626:   if (vals)  *vals = NULL;
627:   return(0);
628: }

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

634:    Not Collective

636:    Input Parameters:
637: +  mat - the matrix

639:    Notes:
640:    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.

642:    Level: advanced

644:    Concepts: matrices^row access

646: .seealso: MatRestoreRowRowUpperTriangular()
647: @*/
648: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
649: {

655:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
656:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
657:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
658:   MatCheckPreallocated(mat,1);
659:   (*mat->ops->getrowuppertriangular)(mat);
660:   return(0);
661: }

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

666:    Not Collective

668:    Input Parameters:
669: +  mat - the matrix

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


675:    Level: advanced

677: .seealso:  MatGetRowUpperTriangular()
678: @*/
679: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
680: {

685:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
686:   if (!mat->ops->restorerowuppertriangular) return(0);
687:   (*mat->ops->restorerowuppertriangular)(mat);
688:   return(0);
689: }

691: /*@C
692:    MatSetOptionsPrefix - Sets the prefix used for searching for all
693:    Mat options in the database.

695:    Logically Collective on Mat

697:    Input Parameter:
698: +  A - the Mat context
699: -  prefix - the prefix to prepend to all option names

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

705:    Level: advanced

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

709: .seealso: MatSetFromOptions()
710: @*/
711: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
712: {

717:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
718:   return(0);
719: }

721: /*@C
722:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
723:    Mat options in the database.

725:    Logically Collective on Mat

727:    Input Parameters:
728: +  A - the Mat context
729: -  prefix - the prefix to prepend to all option names

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

735:    Level: advanced

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

739: .seealso: MatGetOptionsPrefix()
740: @*/
741: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
742: {

747:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
748:   return(0);
749: }

751: /*@C
752:    MatGetOptionsPrefix - Sets the prefix used for searching for all
753:    Mat options in the database.

755:    Not Collective

757:    Input Parameter:
758: .  A - the Mat context

760:    Output Parameter:
761: .  prefix - pointer to the prefix string used

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

766:    Level: advanced

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

770: .seealso: MatAppendOptionsPrefix()
771: @*/
772: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
773: {

778:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
779:   return(0);
780: }

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

785:    Collective on Mat

787:    Input Parameters:
788: .  A - the Mat context

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

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

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

797:    Level: beginner

799: .keywords: Mat, setup

801: .seealso: MatCreate(), MatDestroy()
802: @*/
803: PetscErrorCode MatSetUp(Mat A)
804: {
805:   PetscMPIInt    size;

810:   if (!((PetscObject)A)->type_name) {
811:     MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
812:     if (size == 1) {
813:       MatSetType(A, MATSEQAIJ);
814:     } else {
815:       MatSetType(A, MATMPIAIJ);
816:     }
817:   }
818:   if (!A->preallocated && A->ops->setup) {
819:     PetscInfo(A,"Warning not preallocating matrix storage\n");
820:     (*A->ops->setup)(A);
821:   }
822:   if (A->rmap->n < 0 || A->rmap->N < 0) {
823:     PetscLayoutSetUp(A->rmap);
824:   }
825:   if (A->cmap->n < 0 || A->cmap->N < 0) {
826:     PetscLayoutSetUp(A->cmap);
827:   }
828:   A->preallocated = PETSC_TRUE;
829:   return(0);
830: }

832: #if defined(PETSC_HAVE_SAWS)
833:  #include <petscviewersaws.h>
834: #endif
835: /*@C
836:    MatView - Visualizes a matrix object.

838:    Collective on Mat

840:    Input Parameters:
841: +  mat - the matrix
842: -  viewer - visualization context

844:   Notes:
845:   The available visualization contexts include
846: +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
847: .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
848: .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
849: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

851:    The user can open alternative visualization contexts with
852: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
853: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
854:          specified file; corresponding input uses MatLoad()
855: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
856:          an X window display
857: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
858:          Currently only the sequential dense and AIJ
859:          matrix types support the Socket viewer.

861:    The user can call PetscViewerPushFormat() to specify the output
862:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
863:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
864: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
865: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
866: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
867: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
868:          format common among all matrix types
869: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
870:          format (which is in many cases the same as the default)
871: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
872:          size and structure (not the matrix entries)
873: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
874:          the matrix structure

876:    Options Database Keys:
877: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
878: .  -mat_view ::ascii_info_detail - Prints more detailed info
879: .  -mat_view - Prints matrix in ASCII format
880: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
881: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
882: .  -display <name> - Sets display name (default is host)
883: .  -draw_pause <sec> - Sets number of seconds to pause after display
884: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 12 Using MATLAB with PETSc for details)
885: .  -viewer_socket_machine <machine> -
886: .  -viewer_socket_port <port> -
887: .  -mat_view binary - save matrix to file in binary format
888: -  -viewer_binary_filename <name> -
889:    Level: beginner

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

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

897:       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
898:       And then use the following mouse functions:
899:           left mouse: zoom in
900:           middle mouse: zoom out
901:           right mouse: continue with the simulation

903:    Concepts: matrices^viewing
904:    Concepts: matrices^plotting
905:    Concepts: matrices^printing

907: .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
908:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
909: @*/
910: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
911: {
912:   PetscErrorCode    ierr;
913:   PetscInt          rows,cols,rbs,cbs;
914:   PetscBool         iascii,ibinary;
915:   PetscViewerFormat format;
916: #if defined(PETSC_HAVE_SAWS)
917:   PetscBool         issaws;
918: #endif

923:   if (!viewer) {
924:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
925:   }
928:   MatCheckPreallocated(mat,1);
929:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
930:   if (ibinary) {
931:     PetscBool mpiio;
932:     PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
933:     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
934:   }

936:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
937:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
938:   PetscViewerGetFormat(viewer,&format);
939:   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
940:     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
941:   }

943: #if defined(PETSC_HAVE_SAWS)
944:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
945: #endif
946:   if (iascii) {
947:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
948:     PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
949:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
950:       PetscViewerASCIIPushTab(viewer);
951:       MatGetSize(mat,&rows,&cols);
952:       MatGetBlockSizes(mat,&rbs,&cbs);
953:       if (rbs != 1 || cbs != 1) {
954:         if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
955:         else            {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
956:       } else {
957:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
958:       }
959:       if (mat->factortype) {
960:         const MatSolverPackage solver;
961:         MatFactorGetSolverPackage(mat,&solver);
962:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
963:       }
964:       if (mat->ops->getinfo) {
965:         MatInfo info;
966:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
967:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
968:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
969:       }
970:       if (mat->nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached null space\n");}
971:       if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");}
972:     }
973: #if defined(PETSC_HAVE_SAWS)
974:   } else if (issaws) {
975:     PetscMPIInt rank;

977:     PetscObjectName((PetscObject)mat);
978:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
979:     if (!((PetscObject)mat)->amsmem && !rank) {
980:       PetscObjectViewSAWs((PetscObject)mat,viewer);
981:     }
982: #endif
983:   }
984:   if (mat->ops->view) {
985:     PetscViewerASCIIPushTab(viewer);
986:     (*mat->ops->view)(mat,viewer);
987:     PetscViewerASCIIPopTab(viewer);
988:   }
989:   if (iascii) {
990:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
991:     PetscViewerGetFormat(viewer,&format);
992:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
993:       PetscViewerASCIIPopTab(viewer);
994:     }
995:   }
996:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
997:   return(0);
998: }

1000: #if defined(PETSC_USE_DEBUG)
1001: #include <../src/sys/totalview/tv_data_display.h>
1002: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1003: {
1004:   TV_add_row("Local rows", "int", &mat->rmap->n);
1005:   TV_add_row("Local columns", "int", &mat->cmap->n);
1006:   TV_add_row("Global rows", "int", &mat->rmap->N);
1007:   TV_add_row("Global columns", "int", &mat->cmap->N);
1008:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1009:   return TV_format_OK;
1010: }
1011: #endif

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

1019:    Collective on PetscViewer

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

1026:    Options Database Keys:
1027:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1028:    block size
1029: .    -matload_block_size <bs>

1031:    Level: beginner

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

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

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

1046:    In parallel, each processor can load a subset of rows (or the
1047:    entire matrix).  This routine is especially useful when a large
1048:    matrix is stored on disk and only part of it is desired on each
1049:    processor.  For example, a parallel solver may access only some of
1050:    the rows from each processor.  The algorithm used here reads
1051:    relatively small blocks of data rather than reading the entire
1052:    matrix and then subsetting it.

1054:    Notes for advanced users:
1055:    Most users should not need to know the details of the binary storage
1056:    format, since MatLoad() and MatView() completely hide these details.
1057:    But for anyone who's interested, the standard binary matrix storage
1058:    format is

1060: $    int    MAT_FILE_CLASSID
1061: $    int    number of rows
1062: $    int    number of columns
1063: $    int    total number of nonzeros
1064: $    int    *number nonzeros in each row
1065: $    int    *column indices of all nonzeros (starting index is zero)
1066: $    PetscScalar *values of all nonzeros

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

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

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

1078:  @*/
1079: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1080: {
1082:   PetscBool      isbinary,flg;

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

1090:   if (!((PetscObject)newmat)->type_name) {
1091:     MatSetType(newmat,MATAIJ);
1092:   }

1094:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1095:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1096:   (*newmat->ops->load)(newmat,viewer);
1097:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

1099:   flg  = PETSC_FALSE;
1100:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1101:   if (flg) {
1102:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1103:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1104:   }
1105:   flg  = PETSC_FALSE;
1106:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1107:   if (flg) {
1108:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1109:   }
1110:   return(0);
1111: }

1113: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1114: {
1116:   Mat_Redundant  *redund = *redundant;
1117:   PetscInt       i;

1120:   if (redund){
1121:     if (redund->matseq) { /* via MatGetSubMatrices()  */
1122:       ISDestroy(&redund->isrow);
1123:       ISDestroy(&redund->iscol);
1124:       MatDestroy(&redund->matseq[0]);
1125:       PetscFree(redund->matseq);
1126:     } else {
1127:       PetscFree2(redund->send_rank,redund->recv_rank);
1128:       PetscFree(redund->sbuf_j);
1129:       PetscFree(redund->sbuf_a);
1130:       for (i=0; i<redund->nrecvs; i++) {
1131:         PetscFree(redund->rbuf_j[i]);
1132:         PetscFree(redund->rbuf_a[i]);
1133:       }
1134:       PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1135:     }

1137:     if (redund->subcomm) {
1138:       PetscCommDestroy(&redund->subcomm);
1139:     }
1140:     PetscFree(redund);
1141:   }
1142:   return(0);
1143: }

1145: /*@
1146:    MatDestroy - Frees space taken by a matrix.

1148:    Collective on Mat

1150:    Input Parameter:
1151: .  A - the matrix

1153:    Level: beginner

1155: @*/
1156: PetscErrorCode MatDestroy(Mat *A)
1157: {

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

1165:   /* if memory was published with SAWs then destroy it */
1166:   PetscObjectSAWsViewOff((PetscObject)*A);
1167:   if ((*A)->ops->destroy) {
1168:     (*(*A)->ops->destroy)(*A);
1169:   }

1171:   PetscFree((*A)->solvertype);
1172:   MatDestroy_Redundant(&(*A)->redundant);
1173:   MatNullSpaceDestroy(&(*A)->nullsp);
1174:   MatNullSpaceDestroy(&(*A)->transnullsp);
1175:   MatNullSpaceDestroy(&(*A)->nearnullsp);
1176:   PetscLayoutDestroy(&(*A)->rmap);
1177:   PetscLayoutDestroy(&(*A)->cmap);
1178:   PetscHeaderDestroy(A);
1179:   return(0);
1180: }

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

1187:    Not Collective

1189:    Input Parameters:
1190: +  mat - the matrix
1191: .  v - a logically two-dimensional array of values
1192: .  m, idxm - the number of rows and their global indices
1193: .  n, idxn - the number of columns and their global indices
1194: -  addv - either ADD_VALUES or INSERT_VALUES, where
1195:    ADD_VALUES adds values to any existing entries, and
1196:    INSERT_VALUES replaces existing entries with new values

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

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

1204:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1205:    options cannot be mixed without intervening calls to the assembly
1206:    routines.

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

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

1216:    Efficiency Alert:
1217:    The routine MatSetValuesBlocked() may offer much better efficiency
1218:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1220:    Level: beginner

1222:    Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
1223:                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.

1225:    Concepts: matrices^putting entries in

1227: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1228:           InsertMode, INSERT_VALUES, ADD_VALUES
1229: @*/
1230: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1231: {
1233: #if defined(PETSC_USE_DEBUG)
1234:   PetscInt       i,j;
1235: #endif

1240:   if (!m || !n) return(0); /* no values to insert */
1244:   MatCheckPreallocated(mat,1);
1245:   if (mat->insertmode == NOT_SET_VALUES) {
1246:     mat->insertmode = addv;
1247:   }
1248: #if defined(PETSC_USE_DEBUG)
1249:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1250:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1251:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);

1253:   for (i=0; i<m; i++) {
1254:     for (j=0; j<n; j++) {
1255:       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1256: #if defined(PETSC_USE_COMPLEX)
1257:         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]);
1258: #else
1259:         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1260: #endif
1261:     }
1262:   }
1263: #endif

1265:   if (mat->assembled) {
1266:     mat->was_assembled = PETSC_TRUE;
1267:     mat->assembled     = PETSC_FALSE;
1268:   }
1269:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1270:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1271:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1272: #if defined(PETSC_HAVE_CUSP)
1273:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1274:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1275:   }
1276: #elif defined(PETSC_HAVE_VIENNACL)
1277:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1278:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1279:   }
1280: #elif defined(PETSC_HAVE_VECCUDA)
1281:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1282:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1283:   }
1284: #endif
1285:   return(0);
1286: }


1289: /*@
1290:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1291:         values into a matrix

1293:    Not Collective

1295:    Input Parameters:
1296: +  mat - the matrix
1297: .  row - the (block) row to set
1298: -  v - a logically two-dimensional array of values

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

1303:    All the nonzeros in the row must be provided

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

1307:    The row must belong to this process

1309:    Level: intermediate

1311:    Concepts: matrices^putting entries in

1313: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1314:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1315: @*/
1316: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1317: {
1319:   PetscInt       globalrow;

1325:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1326:   MatSetValuesRow(mat,globalrow,v);
1327: #if defined(PETSC_HAVE_CUSP)
1328:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1329:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1330:   }
1331: #elif defined(PETSC_HAVE_VIENNACL)
1332:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1333:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1334:   }
1335: #elif defined(PETSC_HAVE_VECCUDA)
1336:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1337:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1338:   }
1339: #endif
1340:   return(0);
1341: }

1343: /*@
1344:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1345:         values into a matrix

1347:    Not Collective

1349:    Input Parameters:
1350: +  mat - the matrix
1351: .  row - the (block) row to set
1352: -  v - a logically two-dimensional (column major) array of values for  block matrices with blocksize larger than one, otherwise a one dimensional array of values

1354:    Notes:
1355:    The values, v, are column-oriented for the block version.

1357:    All the nonzeros in the row must be provided

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

1361:    The row must belong to this process

1363:    Level: advanced

1365:    Concepts: matrices^putting entries in

1367: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1368:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1369: @*/
1370: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1371: {

1377:   MatCheckPreallocated(mat,1);
1379: #if defined(PETSC_USE_DEBUG)
1380:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1381:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1382: #endif
1383:   mat->insertmode = INSERT_VALUES;

1385:   if (mat->assembled) {
1386:     mat->was_assembled = PETSC_TRUE;
1387:     mat->assembled     = PETSC_FALSE;
1388:   }
1389:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1390:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1391:   (*mat->ops->setvaluesrow)(mat,row,v);
1392:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1393: #if defined(PETSC_HAVE_CUSP)
1394:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1395:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1396:   }
1397: #elif defined(PETSC_HAVE_VIENNACL)
1398:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1399:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1400:   }
1401: #elif defined(PETSC_HAVE_VECCUDA)
1402:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1403:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1404:   }
1405: #endif
1406:   return(0);
1407: }

1409: /*@
1410:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1411:      Using structured grid indexing

1413:    Not Collective

1415:    Input Parameters:
1416: +  mat - the matrix
1417: .  m - number of rows being entered
1418: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1419: .  n - number of columns being entered
1420: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1421: .  v - a logically two-dimensional array of values
1422: -  addv - either ADD_VALUES or INSERT_VALUES, where
1423:    ADD_VALUES adds values to any existing entries, and
1424:    INSERT_VALUES replaces existing entries with new values

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

1429:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1430:    options cannot be mixed without intervening calls to the assembly
1431:    routines.

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

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

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

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

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

1449:    In Fortran idxm and idxn should be declared as
1450: $     MatStencil idxm(4,m),idxn(4,n)
1451:    and the values inserted using
1452: $    idxm(MatStencil_i,1) = i
1453: $    idxm(MatStencil_j,1) = j
1454: $    idxm(MatStencil_k,1) = k
1455: $    idxm(MatStencil_c,1) = c
1456:    etc

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

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

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

1469:    Efficiency Alert:
1470:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1471:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1473:    Level: beginner

1475:    Concepts: matrices^putting entries in

1477: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1478:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1479: @*/
1480: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1481: {
1483:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1484:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1485:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1495:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1496:     jdxm = buf; jdxn = buf+m;
1497:   } else {
1498:     PetscMalloc2(m,&bufm,n,&bufn);
1499:     jdxm = bufm; jdxn = bufn;
1500:   }
1501:   for (i=0; i<m; i++) {
1502:     for (j=0; j<3-sdim; j++) dxm++;
1503:     tmp = *dxm++ - starts[0];
1504:     for (j=0; j<dim-1; j++) {
1505:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1506:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1507:     }
1508:     if (mat->stencil.noc) dxm++;
1509:     jdxm[i] = tmp;
1510:   }
1511:   for (i=0; i<n; i++) {
1512:     for (j=0; j<3-sdim; j++) dxn++;
1513:     tmp = *dxn++ - starts[0];
1514:     for (j=0; j<dim-1; j++) {
1515:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1516:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1517:     }
1518:     if (mat->stencil.noc) dxn++;
1519:     jdxn[i] = tmp;
1520:   }
1521:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1522:   PetscFree2(bufm,bufn);
1523:   return(0);
1524: }

1526: /*@
1527:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1528:      Using structured grid indexing

1530:    Not Collective

1532:    Input Parameters:
1533: +  mat - the matrix
1534: .  m - number of rows being entered
1535: .  idxm - grid coordinates for matrix rows being entered
1536: .  n - number of columns being entered
1537: .  idxn - grid coordinates for matrix columns being entered
1538: .  v - a logically two-dimensional array of values
1539: -  addv - either ADD_VALUES or INSERT_VALUES, where
1540:    ADD_VALUES adds values to any existing entries, and
1541:    INSERT_VALUES replaces existing entries with new values

1543:    Notes:
1544:    By default the values, v, are row-oriented and unsorted.
1545:    See MatSetOption() for other options.

1547:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1548:    options cannot be mixed without intervening calls to the assembly
1549:    routines.

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

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

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

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

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

1567:    In Fortran idxm and idxn should be declared as
1568: $     MatStencil idxm(4,m),idxn(4,n)
1569:    and the values inserted using
1570: $    idxm(MatStencil_i,1) = i
1571: $    idxm(MatStencil_j,1) = j
1572: $    idxm(MatStencil_k,1) = k
1573:    etc

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

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

1583:    Level: beginner

1585:    Concepts: matrices^putting entries in

1587: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1588:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1589:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1590: @*/
1591: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1592: {
1594:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1595:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1596:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1606:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1607:     jdxm = buf; jdxn = buf+m;
1608:   } else {
1609:     PetscMalloc2(m,&bufm,n,&bufn);
1610:     jdxm = bufm; jdxn = bufn;
1611:   }
1612:   for (i=0; i<m; i++) {
1613:     for (j=0; j<3-sdim; j++) dxm++;
1614:     tmp = *dxm++ - starts[0];
1615:     for (j=0; j<sdim-1; j++) {
1616:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1617:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1618:     }
1619:     dxm++;
1620:     jdxm[i] = tmp;
1621:   }
1622:   for (i=0; i<n; i++) {
1623:     for (j=0; j<3-sdim; j++) dxn++;
1624:     tmp = *dxn++ - starts[0];
1625:     for (j=0; j<sdim-1; j++) {
1626:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1627:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1628:     }
1629:     dxn++;
1630:     jdxn[i] = tmp;
1631:   }
1632:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1633:   PetscFree2(bufm,bufn);
1634: #if defined(PETSC_HAVE_CUSP)
1635:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1636:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1637:   }
1638: #elif defined(PETSC_HAVE_VIENNACL)
1639:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1640:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1641:   }
1642: #elif defined(PETSC_HAVE_VECCUDA)
1643:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1644:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1645:   }
1646: #endif
1647:   return(0);
1648: }

1650: /*@
1651:    MatSetStencil - Sets the grid information for setting values into a matrix via
1652:         MatSetValuesStencil()

1654:    Not Collective

1656:    Input Parameters:
1657: +  mat - the matrix
1658: .  dim - dimension of the grid 1, 2, or 3
1659: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1660: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1661: -  dof - number of degrees of freedom per node


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

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

1670:    Level: beginner

1672:    Concepts: matrices^putting entries in

1674: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1675:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1676: @*/
1677: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1678: {
1679:   PetscInt i;


1686:   mat->stencil.dim = dim + (dof > 1);
1687:   for (i=0; i<dim; i++) {
1688:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1689:     mat->stencil.starts[i] = starts[dim-i-1];
1690:   }
1691:   mat->stencil.dims[dim]   = dof;
1692:   mat->stencil.starts[dim] = 0;
1693:   mat->stencil.noc         = (PetscBool)(dof == 1);
1694:   return(0);
1695: }

1697: /*@C
1698:    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.

1700:    Not Collective

1702:    Input Parameters:
1703: +  mat - the matrix
1704: .  v - a logically two-dimensional array of values
1705: .  m, idxm - the number of block rows and their global block indices
1706: .  n, idxn - the number of block columns and their global block indices
1707: -  addv - either ADD_VALUES or INSERT_VALUES, where
1708:    ADD_VALUES adds values to any existing entries, and
1709:    INSERT_VALUES replaces existing entries with new values

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

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

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

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

1727:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1728:    options cannot be mixed without intervening calls to the assembly
1729:    routines.

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

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

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

1745:    Example:
1746: $   Suppose m=n=2 and block size(bs) = 2 The array is
1747: $
1748: $   1  2  | 3  4
1749: $   5  6  | 7  8
1750: $   - - - | - - -
1751: $   9  10 | 11 12
1752: $   13 14 | 15 16
1753: $
1754: $   v[] should be passed in like
1755: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1756: $
1757: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1758: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

1760:    Level: intermediate

1762:    Concepts: matrices^putting entries in blocked

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

1773:   if (!m || !n) return(0); /* no values to insert */
1777:   MatCheckPreallocated(mat,1);
1778:   if (mat->insertmode == NOT_SET_VALUES) {
1779:     mat->insertmode = addv;
1780:   }
1781: #if defined(PETSC_USE_DEBUG)
1782:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1783:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1784:   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1785: #endif

1787:   if (mat->assembled) {
1788:     mat->was_assembled = PETSC_TRUE;
1789:     mat->assembled     = PETSC_FALSE;
1790:   }
1791:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1792:   if (mat->ops->setvaluesblocked) {
1793:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1794:   } else {
1795:     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1796:     PetscInt i,j,bs,cbs;
1797:     MatGetBlockSizes(mat,&bs,&cbs);
1798:     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1799:       iidxm = buf; iidxn = buf + m*bs;
1800:     } else {
1801:       PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1802:       iidxm = bufr; iidxn = bufc;
1803:     }
1804:     for (i=0; i<m; i++) {
1805:       for (j=0; j<bs; j++) {
1806:         iidxm[i*bs+j] = bs*idxm[i] + j;
1807:       }
1808:     }
1809:     for (i=0; i<n; i++) {
1810:       for (j=0; j<cbs; j++) {
1811:         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1812:       }
1813:     }
1814:     MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1815:     PetscFree2(bufr,bufc);
1816:   }
1817:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1818: #if defined(PETSC_HAVE_CUSP)
1819:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1820:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1821:   }
1822: #elif defined(PETSC_HAVE_VIENNACL)
1823:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1824:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1825:   }
1826: #elif defined(PETSC_HAVE_VECCUDA)
1827:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1828:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1829:   }
1830: #endif
1831:   return(0);
1832: }

1834: /*@
1835:    MatGetValues - Gets a block of values from a matrix.

1837:    Not Collective; currently only returns a local block

1839:    Input Parameters:
1840: +  mat - the matrix
1841: .  v - a logically two-dimensional array for storing the values
1842: .  m, idxm - the number of rows and their global indices
1843: -  n, idxn - the number of columns and their global indices

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

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

1853:    MatGetValues() requires that the matrix has been assembled
1854:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1855:    MatSetValues() and MatGetValues() CANNOT be made in succession
1856:    without intermediate matrix assembly.

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

1861:    Level: advanced

1863:    Concepts: matrices^accessing values

1865: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1866: @*/
1867: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1868: {

1874:   if (!m || !n) return(0);
1878:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1879:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1880:   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1881:   MatCheckPreallocated(mat,1);

1883:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1884:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1885:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1886:   return(0);
1887: }

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

1893:   Not Collective

1895:   Input Parameters:
1896: + mat - the matrix
1897: . nb - the number of blocks
1898: . bs - the number of rows (and columns) in each block
1899: . rows - a concatenation of the rows for each block
1900: - v - a concatenation of logically two-dimensional arrays of values

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

1905:   Level: advanced

1907:   Concepts: matrices^putting entries in

1909: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1910:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1911: @*/
1912: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1913: {

1921: #if defined(PETSC_USE_DEBUG)
1922:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1923: #endif

1925:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1926:   if (mat->ops->setvaluesbatch) {
1927:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1928:   } else {
1929:     PetscInt b;
1930:     for (b = 0; b < nb; ++b) {
1931:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1932:     }
1933:   }
1934:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1935:   return(0);
1936: }

1938: /*@
1939:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1940:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1941:    using a local (per-processor) numbering.

1943:    Not Collective

1945:    Input Parameters:
1946: +  x - the matrix
1947: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1948: - cmapping - column mapping

1950:    Level: intermediate

1952:    Concepts: matrices^local to global mapping
1953:    Concepts: local to global mapping^for matrices

1955: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1956: @*/
1957: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1958: {


1967:   if (x->ops->setlocaltoglobalmapping) {
1968:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1969:   } else {
1970:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1971:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1972:   }
1973:   return(0);
1974: }


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

1980:    Not Collective

1982:    Input Parameters:
1983: .  A - the matrix

1985:    Output Parameters:
1986: + rmapping - row mapping
1987: - cmapping - column mapping

1989:    Level: advanced

1991:    Concepts: matrices^local to global mapping
1992:    Concepts: local to global mapping^for matrices

1994: .seealso:  MatSetValuesLocal()
1995: @*/
1996: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1997: {
2003:   if (rmapping) *rmapping = A->rmap->mapping;
2004:   if (cmapping) *cmapping = A->cmap->mapping;
2005:   return(0);
2006: }

2008: /*@
2009:    MatGetLayouts - Gets the PetscLayout objects for rows and columns

2011:    Not Collective

2013:    Input Parameters:
2014: .  A - the matrix

2016:    Output Parameters:
2017: + rmap - row layout
2018: - cmap - column layout

2020:    Level: advanced

2022: .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2023: @*/
2024: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2025: {
2031:   if (rmap) *rmap = A->rmap;
2032:   if (cmap) *cmap = A->cmap;
2033:   return(0);
2034: }

2036: /*@C
2037:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2038:    using a local ordering of the nodes.

2040:    Not Collective

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

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

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

2057:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2058:    options cannot be mixed without intervening calls to the assembly
2059:    routines.

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

2064:    Level: intermediate

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

2068:    Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
2069:                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.

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

2081:   MatCheckPreallocated(mat,1);
2082:   if (!nrow || !ncol) return(0); /* no values to insert */
2086:   if (mat->insertmode == NOT_SET_VALUES) {
2087:     mat->insertmode = addv;
2088:   }
2089: #if defined(PETSC_USE_DEBUG)
2090:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2091:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2092:   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2093: #endif

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

2132: /*@C
2133:    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2134:    using a local ordering of the nodes a block at a time.

2136:    Not Collective

2138:    Input Parameters:
2139: +  x - the matrix
2140: .  nrow, irow - number of rows and their local indices
2141: .  ncol, icol - number of columns and their local indices
2142: .  y -  a logically two-dimensional array of values
2143: -  addv - either INSERT_VALUES or ADD_VALUES, where
2144:    ADD_VALUES adds values to any existing entries, and
2145:    INSERT_VALUES replaces existing entries with new values

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

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

2154:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2155:    options cannot be mixed without intervening calls to the assembly
2156:    routines.

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

2161:    Level: intermediate

2163:    Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
2164:                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.

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

2168: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2169:            MatSetValuesLocal(),  MatSetValuesBlocked()
2170: @*/
2171: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2172: {

2178:   MatCheckPreallocated(mat,1);
2179:   if (!nrow || !ncol) return(0); /* no values to insert */
2183:   if (mat->insertmode == NOT_SET_VALUES) {
2184:     mat->insertmode = addv;
2185:   }
2186: #if defined(PETSC_USE_DEBUG)
2187:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2188:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2189:   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);
2190: #endif

2192:   if (mat->assembled) {
2193:     mat->was_assembled = PETSC_TRUE;
2194:     mat->assembled     = PETSC_FALSE;
2195:   }
2196:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2197:   if (mat->ops->setvaluesblockedlocal) {
2198:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2199:   } else {
2200:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2201:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2202:       irowm = buf; icolm = buf + nrow;
2203:     } else {
2204:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2205:       irowm = bufr; icolm = bufc;
2206:     }
2207:     ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2208:     ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2209:     MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2210:     PetscFree2(bufr,bufc);
2211:   }
2212:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2213: #if defined(PETSC_HAVE_CUSP)
2214:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2215:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2216:   }
2217: #elif defined(PETSC_HAVE_VIENNACL)
2218:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2219:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2220:   }
2221: #elif defined(PETSC_HAVE_VECCUDA)
2222:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2223:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2224:   }
2225: #endif
2226:   return(0);
2227: }

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

2232:    Collective on Mat and Vec

2234:    Input Parameters:
2235: +  mat - the matrix
2236: -  x   - the vector to be multiplied

2238:    Output Parameters:
2239: .  y - the result

2241:    Notes:
2242:    The vectors x and y cannot be the same.  I.e., one cannot
2243:    call MatMult(A,y,y).

2245:    Level: developer

2247:    Concepts: matrix-vector product

2249: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2250: @*/
2251: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2252: {


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

2266:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2267:   (*mat->ops->multdiagonalblock)(mat,x,y);
2268:   PetscObjectStateIncrease((PetscObject)y);
2269:   return(0);
2270: }

2272: /* --------------------------------------------------------*/
2273: /*@
2274:    MatMult - Computes the matrix-vector product, y = Ax.

2276:    Neighbor-wise Collective on Mat and Vec

2278:    Input Parameters:
2279: +  mat - the matrix
2280: -  x   - the vector to be multiplied

2282:    Output Parameters:
2283: .  y - the result

2285:    Notes:
2286:    The vectors x and y cannot be the same.  I.e., one cannot
2287:    call MatMult(A,y,y).

2289:    Level: beginner

2291:    Concepts: matrix-vector product

2293: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2294: @*/
2295: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2296: {

2304:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2305:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2306:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2307: #if !defined(PETSC_HAVE_CONSTRAINTS)
2308:   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);
2309:   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);
2310:   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);
2311: #endif
2312:   VecLocked(y,3);
2313:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2314:   MatCheckPreallocated(mat,1);

2316:   VecLockPush(x);
2317:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2318:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2319:   (*mat->ops->mult)(mat,x,y);
2320:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2321:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2322:   VecLockPop(x);
2323:   return(0);
2324: }

2326: /*@
2327:    MatMultTranspose - Computes matrix transpose times a vector.

2329:    Neighbor-wise Collective on Mat and Vec

2331:    Input Parameters:
2332: +  mat - the matrix
2333: -  x   - the vector to be multilplied

2335:    Output Parameters:
2336: .  y - the result

2338:    Notes:
2339:    The vectors x and y cannot be the same.  I.e., one cannot
2340:    call MatMultTranspose(A,y,y).

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

2345:    Level: beginner

2347:    Concepts: matrix vector product^transpose

2349: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2350: @*/
2351: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2352: {


2361:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2362:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2363:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2364: #if !defined(PETSC_HAVE_CONSTRAINTS)
2365:   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);
2366:   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);
2367: #endif
2368:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2369:   MatCheckPreallocated(mat,1);

2371:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2372:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2373:   VecLockPush(x);
2374:   (*mat->ops->multtranspose)(mat,x,y);
2375:   VecLockPop(x);
2376:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2377:   PetscObjectStateIncrease((PetscObject)y);
2378:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2379:   return(0);
2380: }

2382: /*@
2383:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2385:    Neighbor-wise Collective on Mat and Vec

2387:    Input Parameters:
2388: +  mat - the matrix
2389: -  x   - the vector to be multilplied

2391:    Output Parameters:
2392: .  y - the result

2394:    Notes:
2395:    The vectors x and y cannot be the same.  I.e., one cannot
2396:    call MatMultHermitianTranspose(A,y,y).

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

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

2402:    Level: beginner

2404:    Concepts: matrix vector product^transpose

2406: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2407: @*/
2408: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2409: {
2411:   Vec            w;


2419:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2420:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2421:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2422: #if !defined(PETSC_HAVE_CONSTRAINTS)
2423:   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);
2424:   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);
2425: #endif
2426:   MatCheckPreallocated(mat,1);

2428:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2429:   if (mat->ops->multhermitiantranspose) {
2430:     VecLockPush(x);
2431:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2432:     VecLockPop(x);
2433:   } else {
2434:     VecDuplicate(x,&w);
2435:     VecCopy(x,w);
2436:     VecConjugate(w);
2437:     MatMultTranspose(mat,w,y);
2438:     VecDestroy(&w);
2439:     VecConjugate(y);
2440:   }
2441:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2442:   PetscObjectStateIncrease((PetscObject)y);
2443:   return(0);
2444: }

2446: /*@
2447:     MatMultAdd -  Computes v3 = v2 + A * v1.

2449:     Neighbor-wise Collective on Mat and Vec

2451:     Input Parameters:
2452: +   mat - the matrix
2453: -   v1, v2 - the vectors

2455:     Output Parameters:
2456: .   v3 - the result

2458:     Notes:
2459:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2460:     call MatMultAdd(A,v1,v2,v1).

2462:     Level: beginner

2464:     Concepts: matrix vector product^addition

2466: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2467: @*/
2468: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2469: {


2479:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2480:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2481:   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);
2482:   /* 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);
2483:      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); */
2484:   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);
2485:   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);
2486:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2487:   MatCheckPreallocated(mat,1);

2489:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2490:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2491:   VecLockPush(v1);
2492:   (*mat->ops->multadd)(mat,v1,v2,v3);
2493:   VecLockPop(v1);
2494:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2495:   PetscObjectStateIncrease((PetscObject)v3);
2496:   return(0);
2497: }

2499: /*@
2500:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2502:    Neighbor-wise Collective on Mat and Vec

2504:    Input Parameters:
2505: +  mat - the matrix
2506: -  v1, v2 - the vectors

2508:    Output Parameters:
2509: .  v3 - the result

2511:    Notes:
2512:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2513:    call MatMultTransposeAdd(A,v1,v2,v1).

2515:    Level: beginner

2517:    Concepts: matrix vector product^transpose and addition

2519: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2520: @*/
2521: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2522: {


2532:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2533:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2534:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2535:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2536:   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);
2537:   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);
2538:   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);
2539:   MatCheckPreallocated(mat,1);

2541:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2542:   VecLockPush(v1);
2543:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2544:   VecLockPop(v1);
2545:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2546:   PetscObjectStateIncrease((PetscObject)v3);
2547:   return(0);
2548: }

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

2553:    Neighbor-wise Collective on Mat and Vec

2555:    Input Parameters:
2556: +  mat - the matrix
2557: -  v1, v2 - the vectors

2559:    Output Parameters:
2560: .  v3 - the result

2562:    Notes:
2563:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2564:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2566:    Level: beginner

2568:    Concepts: matrix vector product^transpose and addition

2570: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2571: @*/
2572: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2573: {


2583:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2584:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2585:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2586:   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);
2587:   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);
2588:   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);
2589:   MatCheckPreallocated(mat,1);

2591:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2592:   VecLockPush(v1);
2593:   if (mat->ops->multhermitiantransposeadd) {
2594:     (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2595:    } else {
2596:     Vec w,z;
2597:     VecDuplicate(v1,&w);
2598:     VecCopy(v1,w);
2599:     VecConjugate(w);
2600:     VecDuplicate(v3,&z);
2601:     MatMultTranspose(mat,w,z);
2602:     VecDestroy(&w);
2603:     VecConjugate(z);
2604:     VecWAXPY(v3,1.0,v2,z);
2605:     VecDestroy(&z);
2606:   }
2607:   VecLockPop(v1);
2608:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2609:   PetscObjectStateIncrease((PetscObject)v3);
2610:   return(0);
2611: }

2613: /*@
2614:    MatMultConstrained - The inner multiplication routine for a
2615:    constrained matrix P^T A P.

2617:    Neighbor-wise Collective on Mat and Vec

2619:    Input Parameters:
2620: +  mat - the matrix
2621: -  x   - the vector to be multilplied

2623:    Output Parameters:
2624: .  y - the result

2626:    Notes:
2627:    The vectors x and y cannot be the same.  I.e., one cannot
2628:    call MatMult(A,y,y).

2630:    Level: beginner

2632: .keywords: matrix, multiply, matrix-vector product, constraint
2633: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2634: @*/
2635: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2636: {

2643:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2644:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2645:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2646:   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);
2647:   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);
2648:   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);

2650:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2651:   VecLockPush(x);
2652:   (*mat->ops->multconstrained)(mat,x,y);
2653:   VecLockPop(x);
2654:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2655:   PetscObjectStateIncrease((PetscObject)y);
2656:   return(0);
2657: }

2659: /*@
2660:    MatMultTransposeConstrained - The inner multiplication routine for a
2661:    constrained matrix P^T A^T P.

2663:    Neighbor-wise Collective on Mat and Vec

2665:    Input Parameters:
2666: +  mat - the matrix
2667: -  x   - the vector to be multilplied

2669:    Output Parameters:
2670: .  y - the result

2672:    Notes:
2673:    The vectors x and y cannot be the same.  I.e., one cannot
2674:    call MatMult(A,y,y).

2676:    Level: beginner

2678: .keywords: matrix, multiply, matrix-vector product, constraint
2679: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2680: @*/
2681: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2682: {

2689:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2690:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2691:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2692:   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);
2693:   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);

2695:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2696:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2697:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2698:   PetscObjectStateIncrease((PetscObject)y);
2699:   return(0);
2700: }

2702: /*@C
2703:    MatGetFactorType - gets the type of factorization it is

2705:    Note Collective
2706:    as the flag

2708:    Input Parameters:
2709: .  mat - the matrix

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

2714:     Level: intermediate

2716: .seealso:    MatFactorType, MatGetFactor()
2717: @*/
2718: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2719: {
2723:   *t = mat->factortype;
2724:   return(0);
2725: }

2727: /* ------------------------------------------------------------*/
2728: /*@C
2729:    MatGetInfo - Returns information about matrix storage (number of
2730:    nonzeros, memory, etc.).

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

2734:    Input Parameters:
2735: .  mat - the matrix

2737:    Output Parameters:
2738: +  flag - flag indicating the type of parameters to be returned
2739:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2740:    MAT_GLOBAL_SUM - sum over all processors)
2741: -  info - matrix information context

2743:    Notes:
2744:    The MatInfo context contains a variety of matrix data, including
2745:    number of nonzeros allocated and used, number of mallocs during
2746:    matrix assembly, etc.  Additional information for factored matrices
2747:    is provided (such as the fill ratio, number of mallocs during
2748:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2749:    when using the runtime options
2750: $       -info -mat_view ::ascii_info

2752:    Example for C/C++ Users:
2753:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2754:    data within the MatInfo context.  For example,
2755: .vb
2756:       MatInfo info;
2757:       Mat     A;
2758:       double  mal, nz_a, nz_u;

2760:       MatGetInfo(A,MAT_LOCAL,&info);
2761:       mal  = info.mallocs;
2762:       nz_a = info.nz_allocated;
2763: .ve

2765:    Example for Fortran Users:
2766:    Fortran users should declare info as a double precision
2767:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2768:    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2769:    a complete list of parameter names.
2770: .vb
2771:       double  precision info(MAT_INFO_SIZE)
2772:       double  precision mal, nz_a
2773:       Mat     A
2774:       integer ierr

2776:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2777:       mal = info(MAT_INFO_MALLOCS)
2778:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2779: .ve

2781:     Level: intermediate

2783:     Concepts: matrices^getting information on

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

2788: .seealso: MatStashGetInfo()

2790: @*/
2791: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2792: {

2799:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2800:   MatCheckPreallocated(mat,1);
2801:   (*mat->ops->getinfo)(mat,flag,info);
2802:   return(0);
2803: }

2805: /*
2806:    This is used by external packages where it is not easy to get the info from the actual
2807:    matrix factorization.
2808: */
2809: PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2810: {

2814:   PetscMemzero(info,sizeof(MatInfo));
2815:   return(0);
2816: }

2818: /* ----------------------------------------------------------*/

2820: /*@C
2821:    MatLUFactor - Performs in-place LU factorization of matrix.

2823:    Collective on Mat

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

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

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

2842:    Level: developer

2844:    Concepts: matrices^LU factorization

2846: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2847:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2852: @*/
2853: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2854: {
2856:   MatFactorInfo  tinfo;

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

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

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

2883:    Collective on Mat

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

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

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

2903:    Level: developer

2905:    Concepts: matrices^ILU factorization

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

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

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

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

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

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

2940:    Collective on Mat

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


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

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

2958:    Level: developer

2960:    Concepts: matrices^LU symbolic factorization

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

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

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

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

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

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

2999:    Collective on Mat

3001:    Input Parameters:
3002: +  fact - the factor matrix obtained with MatGetFactor()
3003: .  mat - the matrix
3004: -  info - options for factorization

3006:    Notes:
3007:    See MatLUFactor() for in-place factorization.  See
3008:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

3014:    Level: developer

3016:    Concepts: matrices^LU numeric factorization

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

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

3023: @*/
3024: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3025: {

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

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

3046: /*@C
3047:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3048:    symmetric matrix.

3050:    Collective on Mat

3052:    Input Parameters:
3053: +  mat - the matrix
3054: .  perm - row and column permutations
3055: -  f - expected fill as ratio of original fill

3057:    Notes:
3058:    See MatLUFactor() for the nonsymmetric case.  See also
3059:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

3065:    Level: developer

3067:    Concepts: matrices^Cholesky factorization

3069: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3070:           MatGetOrdering()

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

3075: @*/
3076: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3077: {

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

3091:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3092:   (*mat->ops->choleskyfactor)(mat,perm,info);
3093:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3094:   PetscObjectStateIncrease((PetscObject)mat);
3095:   return(0);
3096: }

3098: /*@C
3099:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3100:    of a symmetric matrix.

3102:    Collective on Mat

3104:    Input Parameters:
3105: +  fact - the factor matrix obtained with MatGetFactor()
3106: .  mat - the matrix
3107: .  perm - row and column permutations
3108: -  info - options for factorization, includes
3109: $          fill - expected fill as ratio of original fill.
3110: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3111: $                   Run with the option -info to determine an optimal value to use

3113:    Notes:
3114:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3115:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

3121:    Level: developer

3123:    Concepts: matrices^Cholesky symbolic factorization

3125: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3126:           MatGetOrdering()

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

3131: @*/
3132: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3133: {

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

3152:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3153:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3154:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3155:   PetscObjectStateIncrease((PetscObject)fact);
3156:   return(0);
3157: }

3159: /*@C
3160:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3161:    of a symmetric matrix. Call this routine after first calling
3162:    MatCholeskyFactorSymbolic().

3164:    Collective on Mat

3166:    Input Parameters:
3167: +  fact - the factor matrix obtained with MatGetFactor()
3168: .  mat - the initial matrix
3169: .  info - options for factorization
3170: -  fact - the symbolic factor of mat


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

3178:    Level: developer

3180:    Concepts: matrices^Cholesky numeric factorization

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

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

3187: @*/
3188: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3189: {

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

3202:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3203:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3204:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3205:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3206:   PetscObjectStateIncrease((PetscObject)fact);
3207:   return(0);
3208: }

3210: /* ----------------------------------------------------------------*/
3211: /*@
3212:    MatSolve - Solves A x = b, given a factored matrix.

3214:    Neighbor-wise Collective on Mat and Vec

3216:    Input Parameters:
3217: +  mat - the factored matrix
3218: -  b - the right-hand-side vector

3220:    Output Parameter:
3221: .  x - the result vector

3223:    Notes:
3224:    The vectors b and x cannot be the same.  I.e., one cannot
3225:    call MatSolve(A,x,x).

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

3232:    Level: developer

3234:    Concepts: matrices^triangular solves

3236: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3237: @*/
3238: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3239: {

3249:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3250:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3251:   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);
3252:   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);
3253:   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);
3254:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3255:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3256:   MatCheckPreallocated(mat,1);

3258:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3259:   if (mat->factorerrortype) {
3260:     PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3261:     VecSetInf(x);
3262:   } else {
3263:     (*mat->ops->solve)(mat,b,x);
3264:   }
3265:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3266:   PetscObjectStateIncrease((PetscObject)x);
3267:   return(0);
3268: }

3270: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3271: {
3273:   Vec            b,x;
3274:   PetscInt       m,N,i;
3275:   PetscScalar    *bb,*xx;
3276:   PetscBool      flg;

3279:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3280:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3281:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3282:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3284:   MatDenseGetArray(B,&bb);
3285:   MatDenseGetArray(X,&xx);
3286:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3287:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3288:   MatCreateVecs(A,&x,&b);
3289:   for (i=0; i<N; i++) {
3290:     VecPlaceArray(b,bb + i*m);
3291:     VecPlaceArray(x,xx + i*m);
3292:     MatSolve(A,b,x);
3293:     VecResetArray(x);
3294:     VecResetArray(b);
3295:   }
3296:   VecDestroy(&b);
3297:   VecDestroy(&x);
3298:   MatDenseRestoreArray(B,&bb);
3299:   MatDenseRestoreArray(X,&xx);
3300:   return(0);
3301: }

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

3306:    Neighbor-wise Collective on Mat

3308:    Input Parameters:
3309: +  A - the factored matrix
3310: -  B - the right-hand-side matrix  (dense matrix)

3312:    Output Parameter:
3313: .  X - the result matrix (dense matrix)

3315:    Notes:
3316:    The matrices b and x cannot be the same.  I.e., one cannot
3317:    call MatMatSolve(A,x,x).

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

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

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

3330:    Level: developer

3332:    Concepts: matrices^triangular solves

3334: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3335: @*/
3336: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3337: {

3347:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3348:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3349:   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);
3350:   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);
3351:   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);
3352:   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");
3353:   if (!A->rmap->N && !A->cmap->N) return(0);
3354:   MatCheckPreallocated(A,1);

3356:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3357:   if (!A->ops->matsolve) {
3358:     PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3359:     MatMatSolve_Basic(A,B,X);
3360:   } else {
3361:     (*A->ops->matsolve)(A,B,X);
3362:   }
3363:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3364:   PetscObjectStateIncrease((PetscObject)X);
3365:   return(0);
3366: }


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

3373:    Neighbor-wise Collective on Mat and Vec

3375:    Input Parameters:
3376: +  mat - the factored matrix
3377: -  b - the right-hand-side vector

3379:    Output Parameter:
3380: .  x - the result vector

3382:    Notes:
3383:    MatSolve() should be used for most applications, as it performs
3384:    a forward solve followed by a backward solve.

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

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

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

3399:    Level: developer

3401:    Concepts: matrices^forward solves

3403: .seealso: MatSolve(), MatBackwardSolve()
3404: @*/
3405: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3406: {

3416:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3417:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3418:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3419:   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);
3420:   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);
3421:   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);
3422:   MatCheckPreallocated(mat,1);
3423:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3424:   (*mat->ops->forwardsolve)(mat,b,x);
3425:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3426:   PetscObjectStateIncrease((PetscObject)x);
3427:   return(0);
3428: }

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

3434:    Neighbor-wise Collective on Mat and Vec

3436:    Input Parameters:
3437: +  mat - the factored matrix
3438: -  b - the right-hand-side vector

3440:    Output Parameter:
3441: .  x - the result vector

3443:    Notes:
3444:    MatSolve() should be used for most applications, as it performs
3445:    a forward solve followed by a backward solve.

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

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

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

3460:    Level: developer

3462:    Concepts: matrices^backward solves

3464: .seealso: MatSolve(), MatForwardSolve()
3465: @*/
3466: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3467: {

3477:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3478:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3479:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3480:   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);
3481:   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);
3482:   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);
3483:   MatCheckPreallocated(mat,1);

3485:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3486:   (*mat->ops->backwardsolve)(mat,b,x);
3487:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3488:   PetscObjectStateIncrease((PetscObject)x);
3489:   return(0);
3490: }

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

3495:    Neighbor-wise Collective on Mat and Vec

3497:    Input Parameters:
3498: +  mat - the factored matrix
3499: .  b - the right-hand-side vector
3500: -  y - the vector to be added to

3502:    Output Parameter:
3503: .  x - the result vector

3505:    Notes:
3506:    The vectors b and x cannot be the same.  I.e., one cannot
3507:    call MatSolveAdd(A,x,y,x).

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

3513:    Level: developer

3515:    Concepts: matrices^triangular solves

3517: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3518: @*/
3519: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3520: {
3521:   PetscScalar    one = 1.0;
3522:   Vec            tmp;

3534:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3535:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3536:   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);
3537:   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);
3538:   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);
3539:   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);
3540:   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);
3541:   MatCheckPreallocated(mat,1);

3543:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3544:   if (mat->ops->solveadd) {
3545:     (*mat->ops->solveadd)(mat,b,y,x);
3546:   } else {
3547:     /* do the solve then the add manually */
3548:     if (x != y) {
3549:       MatSolve(mat,b,x);
3550:       VecAXPY(x,one,y);
3551:     } else {
3552:       VecDuplicate(x,&tmp);
3553:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3554:       VecCopy(x,tmp);
3555:       MatSolve(mat,b,x);
3556:       VecAXPY(x,one,tmp);
3557:       VecDestroy(&tmp);
3558:     }
3559:   }
3560:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3561:   PetscObjectStateIncrease((PetscObject)x);
3562:   return(0);
3563: }

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

3568:    Neighbor-wise Collective on Mat and Vec

3570:    Input Parameters:
3571: +  mat - the factored matrix
3572: -  b - the right-hand-side vector

3574:    Output Parameter:
3575: .  x - the result vector

3577:    Notes:
3578:    The vectors b and x cannot be the same.  I.e., one cannot
3579:    call MatSolveTranspose(A,x,x).

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

3585:    Level: developer

3587:    Concepts: matrices^triangular solves

3589: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3590: @*/
3591: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3592: {

3602:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3603:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3604:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3605:   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);
3606:   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);
3607:   MatCheckPreallocated(mat,1);
3608:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3609:   if (mat->factorerrortype) {
3610:     PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3611:     VecSetInf(x);
3612:   } else {
3613:     (*mat->ops->solvetranspose)(mat,b,x);
3614:   }
3615:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3616:   PetscObjectStateIncrease((PetscObject)x);
3617:   return(0);
3618: }

3620: /*@
3621:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3622:                       factored matrix.

3624:    Neighbor-wise Collective on Mat and Vec

3626:    Input Parameters:
3627: +  mat - the factored matrix
3628: .  b - the right-hand-side vector
3629: -  y - the vector to be added to

3631:    Output Parameter:
3632: .  x - the result vector

3634:    Notes:
3635:    The vectors b and x cannot be the same.  I.e., one cannot
3636:    call MatSolveTransposeAdd(A,x,y,x).

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

3642:    Level: developer

3644:    Concepts: matrices^triangular solves

3646: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3647: @*/
3648: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3649: {
3650:   PetscScalar    one = 1.0;
3652:   Vec            tmp;

3663:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3664:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3665:   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);
3666:   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);
3667:   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);
3668:   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);
3669:   MatCheckPreallocated(mat,1);

3671:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3672:   if (mat->ops->solvetransposeadd) {
3673:     if (mat->factorerrortype) {
3674:       PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3675:       VecSetInf(x);
3676:     } else {
3677:       (*mat->ops->solvetransposeadd)(mat,b,y,x);
3678:     }
3679:   } else {
3680:     /* do the solve then the add manually */
3681:     if (x != y) {
3682:       MatSolveTranspose(mat,b,x);
3683:       VecAXPY(x,one,y);
3684:     } else {
3685:       VecDuplicate(x,&tmp);
3686:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3687:       VecCopy(x,tmp);
3688:       MatSolveTranspose(mat,b,x);
3689:       VecAXPY(x,one,tmp);
3690:       VecDestroy(&tmp);
3691:     }
3692:   }
3693:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3694:   PetscObjectStateIncrease((PetscObject)x);
3695:   return(0);
3696: }
3697: /* ----------------------------------------------------------------*/

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

3702:    Neighbor-wise Collective on Mat and Vec

3704:    Input Parameters:
3705: +  mat - the matrix
3706: .  b - the right hand side
3707: .  omega - the relaxation factor
3708: .  flag - flag indicating the type of SOR (see below)
3709: .  shift -  diagonal shift
3710: .  its - the number of iterations
3711: -  lits - the number of local iterations

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

3716:    SOR Flags:
3717: .     SOR_FORWARD_SWEEP - forward SOR
3718: .     SOR_BACKWARD_SWEEP - backward SOR
3719: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3720: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3721: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3722: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3723: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3724:          upper/lower triangular part of matrix to
3725:          vector (with omega)
3726: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3728:    Notes:
3729:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3730:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3731:    on each processor.

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

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

3738:    Notes for Advanced Users:
3739:    The flags are implemented as bitwise inclusive or operations.
3740:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3741:    to specify a zero initial guess for SSOR.

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

3747:    Vectors x and b CANNOT be the same

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

3751:    Level: developer

3753:    Concepts: matrices^relaxation
3754:    Concepts: matrices^SOR
3755:    Concepts: matrices^Gauss-Seidel

3757: @*/
3758: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3759: {

3769:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3770:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3771:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3772:   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);
3773:   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);
3774:   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);
3775:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3776:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3777:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3779:   MatCheckPreallocated(mat,1);
3780:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3781:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3782:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3783:   PetscObjectStateIncrease((PetscObject)x);
3784:   return(0);
3785: }

3787: /*
3788:       Default matrix copy routine.
3789: */
3790: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3791: {
3792:   PetscErrorCode    ierr;
3793:   PetscInt          i,rstart = 0,rend = 0,nz;
3794:   const PetscInt    *cwork;
3795:   const PetscScalar *vwork;

3798:   if (B->assembled) {
3799:     MatZeroEntries(B);
3800:   }
3801:   MatGetOwnershipRange(A,&rstart,&rend);
3802:   for (i=rstart; i<rend; i++) {
3803:     MatGetRow(A,i,&nz,&cwork,&vwork);
3804:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3805:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3806:   }
3807:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3808:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3809:   PetscObjectStateIncrease((PetscObject)B);
3810:   return(0);
3811: }

3813: /*@
3814:    MatCopy - Copys a matrix to another matrix.

3816:    Collective on Mat

3818:    Input Parameters:
3819: +  A - the matrix
3820: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3822:    Output Parameter:
3823: .  B - where the copy is put

3825:    Notes:
3826:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3827:    same nonzero pattern or the routine will crash.

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

3833:    Level: intermediate

3835:    Concepts: matrices^copying

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

3839: @*/
3840: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3841: {
3843:   PetscInt       i;

3851:   MatCheckPreallocated(B,2);
3852:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3853:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3854:   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);
3855:   MatCheckPreallocated(A,1);

3857:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3858:   if (A->ops->copy) {
3859:     (*A->ops->copy)(A,B,str);
3860:   } else { /* generic conversion */
3861:     MatCopy_Basic(A,B,str);
3862:   }

3864:   B->stencil.dim = A->stencil.dim;
3865:   B->stencil.noc = A->stencil.noc;
3866:   for (i=0; i<=A->stencil.dim; i++) {
3867:     B->stencil.dims[i]   = A->stencil.dims[i];
3868:     B->stencil.starts[i] = A->stencil.starts[i];
3869:   }

3871:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3872:   PetscObjectStateIncrease((PetscObject)B);
3873:   return(0);
3874: }

3876: /*@C
3877:    MatConvert - Converts a matrix to another matrix, either of the same
3878:    or different type.

3880:    Collective on Mat

3882:    Input Parameters:
3883: +  mat - the matrix
3884: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3885:    same type as the original matrix.
3886: -  reuse - denotes if the destination matrix is to be created or reused.
3887:    Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use
3888:    MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused).

3890:    Output Parameter:
3891: .  M - pointer to place new matrix

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

3898:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3899:    the MPI communicator of the generated matrix is always the same as the communicator
3900:    of the input matrix.

3902:    Level: intermediate

3904:    Concepts: matrices^converting between storage formats

3906: .seealso: MatCopy(), MatDuplicate()
3907: @*/
3908: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3909: {
3911:   PetscBool      sametype,issame,flg;
3912:   char           convname[256],mtype[256];
3913:   Mat            B;

3919:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3920:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3921:   MatCheckPreallocated(mat,1);
3922:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

3924:   PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3925:   if (flg) {
3926:     newtype = mtype;
3927:   }
3928:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3929:   PetscStrcmp(newtype,"same",&issame);
3930:   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
3931:   if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX");

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

3935:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3936:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3937:   } else {
3938:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3939:     const char     *prefix[3] = {"seq","mpi",""};
3940:     PetscInt       i;
3941:     /*
3942:        Order of precedence:
3943:        1) See if a specialized converter is known to the current matrix.
3944:        2) See if a specialized converter is known to the desired matrix class.
3945:        3) See if a good general converter is registered for the desired class
3946:           (as of 6/27/03 only MATMPIADJ falls into this category).
3947:        4) See if a good general converter is known for the current matrix.
3948:        5) Use a really basic converter.
3949:     */

3951:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3952:     for (i=0; i<3; i++) {
3953:       PetscStrcpy(convname,"MatConvert_");
3954:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3955:       PetscStrcat(convname,"_");
3956:       PetscStrcat(convname,prefix[i]);
3957:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3958:       PetscStrcat(convname,"_C");
3959:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3960:       if (conv) goto foundconv;
3961:     }

3963:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3964:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
3965:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3966:     MatSetType(B,newtype);
3967:     for (i=0; i<3; i++) {
3968:       PetscStrcpy(convname,"MatConvert_");
3969:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3970:       PetscStrcat(convname,"_");
3971:       PetscStrcat(convname,prefix[i]);
3972:       PetscStrcat(convname,newtype);
3973:       PetscStrcat(convname,"_C");
3974:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3975:       if (conv) {
3976:         MatDestroy(&B);
3977:         goto foundconv;
3978:       }
3979:     }

3981:     /* 3) See if a good general converter is registered for the desired class */
3982:     conv = B->ops->convertfrom;
3983:     MatDestroy(&B);
3984:     if (conv) goto foundconv;

3986:     /* 4) See if a good general converter is known for the current matrix */
3987:     if (mat->ops->convert) {
3988:       conv = mat->ops->convert;
3989:     }
3990:     if (conv) goto foundconv;

3992:     /* 5) Use a really basic converter. */
3993:     conv = MatConvert_Basic;

3995: foundconv:
3996:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3997:     (*conv)(mat,newtype,reuse,M);
3998:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3999:   }
4000:   PetscObjectStateIncrease((PetscObject)*M);

4002:   /* Copy Mat options */
4003:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
4004:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
4005:   return(0);
4006: }

4008: /*@C
4009:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

4011:    Not Collective

4013:    Input Parameter:
4014: .  mat - the matrix, must be a factored matrix

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

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

4023:    Level: intermediate

4025: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4026: @*/
4027: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4028: {
4029:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

4034:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4035:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
4036:   if (!conv) {
4037:     *type = MATSOLVERPETSC;
4038:   } else {
4039:     (*conv)(mat,type);
4040:   }
4041:   return(0);
4042: }

4044: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4045: struct _MatSolverPackageForSpecifcType {
4046:   MatType                        mtype;
4047:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4048:   MatSolverPackageForSpecifcType next;
4049: };

4051: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4052: struct _MatSolverPackageHolder {
4053:   char                           *name;
4054:   MatSolverPackageForSpecifcType handlers;
4055:   MatSolverPackageHolder         next;
4056: };

4058: static MatSolverPackageHolder MatSolverPackageHolders = NULL;

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

4063:    Input Parameters:
4064: +    package - name of the package, for example petsc or superlu
4065: .    mtype - the matrix type that works with this package
4066: .    ftype - the type of factorization supported by the package
4067: -    getfactor - routine that will create the factored matrix ready to be used

4069:     Level: intermediate

4071: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4072: @*/
4073: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4074: {
4075:   PetscErrorCode                 ierr;
4076:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4077:   PetscBool                      flg;
4078:   MatSolverPackageForSpecifcType inext,iprev = NULL;

4081:   if (!next) {
4082:     PetscNew(&MatSolverPackageHolders);
4083:     PetscStrallocpy(package,&MatSolverPackageHolders->name);
4084:     PetscNew(&MatSolverPackageHolders->handlers);
4085:     PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4086:     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4087:     return(0);
4088:   }
4089:   while (next) {
4090:     PetscStrcasecmp(package,next->name,&flg);
4091:     if (flg) {
4092:       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverPackageHolder is missing handlers");
4093:       inext = next->handlers;
4094:       while (inext) {
4095:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4096:         if (flg) {
4097:           inext->getfactor[(int)ftype-1] = getfactor;
4098:           return(0);
4099:         }
4100:         iprev = inext;
4101:         inext = inext->next;
4102:       }
4103:       PetscNew(&iprev->next);
4104:       PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4105:       iprev->next->getfactor[(int)ftype-1] = getfactor;
4106:       return(0);
4107:     }
4108:     prev = next;
4109:     next = next->next;
4110:   }
4111:   PetscNew(&prev->next);
4112:   PetscStrallocpy(package,&prev->next->name);
4113:   PetscNew(&prev->next->handlers);
4114:   PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4115:   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4116:   return(0);
4117: }

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

4122:    Input Parameters:
4123: +    package - name of the package, for example petsc or superlu
4124: .    ftype - the type of factorization supported by the package
4125: -    mtype - the matrix type that works with this package

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

4132:     Level: intermediate

4134: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4135: @*/
4136: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4137: {
4138:   PetscErrorCode                 ierr;
4139:   MatSolverPackageHolder         next = MatSolverPackageHolders;
4140:   PetscBool                      flg;
4141:   MatSolverPackageForSpecifcType inext;

4144:   if (foundpackage) *foundpackage = PETSC_FALSE;
4145:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4146:   if (getfactor)    *getfactor    = NULL;

4148:   if (package) {
4149:     while (next) {
4150:       PetscStrcasecmp(package,next->name,&flg);
4151:       if (flg) {
4152:         if (foundpackage) *foundpackage = PETSC_TRUE;
4153:         inext = next->handlers;
4154:         while (inext) {
4155:           PetscStrcasecmp(mtype,inext->mtype,&flg);
4156:           if (flg) {
4157:             if (foundmtype) *foundmtype = PETSC_TRUE;
4158:             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4159:             return(0);
4160:           }
4161:           inext = inext->next;
4162:         }
4163:       }
4164:       next = next->next;
4165:     }
4166:   } else {
4167:     while (next) {
4168:       inext = next->handlers;
4169:       while (inext) {
4170:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4171:         if (flg && inext->getfactor[(int)ftype-1]) {
4172:           if (foundpackage) *foundpackage = PETSC_TRUE;
4173:           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4174:           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4175:           return(0);
4176:         }
4177:         inext = inext->next;
4178:       }
4179:       next = next->next;
4180:     }
4181:   }
4182:   return(0);
4183: }

4185: PetscErrorCode MatSolverPackageDestroy(void)
4186: {
4187:   PetscErrorCode                 ierr;
4188:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4189:   MatSolverPackageForSpecifcType inext,iprev;

4192:   while (next) {
4193:     PetscFree(next->name);
4194:     inext = next->handlers;
4195:     while (inext) {
4196:       PetscFree(inext->mtype);
4197:       iprev = inext;
4198:       inext = inext->next;
4199:       PetscFree(iprev);
4200:     }
4201:     prev = next;
4202:     next = next->next;
4203:     PetscFree(prev);
4204:   }
4205:   MatSolverPackageHolders = NULL;
4206:   return(0);
4207: }

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

4212:    Collective on Mat

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

4219:    Output Parameters:
4220: .  f - the factor matrix used with MatXXFactorSymbolic() calls

4222:    Notes:
4223:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4224:      such as pastix, superlu, mumps etc.

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

4228:    Level: intermediate

4230: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4231: @*/
4232: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4233: {
4234:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4235:   PetscBool      foundpackage,foundmtype;


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

4244:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4245:   if (!foundpackage) {
4246:     if (type) {
4247:       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4248:     } else {
4249:       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4250:     }
4251:   }

4253:   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4254:   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);

4256:   (*conv)(mat,ftype,f);
4257:   return(0);
4258: }

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

4263:    Not Collective

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

4270:    Output Parameter:
4271: .    flg - PETSC_TRUE if the factorization is available

4273:    Notes:
4274:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4275:      such as pastix, superlu, mumps etc.

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

4279:    Level: intermediate

4281: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4282: @*/
4283: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4284: {
4285:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);


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

4294:   *flg = PETSC_FALSE;
4295:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4296:   if (gconv) {
4297:     *flg = PETSC_TRUE;
4298:   }
4299:   return(0);
4300: }

4302:  #include <petscdmtypes.h>

4304: /*@
4305:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4307:    Collective on Mat

4309:    Input Parameters:
4310: +  mat - the matrix
4311: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4312:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

4314:    Output Parameter:
4315: .  M - pointer to place new matrix

4317:    Level: intermediate

4319:    Concepts: matrices^duplicating

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

4323: .seealso: MatCopy(), MatConvert()
4324: @*/
4325: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4326: {
4328:   Mat            B;
4329:   PetscInt       i;
4330:   DM             dm;

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

4340:   *M = 0;
4341:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4342:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4343:   (*mat->ops->duplicate)(mat,op,M);
4344:   B    = *M;

4346:   B->stencil.dim = mat->stencil.dim;
4347:   B->stencil.noc = mat->stencil.noc;
4348:   for (i=0; i<=mat->stencil.dim; i++) {
4349:     B->stencil.dims[i]   = mat->stencil.dims[i];
4350:     B->stencil.starts[i] = mat->stencil.starts[i];
4351:   }

4353:   B->nooffproczerorows = mat->nooffproczerorows;
4354:   B->nooffprocentries  = mat->nooffprocentries;

4356:   PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4357:   if (dm) {
4358:     PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4359:   }
4360:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4361:   PetscObjectStateIncrease((PetscObject)B);
4362:   return(0);
4363: }

4365: /*@
4366:    MatGetDiagonal - Gets the diagonal of a matrix.

4368:    Logically Collective on Mat and Vec

4370:    Input Parameters:
4371: +  mat - the matrix
4372: -  v - the vector for storing the diagonal

4374:    Output Parameter:
4375: .  v - the diagonal of the matrix

4377:    Level: intermediate

4379:    Note:
4380:    Currently only correct in parallel for square matrices.

4382:    Concepts: matrices^accessing diagonals

4384: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4385: @*/
4386: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4387: {

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

4398:   (*mat->ops->getdiagonal)(mat,v);
4399:   PetscObjectStateIncrease((PetscObject)v);
4400:   return(0);
4401: }

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

4407:    Logically Collective on Mat and Vec

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

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

4416:    Level: intermediate

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

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

4423:    Concepts: matrices^getting row maximums

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

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

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

4445: /*@C
4446:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4447:         row of the matrix

4449:    Logically Collective on Mat and Vec

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

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

4458:    Level: intermediate

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

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

4465:    Concepts: matrices^getting row maximums

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

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

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

4487: /*@C
4488:    MatGetRowMax - Gets the maximum value (of the real part) of each
4489:         row of the matrix

4491:    Logically Collective on Mat and Vec

4493:    Input Parameters:
4494: .  mat - the matrix

4496:    Output Parameter:
4497: +  v - the vector for storing the maximums
4498: -  idx - the indices of the column found for each row (optional)

4500:    Level: intermediate

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

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

4507:    Concepts: matrices^getting row maximums

4509: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4510: @*/
4511: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4512: {

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

4523:   (*mat->ops->getrowmax)(mat,v,idx);
4524:   PetscObjectStateIncrease((PetscObject)v);
4525:   return(0);
4526: }

4528: /*@C
4529:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4530:         row of the matrix

4532:    Logically Collective on Mat and Vec

4534:    Input Parameters:
4535: .  mat - the matrix

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

4541:    Level: intermediate

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

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

4548:    Concepts: matrices^getting row maximums

4550: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4551: @*/
4552: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4553: {

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

4565:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4566:   PetscObjectStateIncrease((PetscObject)v);
4567:   return(0);
4568: }

4570: /*@
4571:    MatGetRowSum - Gets the sum of each row of the matrix

4573:    Logically Collective on Mat and Vec

4575:    Input Parameters:
4576: .  mat - the matrix

4578:    Output Parameter:
4579: .  v - the vector for storing the sum of rows

4581:    Level: intermediate

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

4585:    Concepts: matrices^getting row sums

4587: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4588: @*/
4589: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4590: {
4591:   PetscInt       start = 0, end = 0, row;
4592:   PetscScalar    *array;

4599:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4600:   MatCheckPreallocated(mat,1);
4601:   MatGetOwnershipRange(mat, &start, &end);
4602:   VecGetArray(v, &array);
4603:   for (row = start; row < end; ++row) {
4604:     PetscInt          ncols, col;
4605:     const PetscInt    *cols;
4606:     const PetscScalar *vals;

4608:     array[row - start] = 0.0;

4610:     MatGetRow(mat, row, &ncols, &cols, &vals);
4611:     for (col = 0; col < ncols; col++) {
4612:       array[row - start] += vals[col];
4613:     }
4614:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4615:   }
4616:   VecRestoreArray(v, &array);
4617:   PetscObjectStateIncrease((PetscObject) v);
4618:   return(0);
4619: }

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

4624:    Collective on Mat

4626:    Input Parameter:
4627: +  mat - the matrix to transpose
4628: -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX

4630:    Output Parameters:
4631: .  B - the transpose

4633:    Notes:
4634:      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B

4636:      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used

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

4640:    Level: intermediate

4642:    Concepts: matrices^transposing

4644: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4645: @*/
4646: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4647: {

4653:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4654:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4655:   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4656:   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4657:   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4658:   MatCheckPreallocated(mat,1);

4660:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4661:   (*mat->ops->transpose)(mat,reuse,B);
4662:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4663:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4664:   return(0);
4665: }

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

4671:    Collective on Mat

4673:    Input Parameter:
4674: +  A - the matrix to test
4675: -  B - the matrix to test against, this can equal the first parameter

4677:    Output Parameters:
4678: .  flg - the result

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

4685:    Level: intermediate

4687:    Concepts: matrices^transposing, matrix^symmetry

4689: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4690: @*/
4691: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4692: {
4693:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4699:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4700:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4701:   *flg = PETSC_FALSE;
4702:   if (f && g) {
4703:     if (f == g) {
4704:       (*f)(A,B,tol,flg);
4705:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4706:   } else {
4707:     MatType mattype;
4708:     if (!f) {
4709:       MatGetType(A,&mattype);
4710:     } else {
4711:       MatGetType(B,&mattype);
4712:     }
4713:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4714:   }
4715:   return(0);
4716: }

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

4721:    Collective on Mat

4723:    Input Parameter:
4724: +  mat - the matrix to transpose and complex conjugate
4725: -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose

4727:    Output Parameters:
4728: .  B - the Hermitian

4730:    Level: intermediate

4732:    Concepts: matrices^transposing, complex conjugatex

4734: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4735: @*/
4736: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4737: {

4741:   MatTranspose(mat,reuse,B);
4742: #if defined(PETSC_USE_COMPLEX)
4743:   MatConjugate(*B);
4744: #endif
4745:   return(0);
4746: }

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

4751:    Collective on Mat

4753:    Input Parameter:
4754: +  A - the matrix to test
4755: -  B - the matrix to test against, this can equal the first parameter

4757:    Output Parameters:
4758: .  flg - the result

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

4765:    Level: intermediate

4767:    Concepts: matrices^transposing, matrix^symmetry

4769: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4770: @*/
4771: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4772: {
4773:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4779:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4780:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4781:   if (f && g) {
4782:     if (f==g) {
4783:       (*f)(A,B,tol,flg);
4784:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4785:   }
4786:   return(0);
4787: }

4789: /*@
4790:    MatPermute - Creates a new matrix with rows and columns permuted from the
4791:    original.

4793:    Collective on Mat

4795:    Input Parameters:
4796: +  mat - the matrix to permute
4797: .  row - row permutation, each processor supplies only the permutation for its rows
4798: -  col - column permutation, each processor supplies only the permutation for its columns

4800:    Output Parameters:
4801: .  B - the permuted matrix

4803:    Level: advanced

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

4809:    Concepts: matrices^permuting

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

4813: @*/
4814: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4815: {

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

4829:   (*mat->ops->permute)(mat,row,col,B);
4830:   PetscObjectStateIncrease((PetscObject)*B);
4831:   return(0);
4832: }

4834: /*@
4835:    MatEqual - Compares two matrices.

4837:    Collective on Mat

4839:    Input Parameters:
4840: +  A - the first matrix
4841: -  B - the second matrix

4843:    Output Parameter:
4844: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4846:    Level: intermediate

4848:    Concepts: matrices^equality between
4849: @*/
4850: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4851: {

4861:   MatCheckPreallocated(B,2);
4862:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4863:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4864:   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);
4865:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4866:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4867:   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);
4868:   MatCheckPreallocated(A,1);

4870:   (*A->ops->equal)(A,B,flg);
4871:   return(0);
4872: }

4874: /*@
4875:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4876:    matrices that are stored as vectors.  Either of the two scaling
4877:    matrices can be NULL.

4879:    Collective on Mat

4881:    Input Parameters:
4882: +  mat - the matrix to be scaled
4883: .  l - the left scaling vector (or NULL)
4884: -  r - the right scaling vector (or NULL)

4886:    Notes:
4887:    MatDiagonalScale() computes A = LAR, where
4888:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4889:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4891:    Level: intermediate

4893:    Concepts: matrices^diagonal scaling
4894:    Concepts: diagonal scaling of matrices

4896: .seealso: MatScale()
4897: @*/
4898: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4899: {

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

4912:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4913:   (*mat->ops->diagonalscale)(mat,l,r);
4914:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4915:   PetscObjectStateIncrease((PetscObject)mat);
4916: #if defined(PETSC_HAVE_CUSP)
4917:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4918:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4919:   }
4920: #elif defined(PETSC_HAVE_VIENNACL)
4921:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4922:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4923:   }
4924: #elif defined(PETSC_HAVE_VECCUDA)
4925:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4926:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4927:   }
4928: #endif
4929:   return(0);
4930: }

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

4935:     Logically Collective on Mat

4937:     Input Parameters:
4938: +   mat - the matrix to be scaled
4939: -   a  - the scaling value

4941:     Output Parameter:
4942: .   mat - the scaled matrix

4944:     Level: intermediate

4946:     Concepts: matrices^scaling all entries

4948: .seealso: MatDiagonalScale()
4949: @*/
4950: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4951: {

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

4963:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4964:   if (a != (PetscScalar)1.0) {
4965:     (*mat->ops->scale)(mat,a);
4966:     PetscObjectStateIncrease((PetscObject)mat);
4967: #if defined(PETSC_HAVE_CUSP)
4968:     if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4969:       mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4970:     }
4971: #elif defined(PETSC_HAVE_VIENNACL)
4972:     if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4973:       mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4974:     }
4975: #elif defined(PETSC_HAVE_VECCUDA)
4976:     if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4977:       mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4978:     }
4979: #endif
4980:   }
4981:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4982:   return(0);
4983: }

4985: /*@
4986:    MatNorm - Calculates various norms of a matrix.

4988:    Collective on Mat

4990:    Input Parameters:
4991: +  mat - the matrix
4992: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4994:    Output Parameters:
4995: .  nrm - the resulting norm

4997:    Level: intermediate

4999:    Concepts: matrices^norm
5000:    Concepts: norm^of matrix
5001: @*/
5002: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5003: {


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

5016:   (*mat->ops->norm)(mat,type,nrm);
5017:   return(0);
5018: }

5020: /*
5021:      This variable is used to prevent counting of MatAssemblyBegin() that
5022:    are called from within a MatAssemblyEnd().
5023: */
5024: static PetscInt MatAssemblyEnd_InUse = 0;
5025: /*@
5026:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5027:    be called after completing all calls to MatSetValues().

5029:    Collective on Mat

5031:    Input Parameters:
5032: +  mat - the matrix
5033: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5035:    Notes:
5036:    MatSetValues() generally caches the values.  The matrix is ready to
5037:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5038:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5039:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5040:    using the matrix.

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

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

5050:    Level: beginner

5052:    Concepts: matrices^assembling

5054: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5055: @*/
5056: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5057: {

5063:   MatCheckPreallocated(mat,1);
5064:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5065:   if (mat->assembled) {
5066:     mat->was_assembled = PETSC_TRUE;
5067:     mat->assembled     = PETSC_FALSE;
5068:   }
5069:   if (!MatAssemblyEnd_InUse) {
5070:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5071:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5072:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5073:   } else if (mat->ops->assemblybegin) {
5074:     (*mat->ops->assemblybegin)(mat,type);
5075:   }
5076:   return(0);
5077: }

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

5083:    Not Collective

5085:    Input Parameter:
5086: .  mat - the matrix

5088:    Output Parameter:
5089: .  assembled - PETSC_TRUE or PETSC_FALSE

5091:    Level: advanced

5093:    Concepts: matrices^assembled?

5095: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5096: @*/
5097: PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5098: {
5103:   *assembled = mat->assembled;
5104:   return(0);
5105: }

5107: /*@
5108:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5109:    be called after MatAssemblyBegin().

5111:    Collective on Mat

5113:    Input Parameters:
5114: +  mat - the matrix
5115: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5117:    Options Database Keys:
5118: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5119: .  -mat_view ::ascii_info_detail - Prints more detailed info
5120: .  -mat_view - Prints matrix in ASCII format
5121: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5122: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5123: .  -display <name> - Sets display name (default is host)
5124: .  -draw_pause <sec> - Sets number of seconds to pause after display
5125: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 12 Using MATLAB with PETSc )
5126: .  -viewer_socket_machine <machine> - Machine to use for socket
5127: .  -viewer_socket_port <port> - Port number to use for socket
5128: -  -mat_view binary:filename[:append] - Save matrix to file in binary format

5130:    Notes:
5131:    MatSetValues() generally caches the values.  The matrix is ready to
5132:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5133:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5134:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5135:    using the matrix.

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

5141:    Level: beginner

5143: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5144: @*/
5145: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5146: {
5147:   PetscErrorCode  ierr;
5148:   static PetscInt inassm = 0;
5149:   PetscBool       flg    = PETSC_FALSE;


5155:   inassm++;
5156:   MatAssemblyEnd_InUse++;
5157:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5158:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5159:     if (mat->ops->assemblyend) {
5160:       (*mat->ops->assemblyend)(mat,type);
5161:     }
5162:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5163:   } else if (mat->ops->assemblyend) {
5164:     (*mat->ops->assemblyend)(mat,type);
5165:   }

5167:   /* Flush assembly is not a true assembly */
5168:   if (type != MAT_FLUSH_ASSEMBLY) {
5169:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5170:   }
5171:   mat->insertmode = NOT_SET_VALUES;
5172:   MatAssemblyEnd_InUse--;
5173:   PetscObjectStateIncrease((PetscObject)mat);
5174:   if (!mat->symmetric_eternal) {
5175:     mat->symmetric_set              = PETSC_FALSE;
5176:     mat->hermitian_set              = PETSC_FALSE;
5177:     mat->structurally_symmetric_set = PETSC_FALSE;
5178:   }
5179: #if defined(PETSC_HAVE_CUSP)
5180:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5181:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5182:   }
5183: #elif defined(PETSC_HAVE_VIENNACL)
5184:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5185:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5186:   }
5187: #elif defined(PETSC_HAVE_VECCUDA)
5188:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5189:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5190:   }
5191: #endif
5192:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5193:     MatViewFromOptions(mat,NULL,"-mat_view");

5195:     if (mat->checksymmetryonassembly) {
5196:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5197:       if (flg) {
5198:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5199:       } else {
5200:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5201:       }
5202:     }
5203:     if (mat->nullsp && mat->checknullspaceonassembly) {
5204:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5205:     }
5206:   }
5207:   inassm--;
5208:   return(0);
5209: }

5211: /*@
5212:    MatSetOption - Sets a parameter option for a matrix. Some options
5213:    may be specific to certain storage formats.  Some options
5214:    determine how values will be inserted (or added). Sorted,
5215:    row-oriented input will generally assemble the fastest. The default
5216:    is row-oriented.

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

5220:    Input Parameters:
5221: +  mat - the matrix
5222: .  option - the option, one of those listed below (and possibly others),
5223: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5225:   Options Describing Matrix Structure:
5226: +    MAT_SPD - symmetric positive definite
5227: .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5228: .    MAT_HERMITIAN - transpose is the complex conjugation
5229: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5230: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5231:                             you set to be kept with all future use of the matrix
5232:                             including after MatAssemblyBegin/End() which could
5233:                             potentially change the symmetry structure, i.e. you
5234:                             KNOW the matrix will ALWAYS have the property you set.


5237:    Options For Use with MatSetValues():
5238:    Insert a logically dense subblock, which can be
5239: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

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

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

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

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

5277:    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5278:    that would generate a new entry in the nonzero structure instead produces
5279:    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

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

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

5293:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5294:    searches during matrix assembly. When this flag is set, the hash table
5295:    is created during the first Matrix Assembly. This hash table is
5296:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5297:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5298:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5299:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5317:    Level: intermediate

5319:    Concepts: matrices^setting options

5321: .seealso:  MatOption, Mat

5323: @*/
5324: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5325: {

5331:   if (op > 0) {
5334:   }

5336:   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);
5337:   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()");

5339:   switch (op) {
5340:   case MAT_NO_OFF_PROC_ENTRIES:
5341:     mat->nooffprocentries = flg;
5342:     return(0);
5343:     break;
5344:   case MAT_SUBSET_OFF_PROC_ENTRIES:
5345:     mat->subsetoffprocentries = flg;
5346:     return(0);
5347:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5348:     mat->nooffproczerorows = flg;
5349:     return(0);
5350:     break;
5351:   case MAT_SPD:
5352:     mat->spd_set = PETSC_TRUE;
5353:     mat->spd     = flg;
5354:     if (flg) {
5355:       mat->symmetric                  = PETSC_TRUE;
5356:       mat->structurally_symmetric     = PETSC_TRUE;
5357:       mat->symmetric_set              = PETSC_TRUE;
5358:       mat->structurally_symmetric_set = PETSC_TRUE;
5359:     }
5360:     break;
5361:   case MAT_SYMMETRIC:
5362:     mat->symmetric = flg;
5363:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5364:     mat->symmetric_set              = PETSC_TRUE;
5365:     mat->structurally_symmetric_set = flg;
5366:     break;
5367:   case MAT_HERMITIAN:
5368:     mat->hermitian = flg;
5369:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5370:     mat->hermitian_set              = PETSC_TRUE;
5371:     mat->structurally_symmetric_set = flg;
5372:     break;
5373:   case MAT_STRUCTURALLY_SYMMETRIC:
5374:     mat->structurally_symmetric     = flg;
5375:     mat->structurally_symmetric_set = PETSC_TRUE;
5376:     break;
5377:   case MAT_SYMMETRY_ETERNAL:
5378:     mat->symmetric_eternal = flg;
5379:     break;
5380:   default:
5381:     break;
5382:   }
5383:   if (mat->ops->setoption) {
5384:     (*mat->ops->setoption)(mat,op,flg);
5385:   }
5386:   return(0);
5387: }

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

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

5394:    Input Parameters:
5395: +  mat - the matrix
5396: -  option - the option, this only responds to certain options, check the code for which ones

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

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

5403:    Level: intermediate

5405:    Concepts: matrices^setting options

5407: .seealso:  MatOption, MatSetOption()

5409: @*/
5410: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5411: {

5416:   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);
5417:   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()");

5419:   switch (op) {
5420:   case MAT_NO_OFF_PROC_ENTRIES:
5421:     *flg = mat->nooffprocentries;
5422:     break;
5423:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5424:     *flg = mat->nooffproczerorows;
5425:     break;
5426:   case MAT_SYMMETRIC:
5427:     *flg = mat->symmetric;
5428:     break;
5429:   case MAT_HERMITIAN:
5430:     *flg = mat->hermitian;
5431:     break;
5432:   case MAT_STRUCTURALLY_SYMMETRIC:
5433:     *flg = mat->structurally_symmetric;
5434:     break;
5435:   case MAT_SYMMETRY_ETERNAL:
5436:     *flg = mat->symmetric_eternal;
5437:     break;
5438:   default:
5439:     break;
5440:   }
5441:   return(0);
5442: }

5444: /*@
5445:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5446:    this routine retains the old nonzero structure.

5448:    Logically Collective on Mat

5450:    Input Parameters:
5451: .  mat - the matrix

5453:    Level: intermediate

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

5458:    Concepts: matrices^zeroing

5460: .seealso: MatZeroRows()
5461: @*/
5462: PetscErrorCode MatZeroEntries(Mat mat)
5463: {

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

5474:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5475:   (*mat->ops->zeroentries)(mat);
5476:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5477:   PetscObjectStateIncrease((PetscObject)mat);
5478: #if defined(PETSC_HAVE_CUSP)
5479:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5480:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5481:   }
5482: #elif defined(PETSC_HAVE_VIENNACL)
5483:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5484:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5485:   }
5486: #elif defined(PETSC_HAVE_VECCUDA)
5487:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5488:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5489:   }
5490: #endif
5491:   return(0);
5492: }

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

5498:    Collective on Mat

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

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

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

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

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

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

5525:    Level: intermediate

5527:    Concepts: matrices^zeroing rows

5529: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5530: @*/
5531: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5532: {

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

5544:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5545:   MatViewFromOptions(mat,NULL,"-mat_view");
5546:   PetscObjectStateIncrease((PetscObject)mat);
5547: #if defined(PETSC_HAVE_CUSP)
5548:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5549:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5550:   }
5551: #elif defined(PETSC_HAVE_VIENNACL)
5552:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5553:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5554:   }
5555: #elif defined(PETSC_HAVE_VECCUDA)
5556:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5557:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5558:   }
5559: #endif
5560:   return(0);
5561: }

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

5567:    Collective on Mat

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

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

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

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

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

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

5593:    Level: intermediate

5595:    Concepts: matrices^zeroing rows

5597: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5598: @*/
5599: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5600: {
5602:   PetscInt       numRows;
5603:   const PetscInt *rows;

5610:   ISGetLocalSize(is,&numRows);
5611:   ISGetIndices(is,&rows);
5612:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5613:   ISRestoreIndices(is,&rows);
5614:   return(0);
5615: }

5617: /*@C
5618:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5619:    of a set of rows of a matrix.

5621:    Collective on Mat

5623:    Input Parameters:
5624: +  mat - the matrix
5625: .  numRows - the number of rows to remove
5626: .  rows - the global row indices
5627: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5628: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5629: -  b - optional vector of right hand side, that will be adjusted by provided solution

5631:    Notes:
5632:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5633:    but does not release memory.  For the dense and block diagonal
5634:    formats this does not alter the nonzero structure.

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

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

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

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

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

5655:    Level: intermediate

5657:    Concepts: matrices^zeroing rows

5659: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5660: @*/
5661: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5662: {

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

5674:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5675:   MatViewFromOptions(mat,NULL,"-mat_view");
5676:   PetscObjectStateIncrease((PetscObject)mat);
5677: #if defined(PETSC_HAVE_CUSP)
5678:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5679:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5680:   }
5681: #elif defined(PETSC_HAVE_VIENNACL)
5682:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5683:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5684:   }
5685: #elif defined(PETSC_HAVE_VECCUDA)
5686:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5687:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5688:   }
5689: #endif
5690:   return(0);
5691: }

5693: /*@C
5694:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5695:    of a set of rows of a matrix.

5697:    Collective on Mat

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

5706:    Notes:
5707:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5708:    but does not release memory.  For the dense and block diagonal
5709:    formats this does not alter the nonzero structure.

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

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

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

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

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

5730:    Level: intermediate

5732:    Concepts: matrices^zeroing rows

5734: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5735: @*/
5736: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5737: {
5738:   PetscInt       numRows;
5739:   const PetscInt *rows;

5746:   ISGetLocalSize(is,&numRows);
5747:   ISGetIndices(is,&rows);
5748:   MatZeroRows(mat,numRows,rows,diag,x,b);
5749:   ISRestoreIndices(is,&rows);
5750:   return(0);
5751: }

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

5757:    Collective on Mat

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

5767:    Notes:
5768:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5769:    but does not release memory.  For the dense and block diagonal
5770:    formats this does not alter the nonzero structure.

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

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

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

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

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

5790:    In Fortran idxm and idxn should be declared as
5791: $     MatStencil idxm(4,m)
5792:    and the values inserted using
5793: $    idxm(MatStencil_i,1) = i
5794: $    idxm(MatStencil_j,1) = j
5795: $    idxm(MatStencil_k,1) = k
5796: $    idxm(MatStencil_c,1) = c
5797:    etc

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

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

5807:    Level: intermediate

5809:    Concepts: matrices^zeroing rows

5811: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5812: @*/
5813: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5814: {
5815:   PetscInt       dim     = mat->stencil.dim;
5816:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5817:   PetscInt       *dims   = mat->stencil.dims+1;
5818:   PetscInt       *starts = mat->stencil.starts;
5819:   PetscInt       *dxm    = (PetscInt*) rows;
5820:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5828:   PetscMalloc1(numRows, &jdxm);
5829:   for (i = 0; i < numRows; ++i) {
5830:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5831:     for (j = 0; j < 3-sdim; ++j) dxm++;
5832:     /* Local index in X dir */
5833:     tmp = *dxm++ - starts[0];
5834:     /* Loop over remaining dimensions */
5835:     for (j = 0; j < dim-1; ++j) {
5836:       /* If nonlocal, set index to be negative */
5837:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5838:       /* Update local index */
5839:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5840:     }
5841:     /* Skip component slot if necessary */
5842:     if (mat->stencil.noc) dxm++;
5843:     /* Local row number */
5844:     if (tmp >= 0) {
5845:       jdxm[numNewRows++] = tmp;
5846:     }
5847:   }
5848:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5849:   PetscFree(jdxm);
5850:   return(0);
5851: }

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

5857:    Collective on Mat

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

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

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

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

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

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

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

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

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

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

5907:    Level: intermediate

5909:    Concepts: matrices^zeroing rows

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


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

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

5957:    Collective on Mat

5959:    Input Parameters:
5960: +  mat - the matrix
5961: .  numRows - the number of rows to remove
5962: .  rows - the global row indices
5963: .  diag - value put in all diagonals of eliminated rows
5964: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5965: -  b - optional vector of right hand side, that will be adjusted by provided solution

5967:    Notes:
5968:    Before calling MatZeroRowsLocal(), the user must first set the
5969:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5971:    For the AIJ matrix formats this removes the old nonzero structure,
5972:    but does not release memory.  For the dense and block diagonal
5973:    formats this does not alter the nonzero structure.

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

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

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

5986:    Level: intermediate

5988:    Concepts: matrices^zeroing

5990: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5991: @*/
5992: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5993: {

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

6004:   if (mat->ops->zerorowslocal) {
6005:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6006:   } else {
6007:     IS             is, newis;
6008:     const PetscInt *newRows;

6010:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6011:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6012:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6013:     ISGetIndices(newis,&newRows);
6014:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6015:     ISRestoreIndices(newis,&newRows);
6016:     ISDestroy(&newis);
6017:     ISDestroy(&is);
6018:   }
6019:   PetscObjectStateIncrease((PetscObject)mat);
6020: #if defined(PETSC_HAVE_CUSP)
6021:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6022:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6023:   }
6024: #elif defined(PETSC_HAVE_VIENNACL)
6025:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6026:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6027:   }
6028: #elif defined(PETSC_HAVE_VECCUDA)
6029:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6030:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6031:   }
6032: #endif
6033:   return(0);
6034: }

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

6040:    Collective on Mat

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

6049:    Notes:
6050:    Before calling MatZeroRowsLocalIS(), the user must first set the
6051:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6053:    For the AIJ matrix formats this removes the old nonzero structure,
6054:    but does not release memory.  For the dense and block diagonal
6055:    formats this does not alter the nonzero structure.

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

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

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

6068:    Level: intermediate

6070:    Concepts: matrices^zeroing

6072: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6073: @*/
6074: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6075: {
6077:   PetscInt       numRows;
6078:   const PetscInt *rows;

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

6088:   ISGetLocalSize(is,&numRows);
6089:   ISGetIndices(is,&rows);
6090:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6091:   ISRestoreIndices(is,&rows);
6092:   return(0);
6093: }

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

6099:    Collective on Mat

6101:    Input Parameters:
6102: +  mat - the matrix
6103: .  numRows - the number of rows to remove
6104: .  rows - the global row indices
6105: .  diag - value put in all diagonals of eliminated rows
6106: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6107: -  b - optional vector of right hand side, that will be adjusted by provided solution

6109:    Notes:
6110:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6111:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6117:    Level: intermediate

6119:    Concepts: matrices^zeroing

6121: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6122: @*/
6123: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6124: {
6126:   IS             is, newis;
6127:   const PetscInt *newRows;

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

6137:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6138:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6139:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6140:   ISGetIndices(newis,&newRows);
6141:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6142:   ISRestoreIndices(newis,&newRows);
6143:   ISDestroy(&newis);
6144:   ISDestroy(&is);
6145:   PetscObjectStateIncrease((PetscObject)mat);
6146: #if defined(PETSC_HAVE_CUSP)
6147:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6148:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6149:   }
6150: #elif defined(PETSC_HAVE_VIENNACL)
6151:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6152:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6153:   }
6154: #elif defined(PETSC_HAVE_VECCUDA)
6155:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6156:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6157:   }
6158: #endif
6159:   return(0);
6160: }

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

6166:    Collective on Mat

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

6175:    Notes:
6176:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6177:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6183:    Level: intermediate

6185:    Concepts: matrices^zeroing

6187: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6188: @*/
6189: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6190: {
6192:   PetscInt       numRows;
6193:   const PetscInt *rows;

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

6203:   ISGetLocalSize(is,&numRows);
6204:   ISGetIndices(is,&rows);
6205:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6206:   ISRestoreIndices(is,&rows);
6207:   return(0);
6208: }

6210: /*@C
6211:    MatGetSize - Returns the numbers of rows and columns in a matrix.

6213:    Not Collective

6215:    Input Parameter:
6216: .  mat - the matrix

6218:    Output Parameters:
6219: +  m - the number of global rows
6220: -  n - the number of global columns

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

6224:    Level: beginner

6226:    Concepts: matrices^size

6228: .seealso: MatGetLocalSize()
6229: @*/
6230: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6231: {
6234:   if (m) *m = mat->rmap->N;
6235:   if (n) *n = mat->cmap->N;
6236:   return(0);
6237: }

6239: /*@C
6240:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6241:    stored locally.  This information may be implementation dependent, so
6242:    use with care.

6244:    Not Collective

6246:    Input Parameters:
6247: .  mat - the matrix

6249:    Output Parameters:
6250: +  m - the number of local rows
6251: -  n - the number of local columns

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

6255:    Level: beginner

6257:    Concepts: matrices^local size

6259: .seealso: MatGetSize()
6260: @*/
6261: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6262: {
6267:   if (m) *m = mat->rmap->n;
6268:   if (n) *n = mat->cmap->n;
6269:   return(0);
6270: }

6272: /*@
6273:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6274:    this processor. (The columns of the "diagonal block")

6276:    Not Collective, unless matrix has not been allocated, then collective on Mat

6278:    Input Parameters:
6279: .  mat - the matrix

6281:    Output Parameters:
6282: +  m - the global index of the first local column
6283: -  n - one more than the global index of the last local column

6285:    Notes: both output parameters can be NULL on input.

6287:    Level: developer

6289:    Concepts: matrices^column ownership

6291: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

6293: @*/
6294: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6295: {
6301:   MatCheckPreallocated(mat,1);
6302:   if (m) *m = mat->cmap->rstart;
6303:   if (n) *n = mat->cmap->rend;
6304:   return(0);
6305: }

6307: /*@
6308:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6309:    this processor, assuming that the matrix is laid out with the first
6310:    n1 rows on the first processor, the next n2 rows on the second, etc.
6311:    For certain parallel layouts this range may not be well defined.

6313:    Not Collective

6315:    Input Parameters:
6316: .  mat - the matrix

6318:    Output Parameters:
6319: +  m - the global index of the first local row
6320: -  n - one more than the global index of the last local row

6322:    Note: Both output parameters can be NULL on input.
6323: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6324: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6325: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

6327:    Level: beginner

6329:    Concepts: matrices^row ownership

6331: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

6333: @*/
6334: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6335: {
6341:   MatCheckPreallocated(mat,1);
6342:   if (m) *m = mat->rmap->rstart;
6343:   if (n) *n = mat->rmap->rend;
6344:   return(0);
6345: }

6347: /*@C
6348:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6349:    each process

6351:    Not Collective, unless matrix has not been allocated, then collective on Mat

6353:    Input Parameters:
6354: .  mat - the matrix

6356:    Output Parameters:
6357: .  ranges - start of each processors portion plus one more than the total length at the end

6359:    Level: beginner

6361:    Concepts: matrices^row ownership

6363: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6365: @*/
6366: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6367: {

6373:   MatCheckPreallocated(mat,1);
6374:   PetscLayoutGetRanges(mat->rmap,ranges);
6375:   return(0);
6376: }

6378: /*@C
6379:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6380:    this processor. (The columns of the "diagonal blocks" for each process)

6382:    Not Collective, unless matrix has not been allocated, then collective on Mat

6384:    Input Parameters:
6385: .  mat - the matrix

6387:    Output Parameters:
6388: .  ranges - start of each processors portion plus one more then the total length at the end

6390:    Level: beginner

6392:    Concepts: matrices^column ownership

6394: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6396: @*/
6397: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6398: {

6404:   MatCheckPreallocated(mat,1);
6405:   PetscLayoutGetRanges(mat->cmap,ranges);
6406:   return(0);
6407: }

6409: /*@C
6410:    MatGetOwnershipIS - Get row and column ownership as index sets

6412:    Not Collective

6414:    Input Arguments:
6415: .  A - matrix of type Elemental

6417:    Output Arguments:
6418: +  rows - rows in which this process owns elements
6419: .  cols - columns in which this process owns elements

6421:    Level: intermediate

6423: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6424: @*/
6425: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6426: {
6427:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6430:   MatCheckPreallocated(A,1);
6431:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6432:   if (f) {
6433:     (*f)(A,rows,cols);
6434:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6435:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6436:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6437:   }
6438:   return(0);
6439: }

6441: /*@C
6442:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6443:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6444:    to complete the factorization.

6446:    Collective on Mat

6448:    Input Parameters:
6449: +  mat - the matrix
6450: .  row - row permutation
6451: .  column - column permutation
6452: -  info - structure containing
6453: $      levels - number of levels of fill.
6454: $      expected fill - as ratio of original fill.
6455: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6456:                 missing diagonal entries)

6458:    Output Parameters:
6459: .  fact - new matrix that has been symbolically factored

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

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

6467:    Level: developer

6469:   Concepts: matrices^symbolic LU factorization
6470:   Concepts: matrices^factorization
6471:   Concepts: LU^symbolic factorization

6473: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6474:           MatGetOrdering(), MatFactorInfo

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

6479: @*/
6480: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6481: {

6491:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6492:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6493:   if (!(fact)->ops->ilufactorsymbolic) {
6494:     const MatSolverPackage spackage;
6495:     MatFactorGetSolverPackage(fact,&spackage);
6496:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6497:   }
6498:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6499:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6500:   MatCheckPreallocated(mat,2);

6502:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6503:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6504:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6505:   return(0);
6506: }

6508: /*@C
6509:    MatICCFactorSymbolic - Performs symbolic incomplete
6510:    Cholesky factorization for a symmetric matrix.  Use
6511:    MatCholeskyFactorNumeric() to complete the factorization.

6513:    Collective on Mat

6515:    Input Parameters:
6516: +  mat - the matrix
6517: .  perm - row and column permutation
6518: -  info - structure containing
6519: $      levels - number of levels of fill.
6520: $      expected fill - as ratio of original fill.

6522:    Output Parameter:
6523: .  fact - the factored matrix

6525:    Notes:
6526:    Most users should employ the KSP interface for linear solvers
6527:    instead of working directly with matrix algebra routines such as this.
6528:    See, e.g., KSPCreate().

6530:    Level: developer

6532:   Concepts: matrices^symbolic incomplete Cholesky factorization
6533:   Concepts: matrices^factorization
6534:   Concepts: Cholsky^symbolic factorization

6536: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

6541: @*/
6542: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6543: {

6552:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6553:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6554:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6555:   if (!(fact)->ops->iccfactorsymbolic) {
6556:     const MatSolverPackage spackage;
6557:     MatFactorGetSolverPackage(fact,&spackage);
6558:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6559:   }
6560:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6561:   MatCheckPreallocated(mat,2);

6563:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6564:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6565:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6566:   return(0);
6567: }

6569: /*@C
6570:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6571:    points to an array of valid matrices, they may be reused to store the new
6572:    submatrices.

6574:    Collective on Mat

6576:    Input Parameters:
6577: +  mat - the matrix
6578: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6579: .  irow, icol - index sets of rows and columns to extract
6580: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6582:    Output Parameter:
6583: .  submat - the array of submatrices

6585:    Notes:
6586:    MatGetSubMatrices() can extract ONLY sequential submatrices
6587:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6588:    to extract a parallel submatrix.

6590:    Some matrix types place restrictions on the row and column
6591:    indices, such as that they be sorted or that they be equal to each other.

6593:    The index sets may not have duplicate entries.

6595:    When extracting submatrices from a parallel matrix, each processor can
6596:    form a different submatrix by setting the rows and columns of its
6597:    individual index sets according to the local submatrix desired.

6599:    When finished using the submatrices, the user should destroy
6600:    them with MatDestroyMatrices().

6602:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6603:    original matrix has not changed from that last call to MatGetSubMatrices().

6605:    This routine creates the matrices in submat; you should NOT create them before
6606:    calling it. It also allocates the array of matrix pointers submat.

6608:    For BAIJ matrices the index sets must respect the block structure, that is if they
6609:    request one row/column in a block, they must request all rows/columns that are in
6610:    that block. For example, if the block size is 2 you cannot request just row 0 and
6611:    column 0.

6613:    Fortran Note:
6614:    The Fortran interface is slightly different from that given below; it
6615:    requires one to pass in  as submat a Mat (integer) array of size at least m.

6617:    Level: advanced

6619:    Concepts: matrices^accessing submatrices
6620:    Concepts: submatrices

6622: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6623: @*/
6624: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6625: {
6627:   PetscInt       i;
6628:   PetscBool      eq;

6633:   if (n) {
6638:   }
6640:   if (n && scall == MAT_REUSE_MATRIX) {
6643:   }
6644:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6645:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6646:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6647:   MatCheckPreallocated(mat,1);

6649:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6650:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6651:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6652:   for (i=0; i<n; i++) {
6653:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6654:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6655:       ISEqual(irow[i],icol[i],&eq);
6656:       if (eq) {
6657:         if (mat->symmetric) {
6658:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6659:         } else if (mat->hermitian) {
6660:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6661:         } else if (mat->structurally_symmetric) {
6662:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6663:         }
6664:       }
6665:     }
6666:   }
6667:   return(0);
6668: }

6670: PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6671: {
6673:   PetscInt       i;
6674:   PetscBool      eq;

6679:   if (n) {
6684:   }
6686:   if (n && scall == MAT_REUSE_MATRIX) {
6689:   }
6690:   if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6691:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6692:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6693:   MatCheckPreallocated(mat,1);

6695:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6696:   (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6697:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6698:   for (i=0; i<n; i++) {
6699:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6700:       ISEqual(irow[i],icol[i],&eq);
6701:       if (eq) {
6702:         if (mat->symmetric) {
6703:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6704:         } else if (mat->hermitian) {
6705:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6706:         } else if (mat->structurally_symmetric) {
6707:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6708:         }
6709:       }
6710:     }
6711:   }
6712:   return(0);
6713: }

6715: /*@C
6716:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().

6718:    Collective on Mat

6720:    Input Parameters:
6721: +  n - the number of local matrices
6722: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6723:                        sequence of MatGetSubMatrices())

6725:    Level: advanced

6727:     Notes: Frees not only the matrices, but also the array that contains the matrices
6728:            In Fortran will not free the array.

6730: .seealso: MatGetSubMatrices()
6731: @*/
6732: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6733: {
6735:   PetscInt       i;

6738:   if (!*mat) return(0);
6739:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6741:   for (i=0; i<n; i++) {
6742:     MatDestroy(&(*mat)[i]);
6743:   }
6744:   /* memory is allocated even if n = 0 */
6745:   PetscFree(*mat);
6746:   *mat = NULL;
6747:   return(0);
6748: }

6750: /*@C
6751:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.

6753:    Collective on Mat

6755:    Input Parameters:
6756: .  mat - the matrix

6758:    Output Parameter:
6759: .  matstruct - the sequential matrix with the nonzero structure of mat

6761:   Level: intermediate

6763: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6764: @*/
6765: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6766: {


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

6777:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6778:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6779:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6780:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6781:   return(0);
6782: }

6784: /*@C
6785:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6787:    Collective on Mat

6789:    Input Parameters:
6790: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6791:                        sequence of MatGetSequentialNonzeroStructure())

6793:    Level: advanced

6795:     Notes: Frees not only the matrices, but also the array that contains the matrices

6797: .seealso: MatGetSeqNonzeroStructure()
6798: @*/
6799: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6800: {

6805:   MatDestroy(mat);
6806:   return(0);
6807: }

6809: /*@
6810:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6811:    replaces the index sets by larger ones that represent submatrices with
6812:    additional overlap.

6814:    Collective on Mat

6816:    Input Parameters:
6817: +  mat - the matrix
6818: .  n   - the number of index sets
6819: .  is  - the array of index sets (these index sets will changed during the call)
6820: -  ov  - the additional overlap requested

6822:    Options Database:
6823: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

6825:    Level: developer

6827:    Concepts: overlap
6828:    Concepts: ASM^computing overlap

6830: .seealso: MatGetSubMatrices()
6831: @*/
6832: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6833: {

6839:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6840:   if (n) {
6843:   }
6844:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6845:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6846:   MatCheckPreallocated(mat,1);

6848:   if (!ov) return(0);
6849:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6850:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6851:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6852:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6853:   return(0);
6854: }


6857: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);

6859: /*@
6860:    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6861:    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6862:    additional overlap.

6864:    Collective on Mat

6866:    Input Parameters:
6867: +  mat - the matrix
6868: .  n   - the number of index sets
6869: .  is  - the array of index sets (these index sets will changed during the call)
6870: -  ov  - the additional overlap requested

6872:    Options Database:
6873: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

6875:    Level: developer

6877:    Concepts: overlap
6878:    Concepts: ASM^computing overlap

6880: .seealso: MatGetSubMatrices()
6881: @*/
6882: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6883: {
6884:   PetscInt       i;

6890:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6891:   if (n) {
6894:   }
6895:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6896:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6897:   MatCheckPreallocated(mat,1);
6898:   if (!ov) return(0);
6899:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6900:   for(i=0; i<n; i++){
6901:          MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
6902:   }
6903:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6904:   return(0);
6905: }




6910: /*@
6911:    MatGetBlockSize - Returns the matrix block size.

6913:    Not Collective

6915:    Input Parameter:
6916: .  mat - the matrix

6918:    Output Parameter:
6919: .  bs - block size

6921:    Notes:
6922:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

6924:    If the block size has not been set yet this routine returns 1.

6926:    Level: intermediate

6928:    Concepts: matrices^block size

6930: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6931: @*/
6932: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
6933: {
6937:   *bs = PetscAbs(mat->rmap->bs);
6938:   return(0);
6939: }

6941: /*@
6942:    MatGetBlockSizes - Returns the matrix block row and column sizes.

6944:    Not Collective

6946:    Input Parameter:
6947: .  mat - the matrix

6949:    Output Parameter:
6950: .  rbs - row block size
6951: .  cbs - coumn block size

6953:    Notes:
6954:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6955:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

6957:    If a block size has not been set yet this routine returns 1.

6959:    Level: intermediate

6961:    Concepts: matrices^block size

6963: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
6964: @*/
6965: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6966: {
6971:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
6972:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
6973:   return(0);
6974: }

6976: /*@
6977:    MatSetBlockSize - Sets the matrix block size.

6979:    Logically Collective on Mat

6981:    Input Parameters:
6982: +  mat - the matrix
6983: -  bs - block size

6985:    Notes:
6986:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6987:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.

6989:     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
6990:     is compatible with the matrix local sizes.

6992:    Level: intermediate

6994:    Concepts: matrices^block size

6996: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
6997: @*/
6998: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
6999: {

7005:   MatSetBlockSizes(mat,bs,bs);
7006:   return(0);
7007: }

7009: /*@
7010:    MatSetBlockSizes - Sets the matrix block row and column sizes.

7012:    Logically Collective on Mat

7014:    Input Parameters:
7015: +  mat - the matrix
7016: -  rbs - row block size
7017: -  cbs - column block size

7019:    Notes:
7020:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7021:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7022:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

7024:     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7025:     are compatible with the matrix local sizes.

7027:     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().

7029:    Level: intermediate

7031:    Concepts: matrices^block size

7033: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7034: @*/
7035: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7036: {

7043:   if (mat->ops->setblocksizes) {
7044:     (*mat->ops->setblocksizes)(mat,rbs,cbs);
7045:   }
7046:   if (mat->rmap->refcnt) {
7047:     ISLocalToGlobalMapping l2g = NULL;
7048:     PetscLayout            nmap = NULL;

7050:     PetscLayoutDuplicate(mat->rmap,&nmap);
7051:     if (mat->rmap->mapping) {
7052:       ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);
7053:     }
7054:     PetscLayoutDestroy(&mat->rmap);
7055:     mat->rmap = nmap;
7056:     mat->rmap->mapping = l2g;
7057:   }
7058:   if (mat->cmap->refcnt) {
7059:     ISLocalToGlobalMapping l2g = NULL;
7060:     PetscLayout            nmap = NULL;

7062:     PetscLayoutDuplicate(mat->cmap,&nmap);
7063:     if (mat->cmap->mapping) {
7064:       ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);
7065:     }
7066:     PetscLayoutDestroy(&mat->cmap);
7067:     mat->cmap = nmap;
7068:     mat->cmap->mapping = l2g;
7069:   }
7070:   PetscLayoutSetBlockSize(mat->rmap,rbs);
7071:   PetscLayoutSetBlockSize(mat->cmap,cbs);
7072:   return(0);
7073: }

7075: /*@
7076:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

7078:    Logically Collective on Mat

7080:    Input Parameters:
7081: +  mat - the matrix
7082: .  fromRow - matrix from which to copy row block size
7083: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

7085:    Level: developer

7087:    Concepts: matrices^block size

7089: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7090: @*/
7091: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7092: {

7099:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7100:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7101:   return(0);
7102: }

7104: /*@
7105:    MatResidual - Default routine to calculate the residual.

7107:    Collective on Mat and Vec

7109:    Input Parameters:
7110: +  mat - the matrix
7111: .  b   - the right-hand-side
7112: -  x   - the approximate solution

7114:    Output Parameter:
7115: .  r - location to store the residual

7117:    Level: developer

7119: .keywords: MG, default, multigrid, residual

7121: .seealso: PCMGSetResidual()
7122: @*/
7123: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7124: {

7133:   MatCheckPreallocated(mat,1);
7134:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7135:   if (!mat->ops->residual) {
7136:     MatMult(mat,x,r);
7137:     VecAYPX(r,-1.0,b);
7138:   } else {
7139:     (*mat->ops->residual)(mat,b,x,r);
7140:   }
7141:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7142:   return(0);
7143: }

7145: /*@C
7146:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.

7148:    Collective on Mat

7150:     Input Parameters:
7151: +   mat - the matrix
7152: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7153: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7154: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7155:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7156:                  always used.

7158:     Output Parameters:
7159: +   n - number of rows in the (possibly compressed) matrix
7160: .   ia - the row pointers [of length n+1]
7161: .   ja - the column indices
7162: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7163:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

7165:     Level: developer

7167:     Notes: You CANNOT change any of the ia[] or ja[] values.

7169:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

7171:     Fortran Node

7173:            In Fortran use
7174: $           PetscInt ia(1), ja(1)
7175: $           PetscOffset iia, jja
7176: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7177: $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7178: $
7179: $          or
7180: $
7181: $           PetscInt, pointer :: ia(:),ja(:)
7182: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7183: $      Acess the ith and jth entries via ia(i) and ja(j)



7187: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7188: @*/
7189: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7190: {

7200:   MatCheckPreallocated(mat,1);
7201:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7202:   else {
7203:     *done = PETSC_TRUE;
7204:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7205:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7206:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7207:   }
7208:   return(0);
7209: }

7211: /*@C
7212:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.

7214:     Collective on Mat

7216:     Input Parameters:
7217: +   mat - the matrix
7218: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7219: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7220:                 symmetrized
7221: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7222:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7223:                  always used.
7224: .   n - number of columns in the (possibly compressed) matrix
7225: .   ia - the column pointers
7226: -   ja - the row indices

7228:     Output Parameters:
7229: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

7231:     Note:
7232:     This routine zeros out n, ia, and ja. This is to prevent accidental
7233:     us of the array after it has been restored. If you pass NULL, it will
7234:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

7236:     Level: developer

7238: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7239: @*/
7240: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7241: {

7251:   MatCheckPreallocated(mat,1);
7252:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7253:   else {
7254:     *done = PETSC_TRUE;
7255:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7256:   }
7257:   return(0);
7258: }

7260: /*@C
7261:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7262:     MatGetRowIJ().

7264:     Collective on Mat

7266:     Input Parameters:
7267: +   mat - the matrix
7268: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7269: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7270:                 symmetrized
7271: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7272:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7273:                  always used.
7274: .   n - size of (possibly compressed) matrix
7275: .   ia - the row pointers
7276: -   ja - the column indices

7278:     Output Parameters:
7279: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7281:     Note:
7282:     This routine zeros out n, ia, and ja. This is to prevent accidental
7283:     us of the array after it has been restored. If you pass NULL, it will
7284:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

7286:     Level: developer

7288: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7289: @*/
7290: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7291: {

7300:   MatCheckPreallocated(mat,1);

7302:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7303:   else {
7304:     *done = PETSC_TRUE;
7305:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7306:     if (n)  *n = 0;
7307:     if (ia) *ia = NULL;
7308:     if (ja) *ja = NULL;
7309:   }
7310:   return(0);
7311: }

7313: /*@C
7314:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7315:     MatGetColumnIJ().

7317:     Collective on Mat

7319:     Input Parameters:
7320: +   mat - the matrix
7321: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7322: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7323:                 symmetrized
7324: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7325:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7326:                  always used.

7328:     Output Parameters:
7329: +   n - size of (possibly compressed) matrix
7330: .   ia - the column pointers
7331: .   ja - the row indices
7332: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7334:     Level: developer

7336: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7337: @*/
7338: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7339: {

7348:   MatCheckPreallocated(mat,1);

7350:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7351:   else {
7352:     *done = PETSC_TRUE;
7353:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7354:     if (n)  *n = 0;
7355:     if (ia) *ia = NULL;
7356:     if (ja) *ja = NULL;
7357:   }
7358:   return(0);
7359: }

7361: /*@C
7362:     MatColoringPatch -Used inside matrix coloring routines that
7363:     use MatGetRowIJ() and/or MatGetColumnIJ().

7365:     Collective on Mat

7367:     Input Parameters:
7368: +   mat - the matrix
7369: .   ncolors - max color value
7370: .   n   - number of entries in colorarray
7371: -   colorarray - array indicating color for each column

7373:     Output Parameters:
7374: .   iscoloring - coloring generated using colorarray information

7376:     Level: developer

7378: .seealso: MatGetRowIJ(), MatGetColumnIJ()

7380: @*/
7381: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7382: {

7390:   MatCheckPreallocated(mat,1);

7392:   if (!mat->ops->coloringpatch) {
7393:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7394:   } else {
7395:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7396:   }
7397:   return(0);
7398: }


7401: /*@
7402:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.

7404:    Logically Collective on Mat

7406:    Input Parameter:
7407: .  mat - the factored matrix to be reset

7409:    Notes:
7410:    This routine should be used only with factored matrices formed by in-place
7411:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7412:    format).  This option can save memory, for example, when solving nonlinear
7413:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7414:    ILU(0) preconditioner.

7416:    Note that one can specify in-place ILU(0) factorization by calling
7417: .vb
7418:      PCType(pc,PCILU);
7419:      PCFactorSeUseInPlace(pc);
7420: .ve
7421:    or by using the options -pc_type ilu -pc_factor_in_place

7423:    In-place factorization ILU(0) can also be used as a local
7424:    solver for the blocks within the block Jacobi or additive Schwarz
7425:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7426:    for details on setting local solver options.

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

7432:    Level: developer

7434: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()

7436:    Concepts: matrices^unfactored

7438: @*/
7439: PetscErrorCode MatSetUnfactored(Mat mat)
7440: {

7446:   MatCheckPreallocated(mat,1);
7447:   mat->factortype = MAT_FACTOR_NONE;
7448:   if (!mat->ops->setunfactored) return(0);
7449:   (*mat->ops->setunfactored)(mat);
7450:   return(0);
7451: }

7453: /*MC
7454:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7456:     Synopsis:
7457:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7459:     Not collective

7461:     Input Parameter:
7462: .   x - matrix

7464:     Output Parameters:
7465: +   xx_v - the Fortran90 pointer to the array
7466: -   ierr - error code

7468:     Example of Usage:
7469: .vb
7470:       PetscScalar, pointer xx_v(:,:)
7471:       ....
7472:       call MatDenseGetArrayF90(x,xx_v,ierr)
7473:       a = xx_v(3)
7474:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7475: .ve

7477:     Level: advanced

7479: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()

7481:     Concepts: matrices^accessing array

7483: M*/

7485: /*MC
7486:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7487:     accessed with MatDenseGetArrayF90().

7489:     Synopsis:
7490:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7492:     Not collective

7494:     Input Parameters:
7495: +   x - matrix
7496: -   xx_v - the Fortran90 pointer to the array

7498:     Output Parameter:
7499: .   ierr - error code

7501:     Example of Usage:
7502: .vb
7503:        PetscScalar, pointer xx_v(:,:)
7504:        ....
7505:        call MatDenseGetArrayF90(x,xx_v,ierr)
7506:        a = xx_v(3)
7507:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7508: .ve

7510:     Level: advanced

7512: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()

7514: M*/


7517: /*MC
7518:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7520:     Synopsis:
7521:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7523:     Not collective

7525:     Input Parameter:
7526: .   x - matrix

7528:     Output Parameters:
7529: +   xx_v - the Fortran90 pointer to the array
7530: -   ierr - error code

7532:     Example of Usage:
7533: .vb
7534:       PetscScalar, pointer xx_v(:)
7535:       ....
7536:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7537:       a = xx_v(3)
7538:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7539: .ve

7541:     Level: advanced

7543: .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()

7545:     Concepts: matrices^accessing array

7547: M*/

7549: /*MC
7550:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7551:     accessed with MatSeqAIJGetArrayF90().

7553:     Synopsis:
7554:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7556:     Not collective

7558:     Input Parameters:
7559: +   x - matrix
7560: -   xx_v - the Fortran90 pointer to the array

7562:     Output Parameter:
7563: .   ierr - error code

7565:     Example of Usage:
7566: .vb
7567:        PetscScalar, pointer xx_v(:)
7568:        ....
7569:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7570:        a = xx_v(3)
7571:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7572: .ve

7574:     Level: advanced

7576: .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()

7578: M*/


7581: /*@
7582:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7583:                       as the original matrix.

7585:     Collective on Mat

7587:     Input Parameters:
7588: +   mat - the original matrix
7589: .   isrow - parallel IS containing the rows this processor should obtain
7590: .   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.
7591: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7593:     Output Parameter:
7594: .   newmat - the new submatrix, of the same type as the old

7596:     Level: advanced

7598:     Notes:
7599:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7601:     Some matrix types place restrictions on the row and column indices, such
7602:     as that they be sorted or that they be equal to each other.

7604:     The index sets may not have duplicate entries.

7606:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7607:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7608:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7609:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7610:    you are finished using it.

7612:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7613:     the input matrix.

7615:     If iscol is NULL then all columns are obtained (not supported in Fortran).

7617:    Example usage:
7618:    Consider the following 8x8 matrix with 34 non-zero values, that is
7619:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7620:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7621:    as follows:

7623: .vb
7624:             1  2  0  |  0  3  0  |  0  4
7625:     Proc0   0  5  6  |  7  0  0  |  8  0
7626:             9  0 10  | 11  0  0  | 12  0
7627:     -------------------------------------
7628:            13  0 14  | 15 16 17  |  0  0
7629:     Proc1   0 18  0  | 19 20 21  |  0  0
7630:             0  0  0  | 22 23  0  | 24  0
7631:     -------------------------------------
7632:     Proc2  25 26 27  |  0  0 28  | 29  0
7633:            30  0  0  | 31 32 33  |  0 34
7634: .ve

7636:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7638: .vb
7639:             2  0  |  0  3  0  |  0
7640:     Proc0   5  6  |  7  0  0  |  8
7641:     -------------------------------
7642:     Proc1  18  0  | 19 20 21  |  0
7643:     -------------------------------
7644:     Proc2  26 27  |  0  0 28  | 29
7645:             0  0  | 31 32 33  |  0
7646: .ve


7649:     Concepts: matrices^submatrices

7651: .seealso: MatGetSubMatrices()
7652: @*/
7653: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7654: {
7656:   PetscMPIInt    size;
7657:   Mat            *local;
7658:   IS             iscoltmp;

7667:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7668:   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");

7670:   MatCheckPreallocated(mat,1);
7671:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7673:   if (!iscol || isrow == iscol) {
7674:     PetscBool   stride;
7675:     PetscMPIInt grabentirematrix = 0,grab;
7676:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7677:     if (stride) {
7678:       PetscInt first,step,n,rstart,rend;
7679:       ISStrideGetInfo(isrow,&first,&step);
7680:       if (step == 1) {
7681:         MatGetOwnershipRange(mat,&rstart,&rend);
7682:         if (rstart == first) {
7683:           ISGetLocalSize(isrow,&n);
7684:           if (n == rend-rstart) {
7685:             grabentirematrix = 1;
7686:           }
7687:         }
7688:       }
7689:     }
7690:     MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7691:     if (grab) {
7692:       PetscInfo(mat,"Getting entire matrix as submatrix\n");
7693:       if (cll == MAT_INITIAL_MATRIX) {
7694:         *newmat = mat;
7695:         PetscObjectReference((PetscObject)mat);
7696:       }
7697:       return(0);
7698:     }
7699:   }

7701:   if (!iscol) {
7702:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7703:   } else {
7704:     iscoltmp = iscol;
7705:   }

7707:   /* if original matrix is on just one processor then use submatrix generated */
7708:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7709:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7710:     if (!iscol) {ISDestroy(&iscoltmp);}
7711:     return(0);
7712:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7713:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7714:     *newmat = *local;
7715:     PetscFree(local);
7716:     if (!iscol) {ISDestroy(&iscoltmp);}
7717:     return(0);
7718:   } else if (!mat->ops->getsubmatrix) {
7719:     /* Create a new matrix type that implements the operation using the full matrix */
7720:     PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7721:     switch (cll) {
7722:     case MAT_INITIAL_MATRIX:
7723:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7724:       break;
7725:     case MAT_REUSE_MATRIX:
7726:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7727:       break;
7728:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7729:     }
7730:     PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7731:     if (!iscol) {ISDestroy(&iscoltmp);}
7732:     return(0);
7733:   }

7735:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7736:   PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7737:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7738:   PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7739:   if (!iscol) {ISDestroy(&iscoltmp);}
7740:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7741:   return(0);
7742: }

7744: /*@
7745:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7746:    used during the assembly process to store values that belong to
7747:    other processors.

7749:    Not Collective

7751:    Input Parameters:
7752: +  mat   - the matrix
7753: .  size  - the initial size of the stash.
7754: -  bsize - the initial size of the block-stash(if used).

7756:    Options Database Keys:
7757: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7758: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7760:    Level: intermediate

7762:    Notes:
7763:      The block-stash is used for values set with MatSetValuesBlocked() while
7764:      the stash is used for values set with MatSetValues()

7766:      Run with the option -info and look for output of the form
7767:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7768:      to determine the appropriate value, MM, to use for size and
7769:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7770:      to determine the value, BMM to use for bsize

7772:    Concepts: stash^setting matrix size
7773:    Concepts: matrices^stash

7775: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7777: @*/
7778: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7779: {

7785:   MatStashSetInitialSize_Private(&mat->stash,size);
7786:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7787:   return(0);
7788: }

7790: /*@
7791:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7792:      the matrix

7794:    Neighbor-wise Collective on Mat

7796:    Input Parameters:
7797: +  mat   - the matrix
7798: .  x,y - the vectors
7799: -  w - where the result is stored

7801:    Level: intermediate

7803:    Notes:
7804:     w may be the same vector as y.

7806:     This allows one to use either the restriction or interpolation (its transpose)
7807:     matrix to do the interpolation

7809:     Concepts: interpolation

7811: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7813: @*/
7814: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7815: {
7817:   PetscInt       M,N,Ny;

7825:   MatCheckPreallocated(A,1);
7826:   MatGetSize(A,&M,&N);
7827:   VecGetSize(y,&Ny);
7828:   if (M == Ny) {
7829:     MatMultAdd(A,x,y,w);
7830:   } else {
7831:     MatMultTransposeAdd(A,x,y,w);
7832:   }
7833:   return(0);
7834: }

7836: /*@
7837:    MatInterpolate - y = A*x or A'*x depending on the shape of
7838:      the matrix

7840:    Neighbor-wise Collective on Mat

7842:    Input Parameters:
7843: +  mat   - the matrix
7844: -  x,y - the vectors

7846:    Level: intermediate

7848:    Notes:
7849:     This allows one to use either the restriction or interpolation (its transpose)
7850:     matrix to do the interpolation

7852:    Concepts: matrices^interpolation

7854: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7856: @*/
7857: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7858: {
7860:   PetscInt       M,N,Ny;

7867:   MatCheckPreallocated(A,1);
7868:   MatGetSize(A,&M,&N);
7869:   VecGetSize(y,&Ny);
7870:   if (M == Ny) {
7871:     MatMult(A,x,y);
7872:   } else {
7873:     MatMultTranspose(A,x,y);
7874:   }
7875:   return(0);
7876: }

7878: /*@
7879:    MatRestrict - y = A*x or A'*x

7881:    Neighbor-wise Collective on Mat

7883:    Input Parameters:
7884: +  mat   - the matrix
7885: -  x,y - the vectors

7887:    Level: intermediate

7889:    Notes:
7890:     This allows one to use either the restriction or interpolation (its transpose)
7891:     matrix to do the restriction

7893:    Concepts: matrices^restriction

7895: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()

7897: @*/
7898: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7899: {
7901:   PetscInt       M,N,Ny;

7908:   MatCheckPreallocated(A,1);

7910:   MatGetSize(A,&M,&N);
7911:   VecGetSize(y,&Ny);
7912:   if (M == Ny) {
7913:     MatMult(A,x,y);
7914:   } else {
7915:     MatMultTranspose(A,x,y);
7916:   }
7917:   return(0);
7918: }

7920: /*@
7921:    MatGetNullSpace - retrieves the null space to a matrix.

7923:    Logically Collective on Mat and MatNullSpace

7925:    Input Parameters:
7926: +  mat - the matrix
7927: -  nullsp - the null space object

7929:    Level: developer

7931:    Concepts: null space^attaching to matrix

7933: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
7934: @*/
7935: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7936: {
7941:   *nullsp = mat->nullsp;
7942:   return(0);
7943: }

7945: /*@
7946:    MatSetNullSpace - attaches a null space to a matrix.

7948:    Logically Collective on Mat and MatNullSpace

7950:    Input Parameters:
7951: +  mat - the matrix
7952: -  nullsp - the null space object

7954:    Level: advanced

7956:    Notes:
7957:       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached

7959:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
7960:       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.

7962:       You can remove the null space by calling this routine with an nullsp of NULL


7965:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
7966:    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).
7967:    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
7968:    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
7969:    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).

7971:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

7973:     If the matrix is known to be symmetric because it is an SBAIJ matrix or one as called MatSetOption(mat,MAT_SYMMETRIC or MAT_SYMMETRIC_ETERNAL,PETSC_TRUE); this
7974:     routine also automatically calls MatSetTransposeNullSpace().

7976:    Concepts: null space^attaching to matrix

7978: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
7979: @*/
7980: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7981: {

7988:   MatCheckPreallocated(mat,1);
7989:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
7990:   MatNullSpaceDestroy(&mat->nullsp);
7991:   mat->nullsp = nullsp;
7992:   if (mat->symmetric_set && mat->symmetric) {
7993:     MatSetTransposeNullSpace(mat,nullsp);
7994:   }
7995:   return(0);
7996: }

7998: /*@
7999:    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.

8001:    Logically Collective on Mat and MatNullSpace

8003:    Input Parameters:
8004: +  mat - the matrix
8005: -  nullsp - the null space object

8007:    Level: developer

8009:    Concepts: null space^attaching to matrix

8011: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8012: @*/
8013: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8014: {
8019:   *nullsp = mat->transnullsp;
8020:   return(0);
8021: }

8023: /*@
8024:    MatSetTransposeNullSpace - attaches a null space to a matrix.

8026:    Logically Collective on Mat and MatNullSpace

8028:    Input Parameters:
8029: +  mat - the matrix
8030: -  nullsp - the null space object

8032:    Level: advanced

8034:    Notes:
8035:       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.
8036:       You must also call MatSetNullSpace()


8039:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8040:    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).
8041:    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
8042:    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
8043:    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).

8045:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

8047:    Concepts: null space^attaching to matrix

8049: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8050: @*/
8051: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8052: {

8059:   MatCheckPreallocated(mat,1);
8060:   PetscObjectReference((PetscObject)nullsp);
8061:   MatNullSpaceDestroy(&mat->transnullsp);
8062:   mat->transnullsp = nullsp;
8063:   return(0);
8064: }

8066: /*@
8067:    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8068:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

8070:    Logically Collective on Mat and MatNullSpace

8072:    Input Parameters:
8073: +  mat - the matrix
8074: -  nullsp - the null space object

8076:    Level: advanced

8078:    Notes:
8079:       Overwrites any previous near null space that may have been attached

8081:       You can remove the null space by calling this routine with an nullsp of NULL

8083:    Concepts: null space^attaching to matrix

8085: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8086: @*/
8087: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8088: {

8095:   MatCheckPreallocated(mat,1);
8096:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8097:   MatNullSpaceDestroy(&mat->nearnullsp);
8098:   mat->nearnullsp = nullsp;
8099:   return(0);
8100: }

8102: /*@
8103:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

8105:    Not Collective

8107:    Input Parameters:
8108: .  mat - the matrix

8110:    Output Parameters:
8111: .  nullsp - the null space object, NULL if not set

8113:    Level: developer

8115:    Concepts: null space^attaching to matrix

8117: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8118: @*/
8119: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8120: {
8125:   MatCheckPreallocated(mat,1);
8126:   *nullsp = mat->nearnullsp;
8127:   return(0);
8128: }

8130: /*@C
8131:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

8133:    Collective on Mat

8135:    Input Parameters:
8136: +  mat - the matrix
8137: .  row - row/column permutation
8138: .  fill - expected fill factor >= 1.0
8139: -  level - level of fill, for ICC(k)

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

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

8149:    Level: developer

8151:    Concepts: matrices^incomplete Cholesky factorization
8152:    Concepts: Cholesky factorization

8154: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

8159: @*/
8160: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8161: {

8169:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8170:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8171:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8172:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8173:   MatCheckPreallocated(mat,1);
8174:   (*mat->ops->iccfactor)(mat,row,info);
8175:   PetscObjectStateIncrease((PetscObject)mat);
8176:   return(0);
8177: }

8179: /*@
8180:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8181:          ghosted ones.

8183:    Not Collective

8185:    Input Parameters:
8186: +  mat - the matrix
8187: -  diag = the diagonal values, including ghost ones

8189:    Level: developer

8191:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

8193: .seealso: MatDiagonalScale()
8194: @*/
8195: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8196: {
8198:   PetscMPIInt    size;


8205:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8206:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8207:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8208:   if (size == 1) {
8209:     PetscInt n,m;
8210:     VecGetSize(diag,&n);
8211:     MatGetSize(mat,0,&m);
8212:     if (m == n) {
8213:       MatDiagonalScale(mat,0,diag);
8214:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8215:   } else {
8216:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8217:   }
8218:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8219:   PetscObjectStateIncrease((PetscObject)mat);
8220:   return(0);
8221: }

8223: /*@
8224:    MatGetInertia - Gets the inertia from a factored matrix

8226:    Collective on Mat

8228:    Input Parameter:
8229: .  mat - the matrix

8231:    Output Parameters:
8232: +   nneg - number of negative eigenvalues
8233: .   nzero - number of zero eigenvalues
8234: -   npos - number of positive eigenvalues

8236:    Level: advanced

8238:    Notes: Matrix must have been factored by MatCholeskyFactor()


8241: @*/
8242: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8243: {

8249:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8250:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8251:   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8252:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8253:   return(0);
8254: }

8256: /* ----------------------------------------------------------------*/
8257: /*@C
8258:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

8260:    Neighbor-wise Collective on Mat and Vecs

8262:    Input Parameters:
8263: +  mat - the factored matrix
8264: -  b - the right-hand-side vectors

8266:    Output Parameter:
8267: .  x - the result vectors

8269:    Notes:
8270:    The vectors b and x cannot be the same.  I.e., one cannot
8271:    call MatSolves(A,x,x).

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

8278:    Level: developer

8280:    Concepts: matrices^triangular solves

8282: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8283: @*/
8284: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8285: {

8291:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8292:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8293:   if (!mat->rmap->N && !mat->cmap->N) return(0);

8295:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8296:   MatCheckPreallocated(mat,1);
8297:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8298:   (*mat->ops->solves)(mat,b,x);
8299:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8300:   return(0);
8301: }

8303: /*@
8304:    MatIsSymmetric - Test whether a matrix is symmetric

8306:    Collective on Mat

8308:    Input Parameter:
8309: +  A - the matrix to test
8310: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

8312:    Output Parameters:
8313: .  flg - the result

8315:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

8317:    Level: intermediate

8319:    Concepts: matrix^symmetry

8321: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8322: @*/
8323: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8324: {


8331:   if (!A->symmetric_set) {
8332:     if (!A->ops->issymmetric) {
8333:       MatType mattype;
8334:       MatGetType(A,&mattype);
8335:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8336:     }
8337:     (*A->ops->issymmetric)(A,tol,flg);
8338:     if (!tol) {
8339:       A->symmetric_set = PETSC_TRUE;
8340:       A->symmetric     = *flg;
8341:       if (A->symmetric) {
8342:         A->structurally_symmetric_set = PETSC_TRUE;
8343:         A->structurally_symmetric     = PETSC_TRUE;
8344:       }
8345:     }
8346:   } else if (A->symmetric) {
8347:     *flg = PETSC_TRUE;
8348:   } else if (!tol) {
8349:     *flg = PETSC_FALSE;
8350:   } else {
8351:     if (!A->ops->issymmetric) {
8352:       MatType mattype;
8353:       MatGetType(A,&mattype);
8354:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8355:     }
8356:     (*A->ops->issymmetric)(A,tol,flg);
8357:   }
8358:   return(0);
8359: }

8361: /*@
8362:    MatIsHermitian - Test whether a matrix is Hermitian

8364:    Collective on Mat

8366:    Input Parameter:
8367: +  A - the matrix to test
8368: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

8370:    Output Parameters:
8371: .  flg - the result

8373:    Level: intermediate

8375:    Concepts: matrix^symmetry

8377: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8378:           MatIsSymmetricKnown(), MatIsSymmetric()
8379: @*/
8380: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8381: {


8388:   if (!A->hermitian_set) {
8389:     if (!A->ops->ishermitian) {
8390:       MatType mattype;
8391:       MatGetType(A,&mattype);
8392:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8393:     }
8394:     (*A->ops->ishermitian)(A,tol,flg);
8395:     if (!tol) {
8396:       A->hermitian_set = PETSC_TRUE;
8397:       A->hermitian     = *flg;
8398:       if (A->hermitian) {
8399:         A->structurally_symmetric_set = PETSC_TRUE;
8400:         A->structurally_symmetric     = PETSC_TRUE;
8401:       }
8402:     }
8403:   } else if (A->hermitian) {
8404:     *flg = PETSC_TRUE;
8405:   } else if (!tol) {
8406:     *flg = PETSC_FALSE;
8407:   } else {
8408:     if (!A->ops->ishermitian) {
8409:       MatType mattype;
8410:       MatGetType(A,&mattype);
8411:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8412:     }
8413:     (*A->ops->ishermitian)(A,tol,flg);
8414:   }
8415:   return(0);
8416: }

8418: /*@
8419:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

8421:    Not Collective

8423:    Input Parameter:
8424: .  A - the matrix to check

8426:    Output Parameters:
8427: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8428: -  flg - the result

8430:    Level: advanced

8432:    Concepts: matrix^symmetry

8434:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8435:          if you want it explicitly checked

8437: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8438: @*/
8439: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8440: {
8445:   if (A->symmetric_set) {
8446:     *set = PETSC_TRUE;
8447:     *flg = A->symmetric;
8448:   } else {
8449:     *set = PETSC_FALSE;
8450:   }
8451:   return(0);
8452: }

8454: /*@
8455:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8457:    Not Collective

8459:    Input Parameter:
8460: .  A - the matrix to check

8462:    Output Parameters:
8463: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8464: -  flg - the result

8466:    Level: advanced

8468:    Concepts: matrix^symmetry

8470:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8471:          if you want it explicitly checked

8473: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8474: @*/
8475: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8476: {
8481:   if (A->hermitian_set) {
8482:     *set = PETSC_TRUE;
8483:     *flg = A->hermitian;
8484:   } else {
8485:     *set = PETSC_FALSE;
8486:   }
8487:   return(0);
8488: }

8490: /*@
8491:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8493:    Collective on Mat

8495:    Input Parameter:
8496: .  A - the matrix to test

8498:    Output Parameters:
8499: .  flg - the result

8501:    Level: intermediate

8503:    Concepts: matrix^symmetry

8505: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8506: @*/
8507: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8508: {

8514:   if (!A->structurally_symmetric_set) {
8515:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8516:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);

8518:     A->structurally_symmetric_set = PETSC_TRUE;
8519:   }
8520:   *flg = A->structurally_symmetric;
8521:   return(0);
8522: }

8524: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8525: /*@
8526:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8527:        to be communicated to other processors during the MatAssemblyBegin/End() process

8529:     Not collective

8531:    Input Parameter:
8532: .   vec - the vector

8534:    Output Parameters:
8535: +   nstash   - the size of the stash
8536: .   reallocs - the number of additional mallocs incurred.
8537: .   bnstash   - the size of the block stash
8538: -   breallocs - the number of additional mallocs incurred.in the block stash

8540:    Level: advanced

8542: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()

8544: @*/
8545: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8546: {

8550:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8551:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8552:   return(0);
8553: }

8555: /*@C
8556:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8557:      parallel layout

8559:    Collective on Mat

8561:    Input Parameter:
8562: .  mat - the matrix

8564:    Output Parameter:
8565: +   right - (optional) vector that the matrix can be multiplied against
8566: -   left - (optional) vector that the matrix vector product can be stored in

8568:    Notes:
8569:     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().

8571:   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed

8573:   Level: advanced

8575: .seealso: MatCreate(), VecDestroy()
8576: @*/
8577: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8578: {

8584:   if (mat->ops->getvecs) {
8585:     (*mat->ops->getvecs)(mat,right,left);
8586:   } else {
8587:     PetscInt rbs,cbs;
8588:     MatGetBlockSizes(mat,&rbs,&cbs);
8589:     if (right) {
8590:       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8591:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8592:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8593:       VecSetBlockSize(*right,cbs);
8594:       VecSetType(*right,VECSTANDARD);
8595:       PetscLayoutReference(mat->cmap,&(*right)->map);
8596:     }
8597:     if (left) {
8598:       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8599:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8600:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8601:       VecSetBlockSize(*left,rbs);
8602:       VecSetType(*left,VECSTANDARD);
8603:       PetscLayoutReference(mat->rmap,&(*left)->map);
8604:     }
8605:   }
8606:   return(0);
8607: }

8609: /*@C
8610:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8611:      with default values.

8613:    Not Collective

8615:    Input Parameters:
8616: .    info - the MatFactorInfo data structure


8619:    Notes: The solvers are generally used through the KSP and PC objects, for example
8620:           PCLU, PCILU, PCCHOLESKY, PCICC

8622:    Level: developer

8624: .seealso: MatFactorInfo

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

8629: @*/

8631: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8632: {

8636:   PetscMemzero(info,sizeof(MatFactorInfo));
8637:   return(0);
8638: }

8640: /*@
8641:    MatFactorSetSchurIS - Set indices corresponding to the Schur complement

8643:    Collective on Mat

8645:    Input Parameters:
8646: +  mat - the factored matrix
8647: -  is - the index set defining the Schur indices (0-based)

8649:    Notes:

8651:    Level: developer

8653:    Concepts:

8655: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()

8657: @*/
8658: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8659: {
8660:   PetscErrorCode ierr,(*f)(Mat,IS);

8668:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8669:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8670:   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");
8671:   (*f)(mat,is);
8672:   return(0);
8673: }

8675: /*@
8676:   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step

8678:    Logically Collective on Mat

8680:    Input Parameters:
8681: +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8682: .  *S - location where to return the Schur complement (MATDENSE)

8684:    Notes:
8685:    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.
8686:    If MatFactorInvertSchurComplement has been called, the routine gets back the inverse

8688:    Level: advanced

8690:    References:

8692: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement()
8693: @*/
8694: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S)
8695: {

8700:   PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));
8701:   return(0);
8702: }

8704: /*@
8705:   MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data

8707:    Logically Collective on Mat

8709:    Input Parameters:
8710: +  F - the factored matrix obtained by calling MatGetFactor()
8711: .  *S - location where to return the Schur complement (in MATDENSE format)

8713:    Notes:
8714:    Schur complement mode is currently implemented for sequential matrices.
8715:    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.
8716:    The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.

8718:    Level: advanced

8720:    References:

8722: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8723: @*/
8724: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S)
8725: {

8730:   PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));
8731:   return(0);
8732: }

8734: /*@
8735:   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement

8737:    Logically Collective on Mat

8739:    Input Parameters:
8740: +  F - the factored matrix obtained by calling MatGetFactor()
8741: .  *S - location where the Schur complement is stored

8743:    Notes:

8745:    Level: advanced

8747:    References:

8749: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8750: @*/
8751: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S)
8752: {

8758:   MatDestroy(S);
8759:   return(0);
8760: }

8762: /*@
8763:   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step

8765:    Logically Collective on Mat

8767:    Input Parameters:
8768: +  F - the factored matrix obtained by calling MatGetFactor()
8769: .  rhs - location where the right hand side of the Schur complement system is stored
8770: -  sol - location where the solution of the Schur complement system has to be returned

8772:    Notes:
8773:    The sizes of the vectors should match the size of the Schur complement

8775:    Level: advanced

8777:    References:

8779: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8780: @*/
8781: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8782: {

8791:   PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));
8792:   return(0);
8793: }

8795: /*@
8796:   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step

8798:    Logically Collective on Mat

8800:    Input Parameters:
8801: +  F - the factored matrix obtained by calling MatGetFactor()
8802: .  rhs - location where the right hand side of the Schur complement system is stored
8803: -  sol - location where the solution of the Schur complement system has to be returned

8805:    Notes:
8806:    The sizes of the vectors should match the size of the Schur complement

8808:    Level: advanced

8810:    References:

8812: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8813: @*/
8814: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8815: {

8824:   PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));
8825:   return(0);
8826: }

8828: /*@
8829:   MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step

8831:    Logically Collective on Mat

8833:    Input Parameters:
8834: +  F - the factored matrix obtained by calling MatGetFactor()

8836:    Notes:

8838:    Level: advanced

8840:    References:

8842: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8843: @*/
8844: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
8845: {

8850:   PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));
8851:   return(0);
8852: }

8854: /*@
8855:   MatFactorFactorizeSchurComplement - Factorize the raw Schur data computed during the factorization step

8857:    Logically Collective on Mat

8859:    Input Parameters:
8860: +  F - the factored matrix obtained by calling MatGetFactor()

8862:    Notes:
8863:    The routine uses the pointer to the raw data of the Schur Complement stored within the solver.

8865:    Level: advanced

8867:    References:

8869: .seealso: MatGetFactor(), MatMumpsSetSchurIS()
8870: @*/
8871: PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
8872: {

8877:   PetscUseMethod(F,"MatFactorFactorizeSchurComplement_C",(Mat),(F));
8878:   return(0);
8879: }

8881: /*@
8882:   MatFactorSetSchurComplementSolverType - Set type of solver for Schur complement

8884:    Logically Collective on Mat

8886:    Input Parameters:
8887: +  F - the factored matrix obtained by calling MatGetFactor()
8888: -  type - either 0 (non-symmetric), 1 (symmetric positive definite) or 2 (symmetric indefinite)

8890:    Notes:
8891:    The parameter is used to compute the correct factorization of the Schur complement matrices
8892:    This could be useful in case the nature of the Schur complement is different from that of the matrix to be factored

8894:    Level: advanced

8896:    References:

8898: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8899: @*/
8900: PetscErrorCode MatFactorSetSchurComplementSolverType(Mat F, PetscInt type)
8901: {

8907:   PetscTryMethod(F,"MatFactorSetSchurComplementSolverType_C",(Mat,PetscInt),(F,type));
8908:   return(0);
8909: }

8911: /*@
8912:    MatPtAP - Creates the matrix product C = P^T * A * P

8914:    Neighbor-wise Collective on Mat

8916:    Input Parameters:
8917: +  A - the matrix
8918: .  P - the projection matrix
8919: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8920: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
8921:           if the result is a dense matrix this is irrelevent

8923:    Output Parameters:
8924: .  C - the product matrix

8926:    Notes:
8927:    C will be created and must be destroyed by the user with MatDestroy().

8929:    This routine is currently only implemented for pairs of AIJ matrices and classes
8930:    which inherit from AIJ.

8932:    Level: intermediate

8934: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8935: @*/
8936: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8937: {
8939:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8940:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8941:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8942:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

8945:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8946:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

8950:   MatCheckPreallocated(A,1);
8951:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
8952:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8953:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8956:   MatCheckPreallocated(P,2);
8957:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8958:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8960:   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);
8961:   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);
8962:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8963:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8965:   if (scall == MAT_REUSE_MATRIX) {
8968:     if (viatranspose || viamatmatmatmult) {
8969:       Mat Pt;
8970:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8971:       if (viamatmatmatmult) {
8972:         MatMatMatMult(Pt,A,P,scall,fill,C);
8973:       } else {
8974:         Mat AP;
8975:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8976:         MatMatMult(Pt,AP,scall,fill,C);
8977:         MatDestroy(&AP);
8978:       }
8979:       MatDestroy(&Pt);
8980:     } else {
8981:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8982:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8983:       (*(*C)->ops->ptapnumeric)(A,P,*C);
8984:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8985:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8986:     }
8987:     return(0);
8988:   }

8990:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8991:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8993:   fA = A->ops->ptap;
8994:   fP = P->ops->ptap;
8995:   if (fP == fA) {
8996:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8997:     ptap = fA;
8998:   } else {
8999:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9000:     char ptapname[256];
9001:     PetscStrcpy(ptapname,"MatPtAP_");
9002:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
9003:     PetscStrcat(ptapname,"_");
9004:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
9005:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9006:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9007:     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);
9008:   }

9010:   if (viatranspose || viamatmatmatmult) {
9011:     Mat Pt;
9012:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9013:     if (viamatmatmatmult) {
9014:       MatMatMatMult(Pt,A,P,scall,fill,C);
9015:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
9016:     } else {
9017:       Mat AP;
9018:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9019:       MatMatMult(Pt,AP,scall,fill,C);
9020:       MatDestroy(&AP);
9021:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
9022:     }
9023:     MatDestroy(&Pt);
9024:   } else {
9025:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9026:     (*ptap)(A,P,scall,fill,C);
9027:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9028:   }
9029:   return(0);
9030: }

9032: /*@
9033:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

9035:    Neighbor-wise Collective on Mat

9037:    Input Parameters:
9038: +  A - the matrix
9039: -  P - the projection matrix

9041:    Output Parameters:
9042: .  C - the product matrix

9044:    Notes:
9045:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9046:    the user using MatDeatroy().

9048:    This routine is currently only implemented for pairs of AIJ matrices and classes
9049:    which inherit from AIJ.  C will be of type MATAIJ.

9051:    Level: intermediate

9053: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9054: @*/
9055: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9056: {

9062:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9063:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9066:   MatCheckPreallocated(P,2);
9067:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9068:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9071:   MatCheckPreallocated(C,3);
9072:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9073:   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);
9074:   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);
9075:   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);
9076:   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);
9077:   MatCheckPreallocated(A,1);

9079:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9080:   (*C->ops->ptapnumeric)(A,P,C);
9081:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9082:   return(0);
9083: }

9085: /*@
9086:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

9088:    Neighbor-wise Collective on Mat

9090:    Input Parameters:
9091: +  A - the matrix
9092: -  P - the projection matrix

9094:    Output Parameters:
9095: .  C - the (i,j) structure of the product matrix

9097:    Notes:
9098:    C will be created and must be destroyed by the user with MatDestroy().

9100:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9101:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9102:    this (i,j) structure by calling MatPtAPNumeric().

9104:    Level: intermediate

9106: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9107: @*/
9108: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9109: {

9115:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9116:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9117:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9120:   MatCheckPreallocated(P,2);
9121:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9122:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9125:   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);
9126:   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);
9127:   MatCheckPreallocated(A,1);
9128:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9129:   (*A->ops->ptapsymbolic)(A,P,fill,C);
9130:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

9132:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
9133:   return(0);
9134: }

9136: /*@
9137:    MatRARt - Creates the matrix product C = R * A * R^T

9139:    Neighbor-wise Collective on Mat

9141:    Input Parameters:
9142: +  A - the matrix
9143: .  R - the projection matrix
9144: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9145: -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9146:           if the result is a dense matrix this is irrelevent

9148:    Output Parameters:
9149: .  C - the product matrix

9151:    Notes:
9152:    C will be created and must be destroyed by the user with MatDestroy().

9154:    This routine is currently only implemented for pairs of AIJ matrices and classes
9155:    which inherit from AIJ.

9157:    Level: intermediate

9159: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9160: @*/
9161: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9162: {

9168:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9169:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9170:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9173:   MatCheckPreallocated(R,2);
9174:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9175:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9177:   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);

9179:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9180:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9181:   MatCheckPreallocated(A,1);

9183:   if (!A->ops->rart) {
9184:     MatType mattype;
9185:     MatGetType(A,&mattype);
9186:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
9187:   }
9188:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
9189:   (*A->ops->rart)(A,R,scall,fill,C);
9190:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
9191:   return(0);
9192: }

9194: /*@
9195:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

9197:    Neighbor-wise Collective on Mat

9199:    Input Parameters:
9200: +  A - the matrix
9201: -  R - the projection matrix

9203:    Output Parameters:
9204: .  C - the product matrix

9206:    Notes:
9207:    C must have been created by calling MatRARtSymbolic and must be destroyed by
9208:    the user using MatDestroy().

9210:    This routine is currently only implemented for pairs of AIJ matrices and classes
9211:    which inherit from AIJ.  C will be of type MATAIJ.

9213:    Level: intermediate

9215: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9216: @*/
9217: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9218: {

9224:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9225:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9228:   MatCheckPreallocated(R,2);
9229:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9230:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9233:   MatCheckPreallocated(C,3);
9234:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9235:   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);
9236:   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);
9237:   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);
9238:   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);
9239:   MatCheckPreallocated(A,1);

9241:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
9242:   (*A->ops->rartnumeric)(A,R,C);
9243:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
9244:   return(0);
9245: }

9247: /*@
9248:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

9250:    Neighbor-wise Collective on Mat

9252:    Input Parameters:
9253: +  A - the matrix
9254: -  R - the projection matrix

9256:    Output Parameters:
9257: .  C - the (i,j) structure of the product matrix

9259:    Notes:
9260:    C will be created and must be destroyed by the user with MatDestroy().

9262:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9263:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9264:    this (i,j) structure by calling MatRARtNumeric().

9266:    Level: intermediate

9268: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9269: @*/
9270: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9271: {

9277:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9278:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9279:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9282:   MatCheckPreallocated(R,2);
9283:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9284:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9287:   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);
9288:   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);
9289:   MatCheckPreallocated(A,1);
9290:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9291:   (*A->ops->rartsymbolic)(A,R,fill,C);
9292:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

9294:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9295:   return(0);
9296: }

9298: /*@
9299:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

9301:    Neighbor-wise Collective on Mat

9303:    Input Parameters:
9304: +  A - the left matrix
9305: .  B - the right matrix
9306: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9307: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9308:           if the result is a dense matrix this is irrelevent

9310:    Output Parameters:
9311: .  C - the product matrix

9313:    Notes:
9314:    Unless scall is MAT_REUSE_MATRIX C will be created.

9316:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9318:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9319:    actually needed.

9321:    If you have many matrices with the same non-zero structure to multiply, you
9322:    should either
9323: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9324: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9325:    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
9326:    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.

9328:    Level: intermediate

9330: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9331: @*/
9332: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9333: {
9335:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9336:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9337:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9342:   MatCheckPreallocated(A,1);
9343:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9344:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9347:   MatCheckPreallocated(B,2);
9348:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9349:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9351:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9352:   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);
9353:   if (scall == MAT_REUSE_MATRIX) {
9356:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9357:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9358:     (*(*C)->ops->matmultnumeric)(A,B,*C);
9359:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9360:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9361:     return(0);
9362:   }
9363:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9364:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9366:   fA = A->ops->matmult;
9367:   fB = B->ops->matmult;
9368:   if (fB == fA) {
9369:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9370:     mult = fB;
9371:   } else {
9372:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9373:     char multname[256];
9374:     PetscStrcpy(multname,"MatMatMult_");
9375:     PetscStrcat(multname,((PetscObject)A)->type_name);
9376:     PetscStrcat(multname,"_");
9377:     PetscStrcat(multname,((PetscObject)B)->type_name);
9378:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9379:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9380:     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);
9381:   }
9382:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9383:   (*mult)(A,B,scall,fill,C);
9384:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9385:   return(0);
9386: }

9388: /*@
9389:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9390:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

9392:    Neighbor-wise Collective on Mat

9394:    Input Parameters:
9395: +  A - the left matrix
9396: .  B - the right matrix
9397: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9398:       if C is a dense matrix this is irrelevent

9400:    Output Parameters:
9401: .  C - the product matrix

9403:    Notes:
9404:    Unless scall is MAT_REUSE_MATRIX C will be created.

9406:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9407:    actually needed.

9409:    This routine is currently implemented for
9410:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9411:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9412:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9414:    Level: intermediate

9416:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9417:      We should incorporate them into PETSc.

9419: .seealso: MatMatMult(), MatMatMultNumeric()
9420: @*/
9421: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9422: {
9424:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9425:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,