Actual source code: matrix.c

petsc-master 2014-11-25
Report Typos and Errors
  2: /*
  3:    This is where the abstract matrix operations are defined
  4: */

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

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

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

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

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

 46:    Logically Collective on Vec

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

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

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

 63:    Level: intermediate

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

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


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

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

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


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

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

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

109:   Level: intermediate

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

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

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

130:    Not Collective

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

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

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

140:    Level: advanced

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

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

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

173:    Collective on Mat

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

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

181:    Level: advanced

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

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

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

202:    Logically Collective on Mat

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

207:    Level: advanced


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

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

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

242:    Collective on Mat

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

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

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

253:    Level: advanced

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

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


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

280:    Logically Collective on Mat

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

285:    Level: advanced


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

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

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

320:    Collective on Mat

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

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

329:    Level: advanced


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

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

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

355:    Not Collective

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

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

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

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

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

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

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

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


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

405:    Level: advanced

407:    Concepts: matrices^row access

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

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

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

435:    Logically Collective on Mat

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

440:    Level: advanced

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

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

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

475:    Not Collective

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

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

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

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

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

505:    Level: advanced

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

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

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

531:    Not Collective

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

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

539:    Level: advanced

541:    Concepts: matrices^row access

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

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

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

565:    Not Collective

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

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


574:    Level: advanced

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

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

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

596:    Logically Collective on Mat

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

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

606:    Level: advanced

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

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

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

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

628:    Logically Collective on Mat

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

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

638:    Level: advanced

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

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

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

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

660:    Not Collective

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

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

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

671:    Level: advanced

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

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

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

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

692:    Collective on Mat

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

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

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

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

704:    Level: beginner

706: .keywords: Mat, setup

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

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

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

741:    Collective on Mat

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

920:    Collective on PetscViewer

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

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

932:    Level: beginner

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1053:    Collective on Mat

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

1058:    Level: beginner

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

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

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

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

1091:    Not Collective

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

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

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

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

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

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

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

1124:    Level: beginner

1126:    Concepts: matrices^putting entries in

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

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

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

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


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

1193:    Not Collective

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

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

1203:    All the nonzeros in the row must be provided

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

1207:    The row must belong to this process

1209:    Level: intermediate

1211:    Concepts: matrices^putting entries in

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

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

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

1246:    Not Collective

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

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

1256:    All the nonzeros in the row must be provided

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

1260:    The row must belong to this process

1262:    Level: advanced

1264:    Concepts: matrices^putting entries in

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

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

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

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

1311:    Not Collective

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

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

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

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

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

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

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

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

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

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

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

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

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

1371:    Level: beginner

1373:    Concepts: matrices^putting entries in

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

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

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

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

1430:    Not Collective

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

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

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

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

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

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

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

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

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

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

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

1483:    Level: beginner

1485:    Concepts: matrices^putting entries in

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

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

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

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

1553:    Not Collective

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


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

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

1569:    Level: beginner

1571:    Concepts: matrices^putting entries in

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


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

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

1601:    Not Collective

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

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

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

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

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

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

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

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

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

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

1661:    Level: intermediate

1663:    Concepts: matrices^putting entries in blocked

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

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

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

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

1737:    Not Collective; currently only returns a local block

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

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

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

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

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

1761:    Level: advanced

1763:    Concepts: matrices^accessing values

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

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

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

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

1795:   Not Collective

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

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

1807:   Level: advanced

1809:   Concepts: matrices^putting entries in

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

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

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

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

1847:    Not Collective

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

1854:    Level: intermediate

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

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


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


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

1886:    Not Collective

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

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

1895:    Level: advanced

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

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

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

1919:    Not Collective

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

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

1928:    Level: advanced

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

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

1950:    Not Collective

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

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

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

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

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

1974:    Level: intermediate

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

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

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

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

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

2042:    Not Collective

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

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

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

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

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

2067:    Level: intermediate

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

2071: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2072:            MatSetValuesLocal(),  MatSetValuesBlocked()
2073: @*/
2074: PetscErrorCode  MatSetValuesBlockedLocal(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->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !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->setvaluesblockedlocal) {
2101:     (*mat->ops->setvaluesblockedlocal)(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:     ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2111:     ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2112:     MatSetValuesBlocked(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: #endif
2121: #if defined(PETSC_HAVE_VIENNACL)
2122:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2123:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2124:   }
2125: #endif
2126:   return(0);
2127: }

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

2134:    Collective on Mat and Vec

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

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

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

2147:    Level: developer

2149:    Concepts: matrix-vector product

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


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

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

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

2180:    Neighbor-wise Collective on Mat and Vec

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

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

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

2193:    Level: beginner

2195:    Concepts: matrix-vector product

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

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

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

2229: /*@
2230:    MatMultTranspose - Computes matrix transpose times a vector.

2232:    Neighbor-wise Collective on Mat and Vec

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

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 MatMultTranspose(A,y,y).

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

2248:    Level: beginner

2250:    Concepts: matrix vector product^transpose

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


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

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

2285: /*@
2286:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2288:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

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

2305:    Level: beginner

2307:    Concepts: matrix vector product^transpose

2309: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2310: @*/
2311: PetscErrorCode  MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2312: {
2314:   Vec            w;


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

2331:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2332:   if (mat->ops->multhermitiantranspose) {
2333:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2334:   } else {
2335:     VecDuplicate(x,&w);
2336:     VecCopy(x,w);
2337:     VecConjugate(w);
2338:     MatMultTranspose(mat,w,y);
2339:     VecDestroy(&w);
2340:     VecConjugate(y);
2341:   }
2342:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2343:   PetscObjectStateIncrease((PetscObject)y);
2344:   return(0);
2345: }

2349: /*@
2350:     MatMultAdd -  Computes v3 = v2 + A * v1.

2352:     Neighbor-wise Collective on Mat and Vec

2354:     Input Parameters:
2355: +   mat - the matrix
2356: -   v1, v2 - the vectors

2358:     Output Parameters:
2359: .   v3 - the result

2361:     Notes:
2362:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2363:     call MatMultAdd(A,v1,v2,v1).

2365:     Level: beginner

2367:     Concepts: matrix vector product^addition

2369: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2370: @*/
2371: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2372: {


2382:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2383:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2384:   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);
2385:   /* 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);
2386:      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); */
2387:   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);
2388:   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);
2389:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2390:   MatCheckPreallocated(mat,1);

2392:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2393:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2394:   (*mat->ops->multadd)(mat,v1,v2,v3);
2395:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2396:   PetscObjectStateIncrease((PetscObject)v3);
2397:   return(0);
2398: }

2402: /*@
2403:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2405:    Neighbor-wise Collective on Mat and Vec

2407:    Input Parameters:
2408: +  mat - the matrix
2409: -  v1, v2 - the vectors

2411:    Output Parameters:
2412: .  v3 - the result

2414:    Notes:
2415:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2416:    call MatMultTransposeAdd(A,v1,v2,v1).

2418:    Level: beginner

2420:    Concepts: matrix vector product^transpose and addition

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


2435:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2436:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2437:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2438:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2439:   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);
2440:   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);
2441:   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);
2442:   MatCheckPreallocated(mat,1);

2444:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2445:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2446:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2447:   PetscObjectStateIncrease((PetscObject)v3);
2448:   return(0);
2449: }

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

2456:    Neighbor-wise Collective on Mat and Vec

2458:    Input Parameters:
2459: +  mat - the matrix
2460: -  v1, v2 - the vectors

2462:    Output Parameters:
2463: .  v3 - the result

2465:    Notes:
2466:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2467:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2469:    Level: beginner

2471:    Concepts: matrix vector product^transpose and addition

2473: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2474: @*/
2475: PetscErrorCode  MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2476: {


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

2495:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2496:   (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2497:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2498:   PetscObjectStateIncrease((PetscObject)v3);
2499:   return(0);
2500: }

2504: /*@
2505:    MatMultConstrained - The inner multiplication routine for a
2506:    constrained matrix P^T A P.

2508:    Neighbor-wise Collective on Mat and Vec

2510:    Input Parameters:
2511: +  mat - the matrix
2512: -  x   - the vector to be multilplied

2514:    Output Parameters:
2515: .  y - the result

2517:    Notes:
2518:    The vectors x and y cannot be the same.  I.e., one cannot
2519:    call MatMult(A,y,y).

2521:    Level: beginner

2523: .keywords: matrix, multiply, matrix-vector product, constraint
2524: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2525: @*/
2526: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
2527: {

2534:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2535:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2536:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2537:   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);
2538:   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);
2539:   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);

2541:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2542:   (*mat->ops->multconstrained)(mat,x,y);
2543:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2544:   PetscObjectStateIncrease((PetscObject)y);
2545:   return(0);
2546: }

2550: /*@
2551:    MatMultTransposeConstrained - The inner multiplication routine for a
2552:    constrained matrix P^T A^T P.

2554:    Neighbor-wise Collective on Mat and Vec

2556:    Input Parameters:
2557: +  mat - the matrix
2558: -  x   - the vector to be multilplied

2560:    Output Parameters:
2561: .  y - the result

2563:    Notes:
2564:    The vectors x and y cannot be the same.  I.e., one cannot
2565:    call MatMult(A,y,y).

2567:    Level: beginner

2569: .keywords: matrix, multiply, matrix-vector product, constraint
2570: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2571: @*/
2572: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2573: {

2580:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2581:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2582:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2583:   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);
2584:   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);

2586:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2587:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2588:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2589:   PetscObjectStateIncrease((PetscObject)y);
2590:   return(0);
2591: }

2595: /*@C
2596:    MatGetFactorType - gets the type of factorization it is

2598:    Note Collective
2599:    as the flag

2601:    Input Parameters:
2602: .  mat - the matrix

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

2607:     Level: intermediate

2609: .seealso:    MatFactorType, MatGetFactor()
2610: @*/
2611: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
2612: {
2616:   *t = mat->factortype;
2617:   return(0);
2618: }

2620: /* ------------------------------------------------------------*/
2623: /*@C
2624:    MatGetInfo - Returns information about matrix storage (number of
2625:    nonzeros, memory, etc.).

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

2629:    Input Parameters:
2630: .  mat - the matrix

2632:    Output Parameters:
2633: +  flag - flag indicating the type of parameters to be returned
2634:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2635:    MAT_GLOBAL_SUM - sum over all processors)
2636: -  info - matrix information context

2638:    Notes:
2639:    The MatInfo context contains a variety of matrix data, including
2640:    number of nonzeros allocated and used, number of mallocs during
2641:    matrix assembly, etc.  Additional information for factored matrices
2642:    is provided (such as the fill ratio, number of mallocs during
2643:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2644:    when using the runtime options
2645: $       -info -mat_view ::ascii_info

2647:    Example for C/C++ Users:
2648:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2649:    data within the MatInfo context.  For example,
2650: .vb
2651:       MatInfo info;
2652:       Mat     A;
2653:       double  mal, nz_a, nz_u;

2655:       MatGetInfo(A,MAT_LOCAL,&info);
2656:       mal  = info.mallocs;
2657:       nz_a = info.nz_allocated;
2658: .ve

2660:    Example for Fortran Users:
2661:    Fortran users should declare info as a double precision
2662:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2663:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2664:    a complete list of parameter names.
2665: .vb
2666:       double  precision info(MAT_INFO_SIZE)
2667:       double  precision mal, nz_a
2668:       Mat     A
2669:       integer ierr

2671:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2672:       mal = info(MAT_INFO_MALLOCS)
2673:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2674: .ve

2676:     Level: intermediate

2678:     Concepts: matrices^getting information on

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

2683: .seealso: MatStashGetInfo()

2685: @*/
2686: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2687: {

2694:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2695:   MatCheckPreallocated(mat,1);
2696:   (*mat->ops->getinfo)(mat,flag,info);
2697:   return(0);
2698: }

2700: /* ----------------------------------------------------------*/

2704: /*@C
2705:    MatLUFactor - Performs in-place LU factorization of matrix.

2707:    Collective on Mat

2709:    Input Parameters:
2710: +  mat - the matrix
2711: .  row - row permutation
2712: .  col - column permutation
2713: -  info - options for factorization, includes
2714: $          fill - expected fill as ratio of original fill.
2715: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2716: $                   Run with the option -info to determine an optimal value to use

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

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

2726:    Level: developer

2728:    Concepts: matrices^LU factorization

2730: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2731:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2736: @*/
2737: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2738: {
2740:   MatFactorInfo  tinfo;

2748:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2749:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2750:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2751:   MatCheckPreallocated(mat,1);
2752:   if (!info) {
2753:     MatFactorInfoInitialize(&tinfo);
2754:     info = &tinfo;
2755:   }

2757:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2758:   (*mat->ops->lufactor)(mat,row,col,info);
2759:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2760:   PetscObjectStateIncrease((PetscObject)mat);
2761:   return(0);
2762: }

2766: /*@C
2767:    MatILUFactor - Performs in-place ILU factorization of matrix.

2769:    Collective on Mat

2771:    Input Parameters:
2772: +  mat - the matrix
2773: .  row - row permutation
2774: .  col - column permutation
2775: -  info - structure containing
2776: $      levels - number of levels of fill.
2777: $      expected fill - as ratio of original fill.
2778: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2779:                 missing diagonal entries)

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

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

2789:    Level: developer

2791:    Concepts: matrices^ILU factorization

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

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

2798: @*/
2799: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2800: {

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

2815:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2816:   (*mat->ops->ilufactor)(mat,row,col,info);
2817:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2818:   PetscObjectStateIncrease((PetscObject)mat);
2819:   return(0);
2820: }

2824: /*@C
2825:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2826:    Call this routine before calling MatLUFactorNumeric().

2828:    Collective on Mat

2830:    Input Parameters:
2831: +  fact - the factor matrix obtained with MatGetFactor()
2832: .  mat - the matrix
2833: .  row, col - row and column permutations
2834: -  info - options for factorization, includes
2835: $          fill - expected fill as ratio of original fill.
2836: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2837: $                   Run with the option -info to determine an optimal value to use


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

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

2846:    Level: developer

2848:    Concepts: matrices^LU symbolic factorization

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

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

2855: @*/
2856: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2857: {

2867:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2868:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2869:   if (!(fact)->ops->lufactorsymbolic) {
2870:     const MatSolverPackage spackage;
2871:     MatFactorGetSolverPackage(fact,&spackage);
2872:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2873:   }
2874:   MatCheckPreallocated(mat,2);

2876:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2877:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2878:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2879:   PetscObjectStateIncrease((PetscObject)fact);
2880:   return(0);
2881: }

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

2889:    Collective on Mat

2891:    Input Parameters:
2892: +  fact - the factor matrix obtained with MatGetFactor()
2893: .  mat - the matrix
2894: -  info - options for factorization

2896:    Notes:
2897:    See MatLUFactor() for in-place factorization.  See
2898:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

2904:    Level: developer

2906:    Concepts: matrices^LU numeric factorization

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

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

2913: @*/
2914: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2915: {

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

2926:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2927:   MatCheckPreallocated(mat,2);
2928:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2929:   (fact->ops->lufactornumeric)(fact,mat,info);
2930:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2931:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
2932:   PetscObjectStateIncrease((PetscObject)fact);
2933:   return(0);
2934: }

2938: /*@C
2939:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2940:    symmetric matrix.

2942:    Collective on Mat

2944:    Input Parameters:
2945: +  mat - the matrix
2946: .  perm - row and column permutations
2947: -  f - expected fill as ratio of original fill

2949:    Notes:
2950:    See MatLUFactor() for the nonsymmetric case.  See also
2951:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

2957:    Level: developer

2959:    Concepts: matrices^Cholesky factorization

2961: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2962:           MatGetOrdering()

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

2967: @*/
2968: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2969: {

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

2983:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2984:   (*mat->ops->choleskyfactor)(mat,perm,info);
2985:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2986:   PetscObjectStateIncrease((PetscObject)mat);
2987:   return(0);
2988: }

2992: /*@C
2993:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2994:    of a symmetric matrix.

2996:    Collective on Mat

2998:    Input Parameters:
2999: +  fact - the factor matrix obtained with MatGetFactor()
3000: .  mat - the matrix
3001: .  perm - row and column permutations
3002: -  info - options for factorization, includes
3003: $          fill - expected fill as ratio of original fill.
3004: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3005: $                   Run with the option -info to determine an optimal value to use

3007:    Notes:
3008:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3009:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

3015:    Level: developer

3017:    Concepts: matrices^Cholesky symbolic factorization

3019: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3020:           MatGetOrdering()

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

3025: @*/
3026: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3027: {

3036:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3037:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3038:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3039:   if (!(fact)->ops->choleskyfactorsymbolic) {
3040:     const MatSolverPackage spackage;
3041:     MatFactorGetSolverPackage(fact,&spackage);
3042:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3043:   }
3044:   MatCheckPreallocated(mat,2);

3046:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3047:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3048:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3049:   PetscObjectStateIncrease((PetscObject)fact);
3050:   return(0);
3051: }

3055: /*@C
3056:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3057:    of a symmetric matrix. Call this routine after first calling
3058:    MatCholeskyFactorSymbolic().

3060:    Collective on Mat

3062:    Input Parameters:
3063: +  fact - the factor matrix obtained with MatGetFactor()
3064: .  mat - the initial matrix
3065: .  info - options for factorization
3066: -  fact - the symbolic factor of mat


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

3074:    Level: developer

3076:    Concepts: matrices^Cholesky numeric factorization

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

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

3083: @*/
3084: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3085: {

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

3098:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3099:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3100:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3101:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3102:   PetscObjectStateIncrease((PetscObject)fact);
3103:   return(0);
3104: }

3106: /* ----------------------------------------------------------------*/
3109: /*@
3110:    MatSolve - Solves A x = b, given a factored matrix.

3112:    Neighbor-wise Collective on Mat and Vec

3114:    Input Parameters:
3115: +  mat - the factored matrix
3116: -  b - the right-hand-side vector

3118:    Output Parameter:
3119: .  x - the result vector

3121:    Notes:
3122:    The vectors b and x cannot be the same.  I.e., one cannot
3123:    call MatSolve(A,x,x).

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

3130:    Level: developer

3132:    Concepts: matrices^triangular solves

3134: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3135: @*/
3136: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
3137: {

3147:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3148:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3149:   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);
3150:   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);
3151:   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);
3152:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3153:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3154:   MatCheckPreallocated(mat,1);

3156:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3157:   (*mat->ops->solve)(mat,b,x);
3158:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3159:   PetscObjectStateIncrease((PetscObject)x);
3160:   return(0);
3161: }

3165: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
3166: {
3168:   Vec            b,x;
3169:   PetscInt       m,N,i;
3170:   PetscScalar    *bb,*xx;
3171:   PetscBool      flg;

3174:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3175:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3176:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3177:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3179:   MatDenseGetArray(B,&bb);
3180:   MatDenseGetArray(X,&xx);
3181:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3182:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3183:   MatCreateVecs(A,&x,&b);
3184:   for (i=0; i<N; i++) {
3185:     VecPlaceArray(b,bb + i*m);
3186:     VecPlaceArray(x,xx + i*m);
3187:     MatSolve(A,b,x);
3188:     VecResetArray(x);
3189:     VecResetArray(b);
3190:   }
3191:   VecDestroy(&b);
3192:   VecDestroy(&x);
3193:   MatDenseRestoreArray(B,&bb);
3194:   MatDenseRestoreArray(X,&xx);
3195:   return(0);
3196: }

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

3203:    Neighbor-wise Collective on Mat

3205:    Input Parameters:
3206: +  mat - the factored matrix
3207: -  B - the right-hand-side matrix  (dense matrix)

3209:    Output Parameter:
3210: .  X - the result matrix (dense matrix)

3212:    Notes:
3213:    The matrices b and x cannot be the same.  I.e., one cannot
3214:    call MatMatSolve(A,x,x).

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

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

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

3227:    Level: developer

3229:    Concepts: matrices^triangular solves

3231: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3232: @*/
3233: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
3234: {

3244:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3245:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3246:   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);
3247:   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);
3248:   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);
3249:   if (!A->rmap->N && !A->cmap->N) return(0);
3250:   MatCheckPreallocated(A,1);

3252:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3253:   if (!A->ops->matsolve) {
3254:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3255:     MatMatSolve_Basic(A,B,X);
3256:   } else {
3257:     (*A->ops->matsolve)(A,B,X);
3258:   }
3259:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3260:   PetscObjectStateIncrease((PetscObject)X);
3261:   return(0);
3262: }


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

3271:    Neighbor-wise Collective on Mat and Vec

3273:    Input Parameters:
3274: +  mat - the factored matrix
3275: -  b - the right-hand-side vector

3277:    Output Parameter:
3278: .  x - the result vector

3280:    Notes:
3281:    MatSolve() should be used for most applications, as it performs
3282:    a forward solve followed by a backward solve.

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

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

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

3297:    Level: developer

3299:    Concepts: matrices^forward solves

3301: .seealso: MatSolve(), MatBackwardSolve()
3302: @*/
3303: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
3304: {

3314:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3315:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3316:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3317:   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);
3318:   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);
3319:   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);
3320:   MatCheckPreallocated(mat,1);
3321:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3322:   (*mat->ops->forwardsolve)(mat,b,x);
3323:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3324:   PetscObjectStateIncrease((PetscObject)x);
3325:   return(0);
3326: }

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

3334:    Neighbor-wise Collective on Mat and Vec

3336:    Input Parameters:
3337: +  mat - the factored matrix
3338: -  b - the right-hand-side vector

3340:    Output Parameter:
3341: .  x - the result vector

3343:    Notes:
3344:    MatSolve() should be used for most applications, as it performs
3345:    a forward solve followed by a backward solve.

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

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

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

3360:    Level: developer

3362:    Concepts: matrices^backward solves

3364: .seealso: MatSolve(), MatForwardSolve()
3365: @*/
3366: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
3367: {

3377:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3378:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3379:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3380:   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);
3381:   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);
3382:   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);
3383:   MatCheckPreallocated(mat,1);

3385:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3386:   (*mat->ops->backwardsolve)(mat,b,x);
3387:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3388:   PetscObjectStateIncrease((PetscObject)x);
3389:   return(0);
3390: }

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

3397:    Neighbor-wise Collective on Mat and Vec

3399:    Input Parameters:
3400: +  mat - the factored matrix
3401: .  b - the right-hand-side vector
3402: -  y - the vector to be added to

3404:    Output Parameter:
3405: .  x - the result vector

3407:    Notes:
3408:    The vectors b and x cannot be the same.  I.e., one cannot
3409:    call MatSolveAdd(A,x,y,x).

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

3415:    Level: developer

3417:    Concepts: matrices^triangular solves

3419: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3420: @*/
3421: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3422: {
3423:   PetscScalar    one = 1.0;
3424:   Vec            tmp;

3436:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3437:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3438:   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);
3439:   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);
3440:   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);
3441:   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);
3442:   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);
3443:   MatCheckPreallocated(mat,1);

3445:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3446:   if (mat->ops->solveadd) {
3447:     (*mat->ops->solveadd)(mat,b,y,x);
3448:   } else {
3449:     /* do the solve then the add manually */
3450:     if (x != y) {
3451:       MatSolve(mat,b,x);
3452:       VecAXPY(x,one,y);
3453:     } else {
3454:       VecDuplicate(x,&tmp);
3455:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3456:       VecCopy(x,tmp);
3457:       MatSolve(mat,b,x);
3458:       VecAXPY(x,one,tmp);
3459:       VecDestroy(&tmp);
3460:     }
3461:   }
3462:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3463:   PetscObjectStateIncrease((PetscObject)x);
3464:   return(0);
3465: }

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

3472:    Neighbor-wise Collective on Mat and Vec

3474:    Input Parameters:
3475: +  mat - the factored matrix
3476: -  b - the right-hand-side vector

3478:    Output Parameter:
3479: .  x - the result vector

3481:    Notes:
3482:    The vectors b and x cannot be the same.  I.e., one cannot
3483:    call MatSolveTranspose(A,x,x).

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

3489:    Level: developer

3491:    Concepts: matrices^triangular solves

3493: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3494: @*/
3495: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
3496: {

3506:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3507:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3508:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3509:   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);
3510:   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);
3511:   MatCheckPreallocated(mat,1);
3512:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3513:   (*mat->ops->solvetranspose)(mat,b,x);
3514:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3515:   PetscObjectStateIncrease((PetscObject)x);
3516:   return(0);
3517: }

3521: /*@
3522:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3523:                       factored matrix.

3525:    Neighbor-wise Collective on Mat and Vec

3527:    Input Parameters:
3528: +  mat - the factored matrix
3529: .  b - the right-hand-side vector
3530: -  y - the vector to be added to

3532:    Output Parameter:
3533: .  x - the result vector

3535:    Notes:
3536:    The vectors b and x cannot be the same.  I.e., one cannot
3537:    call MatSolveTransposeAdd(A,x,y,x).

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

3543:    Level: developer

3545:    Concepts: matrices^triangular solves

3547: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3548: @*/
3549: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3550: {
3551:   PetscScalar    one = 1.0;
3553:   Vec            tmp;

3564:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3565:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3566:   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3567:   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3568:   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);
3569:   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);
3570:   MatCheckPreallocated(mat,1);

3572:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3573:   if (mat->ops->solvetransposeadd) {
3574:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3575:   } else {
3576:     /* do the solve then the add manually */
3577:     if (x != y) {
3578:       MatSolveTranspose(mat,b,x);
3579:       VecAXPY(x,one,y);
3580:     } else {
3581:       VecDuplicate(x,&tmp);
3582:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3583:       VecCopy(x,tmp);
3584:       MatSolveTranspose(mat,b,x);
3585:       VecAXPY(x,one,tmp);
3586:       VecDestroy(&tmp);
3587:     }
3588:   }
3589:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3590:   PetscObjectStateIncrease((PetscObject)x);
3591:   return(0);
3592: }
3593: /* ----------------------------------------------------------------*/

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

3600:    Neighbor-wise Collective on Mat and Vec

3602:    Input Parameters:
3603: +  mat - the matrix
3604: .  b - the right hand side
3605: .  omega - the relaxation factor
3606: .  flag - flag indicating the type of SOR (see below)
3607: .  shift -  diagonal shift
3608: .  its - the number of iterations
3609: -  lits - the number of local iterations

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

3614:    SOR Flags:
3615: .     SOR_FORWARD_SWEEP - forward SOR
3616: .     SOR_BACKWARD_SWEEP - backward SOR
3617: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3618: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3619: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3620: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3621: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3622:          upper/lower triangular part of matrix to
3623:          vector (with omega)
3624: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3626:    Notes:
3627:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3628:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3629:    on each processor.

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

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

3636:    Notes for Advanced Users:
3637:    The flags are implemented as bitwise inclusive or operations.
3638:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3639:    to specify a zero initial guess for SSOR.

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

3645:    Vectors x and b CANNOT be the same

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

3649:    Level: developer

3651:    Concepts: matrices^relaxation
3652:    Concepts: matrices^SOR
3653:    Concepts: matrices^Gauss-Seidel

3655: @*/
3656: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3657: {

3667:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3668:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3669:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3670:   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);
3671:   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);
3672:   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);
3673:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3674:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3675:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3677:   MatCheckPreallocated(mat,1);
3678:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3679:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3680:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3681:   PetscObjectStateIncrease((PetscObject)x);
3682:   return(0);
3683: }

3687: /*
3688:       Default matrix copy routine.
3689: */
3690: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3691: {
3692:   PetscErrorCode    ierr;
3693:   PetscInt          i,rstart = 0,rend = 0,nz;
3694:   const PetscInt    *cwork;
3695:   const PetscScalar *vwork;

3698:   if (B->assembled) {
3699:     MatZeroEntries(B);
3700:   }
3701:   MatGetOwnershipRange(A,&rstart,&rend);
3702:   for (i=rstart; i<rend; i++) {
3703:     MatGetRow(A,i,&nz,&cwork,&vwork);
3704:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3705:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3706:   }
3707:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3708:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3709:   PetscObjectStateIncrease((PetscObject)B);
3710:   return(0);
3711: }

3715: /*@
3716:    MatCopy - Copys a matrix to another matrix.

3718:    Collective on Mat

3720:    Input Parameters:
3721: +  A - the matrix
3722: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3724:    Output Parameter:
3725: .  B - where the copy is put

3727:    Notes:
3728:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3729:    same nonzero pattern or the routine will crash.

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

3735:    Level: intermediate

3737:    Concepts: matrices^copying

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

3741: @*/
3742: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3743: {
3745:   PetscInt       i;

3753:   MatCheckPreallocated(B,2);
3754:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3755:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3756:   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);
3757:   MatCheckPreallocated(A,1);

3759:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3760:   if (A->ops->copy) {
3761:     (*A->ops->copy)(A,B,str);
3762:   } else { /* generic conversion */
3763:     MatCopy_Basic(A,B,str);
3764:   }

3766:   B->stencil.dim = A->stencil.dim;
3767:   B->stencil.noc = A->stencil.noc;
3768:   for (i=0; i<=A->stencil.dim; i++) {
3769:     B->stencil.dims[i]   = A->stencil.dims[i];
3770:     B->stencil.starts[i] = A->stencil.starts[i];
3771:   }

3773:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3774:   PetscObjectStateIncrease((PetscObject)B);
3775:   return(0);
3776: }

3780: /*@C
3781:    MatConvert - Converts a matrix to another matrix, either of the same
3782:    or different type.

3784:    Collective on Mat

3786:    Input Parameters:
3787: +  mat - the matrix
3788: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3789:    same type as the original matrix.
3790: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3791:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3792:    MAT_INITIAL_MATRIX.

3794:    Output Parameter:
3795: .  M - pointer to place new matrix

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

3802:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3803:    the MPI communicator of the generated matrix is always the same as the communicator
3804:    of the input matrix.

3806:    Level: intermediate

3808:    Concepts: matrices^converting between storage formats

3810: .seealso: MatCopy(), MatDuplicate()
3811: @*/
3812: PetscErrorCode  MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3813: {
3815:   PetscBool      sametype,issame,flg;
3816:   char           convname[256],mtype[256];
3817:   Mat            B;

3823:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3824:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3825:   MatCheckPreallocated(mat,1);
3826:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

3828:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3829:   if (flg) {
3830:     newtype = mtype;
3831:   }
3832:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3833:   PetscStrcmp(newtype,"same",&issame);
3834:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");

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

3838:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3839:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3840:   } else {
3841:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3842:     const char     *prefix[3] = {"seq","mpi",""};
3843:     PetscInt       i;
3844:     /*
3845:        Order of precedence:
3846:        1) See if a specialized converter is known to the current matrix.
3847:        2) See if a specialized converter is known to the desired matrix class.
3848:        3) See if a good general converter is registered for the desired class
3849:           (as of 6/27/03 only MATMPIADJ falls into this category).
3850:        4) See if a good general converter is known for the current matrix.
3851:        5) Use a really basic converter.
3852:     */

3854:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3855:     for (i=0; i<3; i++) {
3856:       PetscStrcpy(convname,"MatConvert_");
3857:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3858:       PetscStrcat(convname,"_");
3859:       PetscStrcat(convname,prefix[i]);
3860:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3861:       PetscStrcat(convname,"_C");
3862:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3863:       if (conv) goto foundconv;
3864:     }

3866:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3867:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
3868:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3869:     MatSetType(B,newtype);
3870:     for (i=0; i<3; i++) {
3871:       PetscStrcpy(convname,"MatConvert_");
3872:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3873:       PetscStrcat(convname,"_");
3874:       PetscStrcat(convname,prefix[i]);
3875:       PetscStrcat(convname,newtype);
3876:       PetscStrcat(convname,"_C");
3877:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3878:       if (conv) {
3879:         MatDestroy(&B);
3880:         goto foundconv;
3881:       }
3882:     }

3884:     /* 3) See if a good general converter is registered for the desired class */
3885:     conv = B->ops->convertfrom;
3886:     MatDestroy(&B);
3887:     if (conv) goto foundconv;

3889:     /* 4) See if a good general converter is known for the current matrix */
3890:     if (mat->ops->convert) {
3891:       conv = mat->ops->convert;
3892:     }
3893:     if (conv) goto foundconv;

3895:     /* 5) Use a really basic converter. */
3896:     conv = MatConvert_Basic;

3898: foundconv:
3899:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3900:     (*conv)(mat,newtype,reuse,M);
3901:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3902:   }
3903:   PetscObjectStateIncrease((PetscObject)*M);

3905:   /* Copy Mat options */
3906:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3907:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3908:   return(0);
3909: }

3913: /*@C
3914:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3916:    Not Collective

3918:    Input Parameter:
3919: .  mat - the matrix, must be a factored matrix

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

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

3928:    Level: intermediate

3930: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3931: @*/
3932: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3933: {
3934:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

3939:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3940:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
3941:   if (!conv) {
3942:     *type = MATSOLVERPETSC;
3943:   } else {
3944:     (*conv)(mat,type);
3945:   }
3946:   return(0);
3947: }

3949: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
3950: struct _MatSolverPackageForSpecifcType {
3951:   MatType                        mtype;
3952:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
3953:   MatSolverPackageForSpecifcType next;
3954: };

3956: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
3957: struct _MatSolverPackageHolder {
3958:   char                           *name;
3959:   MatSolverPackageForSpecifcType handlers;
3960:   MatSolverPackageHolder         next;
3961: };

3963: static MatSolverPackageHolder MatSolverPackageHolders = NULL;

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

3970:    Input Parameters:
3971: +    package - name of the package, for example petsc or superlu
3972: .    mtype - the matrix type that works with this package
3973: .    ftype - the type of factorization supported by the package
3974: -    getfactor - routine that will create the factored matrix ready to be used

3976:     Level: intermediate

3978: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3979: @*/
3980: PetscErrorCode  MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
3981: {
3982:   PetscErrorCode                 ierr;
3983:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
3984:   PetscBool                      flg;
3985:   MatSolverPackageForSpecifcType inext,iprev = NULL;

3988:   if (!MatSolverPackageHolders) {
3989:     PetscNew(&MatSolverPackageHolders);
3990:     PetscStrallocpy(package,&MatSolverPackageHolders->name);
3991:     PetscNew(&MatSolverPackageHolders->handlers);
3992:     PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
3993:     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
3994:     return(0);
3995:   }
3996:   while (next) {
3997:     PetscStrcasecmp(package,next->name,&flg);
3998:     if (flg) {
3999:       inext = next->handlers;
4000:       while (inext) {
4001:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4002:         if (flg) {
4003:           inext->getfactor[(int)ftype-1] = getfactor;
4004:           return(0);
4005:         }
4006:         iprev = inext;
4007:         inext = inext->next;
4008:       }
4009:       PetscNew(&iprev->next);
4010:       PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4011:       iprev->next->getfactor[(int)ftype-1] = getfactor;
4012:       return(0);
4013:     }
4014:     prev = next;
4015:     next = next->next;
4016:   }
4017:   PetscNew(&prev->next);
4018:   PetscStrallocpy(package,&prev->next->name);
4019:   PetscNew(&prev->next->handlers);
4020:   PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4021:   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4022:   return(0);
4023: }

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

4030:    Input Parameters:
4031: +    package - name of the package, for example petsc or superlu
4032: .    ftype - the type of factorization supported by the package
4033: -    mtype - the matrix type that works with this package

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

4040:     Level: intermediate

4042: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4043: @*/
4044: PetscErrorCode  MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4045: {
4046:   PetscErrorCode                 ierr;
4047:   MatSolverPackageHolder         next = MatSolverPackageHolders;
4048:   PetscBool                      flg;
4049:   MatSolverPackageForSpecifcType inext;

4052:   if (foundpackage) *foundpackage = PETSC_FALSE;
4053:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4054:   if (getfactor)    *getfactor    = NULL;
4055:   while (next) {
4056:     PetscStrcasecmp(package,next->name,&flg);
4057:     if (flg) {
4058:       if (foundpackage) *foundpackage = PETSC_TRUE;
4059:       inext = next->handlers;
4060:       while (inext) {
4061:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4062:         if (flg) {
4063:           if (foundmtype) *foundmtype = PETSC_TRUE;
4064:           if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4065:           return(0);
4066:         }
4067:         inext = inext->next;
4068:       }
4069:     }
4070:     next = next->next;
4071:   }
4072:   return(0);
4073: }

4077: PetscErrorCode  MatSolverPackageDestroy(void)
4078: {
4079:   PetscErrorCode                 ierr;
4080:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4081:   MatSolverPackageForSpecifcType inext,iprev;

4084:   while (next) {
4085:     PetscFree(next->name);
4086:     inext = next->handlers;
4087:     while (inext) {
4088:       PetscFree(inext->mtype);
4089:       iprev = inext;
4090:       inext = inext->next;
4091:       PetscFree(iprev);
4092:     }
4093:     prev = next;
4094:     next = next->next;
4095:     PetscFree(prev);
4096:   }
4097:   MatSolverPackageHolders = NULL;
4098:   return(0);
4099: }

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

4106:    Collective on Mat

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

4113:    Output Parameters:
4114: .  f - the factor matrix used with MatXXFactorSymbolic() calls

4116:    Notes:
4117:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4118:      such as pastix, superlu, mumps etc.

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

4122:    Level: intermediate

4124: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4125: @*/
4126: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4127: {
4128:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4129:   PetscBool      foundpackage,foundmtype;


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

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

4143:   (*conv)(mat,ftype,f);
4144:   return(0);
4145: }

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

4152:    Not Collective

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

4159:    Output Parameter:
4160: .    flg - PETSC_TRUE if the factorization is available

4162:    Notes:
4163:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4164:      such as pastix, superlu, mumps etc.

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

4168:    Level: intermediate

4170: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4171: @*/
4172: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4173: {
4174:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);


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

4183:   *flg = PETSC_FALSE;
4184:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4185:   if (gconv) {
4186:     *flg = PETSC_TRUE;
4187:   }
4188:   return(0);
4189: }

4193: /*@
4194:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4196:    Collective on Mat

4198:    Input Parameters:
4199: +  mat - the matrix
4200: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4201:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

4203:    Output Parameter:
4204: .  M - pointer to place new matrix

4206:    Level: intermediate

4208:    Concepts: matrices^duplicating

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

4212: .seealso: MatCopy(), MatConvert()
4213: @*/
4214: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4215: {
4217:   Mat            B;
4218:   PetscInt       i;

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

4228:   *M = 0;
4229:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4230:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4231:   (*mat->ops->duplicate)(mat,op,M);
4232:   B    = *M;

4234:   B->stencil.dim = mat->stencil.dim;
4235:   B->stencil.noc = mat->stencil.noc;
4236:   for (i=0; i<=mat->stencil.dim; i++) {
4237:     B->stencil.dims[i]   = mat->stencil.dims[i];
4238:     B->stencil.starts[i] = mat->stencil.starts[i];
4239:   }

4241:   B->nooffproczerorows = mat->nooffproczerorows;
4242:   B->nooffprocentries  = mat->nooffprocentries;

4244:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4245:   PetscObjectStateIncrease((PetscObject)B);
4246:   return(0);
4247: }

4251: /*@
4252:    MatGetDiagonal - Gets the diagonal of a matrix.

4254:    Logically Collective on Mat and Vec

4256:    Input Parameters:
4257: +  mat - the matrix
4258: -  v - the vector for storing the diagonal

4260:    Output Parameter:
4261: .  v - the diagonal of the matrix

4263:    Level: intermediate

4265:    Note:
4266:    Currently only correct in parallel for square matrices.

4268:    Concepts: matrices^accessing diagonals

4270: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4271: @*/
4272: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
4273: {

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

4284:   (*mat->ops->getdiagonal)(mat,v);
4285:   PetscObjectStateIncrease((PetscObject)v);
4286:   return(0);
4287: }

4291: /*@
4292:    MatGetRowMin - Gets the minimum value (of the real part) of each
4293:         row of the matrix

4295:    Logically Collective on Mat and Vec

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

4300:    Output Parameter:
4301: +  v - the vector for storing the maximums
4302: -  idx - the indices of the column found for each row (optional)

4304:    Level: intermediate

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

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

4311:    Concepts: matrices^getting row maximums

4313: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4314:           MatGetRowMax()
4315: @*/
4316: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4317: {

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

4328:   (*mat->ops->getrowmin)(mat,v,idx);
4329:   PetscObjectStateIncrease((PetscObject)v);
4330:   return(0);
4331: }

4335: /*@
4336:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4337:         row of the matrix

4339:    Logically Collective on Mat and Vec

4341:    Input Parameters:
4342: .  mat - the matrix

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

4348:    Level: intermediate

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

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

4355:    Concepts: matrices^getting row maximums

4357: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4358: @*/
4359: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4360: {

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

4372:   (*mat->ops->getrowminabs)(mat,v,idx);
4373:   PetscObjectStateIncrease((PetscObject)v);
4374:   return(0);
4375: }

4379: /*@
4380:    MatGetRowMax - Gets the maximum value (of the real part) of each
4381:         row of the matrix

4383:    Logically Collective on Mat and Vec

4385:    Input Parameters:
4386: .  mat - the matrix

4388:    Output Parameter:
4389: +  v - the vector for storing the maximums
4390: -  idx - the indices of the column found for each row (optional)

4392:    Level: intermediate

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

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

4399:    Concepts: matrices^getting row maximums

4401: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4402: @*/
4403: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4404: {

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

4415:   (*mat->ops->getrowmax)(mat,v,idx);
4416:   PetscObjectStateIncrease((PetscObject)v);
4417:   return(0);
4418: }

4422: /*@
4423:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4424:         row of the matrix

4426:    Logically Collective on Mat and Vec

4428:    Input Parameters:
4429: .  mat - the matrix

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

4435:    Level: intermediate

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

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

4442:    Concepts: matrices^getting row maximums

4444: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4445: @*/
4446: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4447: {

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

4459:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4460:   PetscObjectStateIncrease((PetscObject)v);
4461:   return(0);
4462: }

4466: /*@
4467:    MatGetRowSum - Gets the sum of each row of the matrix

4469:    Logically Collective on Mat and Vec

4471:    Input Parameters:
4472: .  mat - the matrix

4474:    Output Parameter:
4475: .  v - the vector for storing the sum of rows

4477:    Level: intermediate

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

4481:    Concepts: matrices^getting row sums

4483: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4484: @*/
4485: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4486: {
4487:   PetscInt       start = 0, end = 0, row;
4488:   PetscScalar    *array;

4495:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4496:   MatCheckPreallocated(mat,1);
4497:   MatGetOwnershipRange(mat, &start, &end);
4498:   VecGetArray(v, &array);
4499:   for (row = start; row < end; ++row) {
4500:     PetscInt          ncols, col;
4501:     const PetscInt    *cols;
4502:     const PetscScalar *vals;

4504:     array[row - start] = 0.0;

4506:     MatGetRow(mat, row, &ncols, &cols, &vals);
4507:     for (col = 0; col < ncols; col++) {
4508:       array[row - start] += vals[col];
4509:     }
4510:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4511:   }
4512:   VecRestoreArray(v, &array);
4513:   PetscObjectStateIncrease((PetscObject) v);
4514:   return(0);
4515: }

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

4522:    Collective on Mat

4524:    Input Parameter:
4525: +  mat - the matrix to transpose
4526: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4528:    Output Parameters:
4529: .  B - the transpose

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

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

4536:    Level: intermediate

4538:    Concepts: matrices^transposing

4540: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4541: @*/
4542: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4543: {

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

4554:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4555:   (*mat->ops->transpose)(mat,reuse,B);
4556:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4557:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4558:   return(0);
4559: }

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

4567:    Collective on Mat

4569:    Input Parameter:
4570: +  A - the matrix to test
4571: -  B - the matrix to test against, this can equal the first parameter

4573:    Output Parameters:
4574: .  flg - the result

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

4581:    Level: intermediate

4583:    Concepts: matrices^transposing, matrix^symmetry

4585: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4586: @*/
4587: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4588: {
4589:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4595:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4596:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4597:   *flg = PETSC_FALSE;
4598:   if (f && g) {
4599:     if (f == g) {
4600:       (*f)(A,B,tol,flg);
4601:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4602:   } else {
4603:     MatType mattype;
4604:     if (!f) {
4605:       MatGetType(A,&mattype);
4606:     } else {
4607:       MatGetType(B,&mattype);
4608:     }
4609:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4610:   }
4611:   return(0);
4612: }

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

4619:    Collective on Mat

4621:    Input Parameter:
4622: +  mat - the matrix to transpose and complex conjugate
4623: -  reuse - store the transpose matrix in the provided B

4625:    Output Parameters:
4626: .  B - the Hermitian

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

4631:    Level: intermediate

4633:    Concepts: matrices^transposing, complex conjugatex

4635: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4636: @*/
4637: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4638: {

4642:   MatTranspose(mat,reuse,B);
4643: #if defined(PETSC_USE_COMPLEX)
4644:   MatConjugate(*B);
4645: #endif
4646:   return(0);
4647: }

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

4654:    Collective on Mat

4656:    Input Parameter:
4657: +  A - the matrix to test
4658: -  B - the matrix to test against, this can equal the first parameter

4660:    Output Parameters:
4661: .  flg - the result

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

4668:    Level: intermediate

4670:    Concepts: matrices^transposing, matrix^symmetry

4672: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4673: @*/
4674: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4675: {
4676:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4682:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4683:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4684:   if (f && g) {
4685:     if (f==g) {
4686:       (*f)(A,B,tol,flg);
4687:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4688:   }
4689:   return(0);
4690: }

4694: /*@
4695:    MatPermute - Creates a new matrix with rows and columns permuted from the
4696:    original.

4698:    Collective on Mat

4700:    Input Parameters:
4701: +  mat - the matrix to permute
4702: .  row - row permutation, each processor supplies only the permutation for its rows
4703: -  col - column permutation, each processor supplies only the permutation for its columns

4705:    Output Parameters:
4706: .  B - the permuted matrix

4708:    Level: advanced

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

4714:    Concepts: matrices^permuting

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

4718: @*/
4719: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4720: {

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

4734:   (*mat->ops->permute)(mat,row,col,B);
4735:   PetscObjectStateIncrease((PetscObject)*B);
4736:   return(0);
4737: }

4741: /*@
4742:    MatEqual - Compares two matrices.

4744:    Collective on Mat

4746:    Input Parameters:
4747: +  A - the first matrix
4748: -  B - the second matrix

4750:    Output Parameter:
4751: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4753:    Level: intermediate

4755:    Concepts: matrices^equality between
4756: @*/
4757: PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4758: {

4768:   MatCheckPreallocated(B,2);
4769:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4770:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4771:   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);
4772:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4773:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4774:   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);
4775:   MatCheckPreallocated(A,1);

4777:   (*A->ops->equal)(A,B,flg);
4778:   return(0);
4779: }

4783: /*@
4784:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4785:    matrices that are stored as vectors.  Either of the two scaling
4786:    matrices can be NULL.

4788:    Collective on Mat

4790:    Input Parameters:
4791: +  mat - the matrix to be scaled
4792: .  l - the left scaling vector (or NULL)
4793: -  r - the right scaling vector (or NULL)

4795:    Notes:
4796:    MatDiagonalScale() computes A = LAR, where
4797:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4798:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4800:    Level: intermediate

4802:    Concepts: matrices^diagonal scaling
4803:    Concepts: diagonal scaling of matrices

4805: .seealso: MatScale()
4806: @*/
4807: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4808: {

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

4821:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4822:   (*mat->ops->diagonalscale)(mat,l,r);
4823:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4824:   PetscObjectStateIncrease((PetscObject)mat);
4825: #if defined(PETSC_HAVE_CUSP)
4826:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4827:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4828:   }
4829: #endif
4830: #if defined(PETSC_HAVE_VIENNACL)
4831:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4832:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4833:   }
4834: #endif
4835:   return(0);
4836: }

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

4843:     Logically Collective on Mat

4845:     Input Parameters:
4846: +   mat - the matrix to be scaled
4847: -   a  - the scaling value

4849:     Output Parameter:
4850: .   mat - the scaled matrix

4852:     Level: intermediate

4854:     Concepts: matrices^scaling all entries

4856: .seealso: MatDiagonalScale()
4857: @*/
4858: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4859: {

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

4871:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4872:   if (a != (PetscScalar)1.0) {
4873:     (*mat->ops->scale)(mat,a);
4874:     PetscObjectStateIncrease((PetscObject)mat);
4875:   }
4876:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4877: #if defined(PETSC_HAVE_CUSP)
4878:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4879:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4880:   }
4881: #endif
4882: #if defined(PETSC_HAVE_VIENNACL)
4883:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4884:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4885:   }
4886: #endif
4887:   return(0);
4888: }

4892: /*@
4893:    MatNorm - Calculates various norms of a matrix.

4895:    Collective on Mat

4897:    Input Parameters:
4898: +  mat - the matrix
4899: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4901:    Output Parameters:
4902: .  nrm - the resulting norm

4904:    Level: intermediate

4906:    Concepts: matrices^norm
4907:    Concepts: norm^of matrix
4908: @*/
4909: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4910: {


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

4923:   (*mat->ops->norm)(mat,type,nrm);
4924:   return(0);
4925: }

4927: /*
4928:      This variable is used to prevent counting of MatAssemblyBegin() that
4929:    are called from within a MatAssemblyEnd().
4930: */
4931: static PetscInt MatAssemblyEnd_InUse = 0;
4934: /*@
4935:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4936:    be called after completing all calls to MatSetValues().

4938:    Collective on Mat

4940:    Input Parameters:
4941: +  mat - the matrix
4942: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4944:    Notes:
4945:    MatSetValues() generally caches the values.  The matrix is ready to
4946:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4947:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4948:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4949:    using the matrix.

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

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

4959:    Level: beginner

4961:    Concepts: matrices^assembling

4963: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4964: @*/
4965: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4966: {

4972:   MatCheckPreallocated(mat,1);
4973:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4974:   if (mat->assembled) {
4975:     mat->was_assembled = PETSC_TRUE;
4976:     mat->assembled     = PETSC_FALSE;
4977:   }
4978:   if (!MatAssemblyEnd_InUse) {
4979:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4980:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
4981:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4982:   } else if (mat->ops->assemblybegin) {
4983:     (*mat->ops->assemblybegin)(mat,type);
4984:   }
4985:   return(0);
4986: }

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

4994:    Not Collective

4996:    Input Parameter:
4997: .  mat - the matrix

4999:    Output Parameter:
5000: .  assembled - PETSC_TRUE or PETSC_FALSE

5002:    Level: advanced

5004:    Concepts: matrices^assembled?

5006: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5007: @*/
5008: PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
5009: {
5014:   *assembled = mat->assembled;
5015:   return(0);
5016: }

5020: /*@
5021:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5022:    be called after MatAssemblyBegin().

5024:    Collective on Mat

5026:    Input Parameters:
5027: +  mat - the matrix
5028: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5030:    Options Database Keys:
5031: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5032: .  -mat_view ::ascii_info_detail - Prints more detailed info
5033: .  -mat_view - Prints matrix in ASCII format
5034: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5035: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5036: .  -display <name> - Sets display name (default is host)
5037: .  -draw_pause <sec> - Sets number of seconds to pause after display
5038: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 10 Using MATLAB with PETSc )
5039: .  -viewer_socket_machine <machine>
5040: .  -viewer_socket_port <port>
5041: .  -mat_view binary - save matrix to file in binary format
5042: -  -viewer_binary_filename <name>

5044:    Notes:
5045:    MatSetValues() generally caches the values.  The matrix is ready to
5046:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5047:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5048:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5049:    using the matrix.

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

5055:    Level: beginner

5057: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5058: @*/
5059: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
5060: {
5061:   PetscErrorCode  ierr;
5062:   static PetscInt inassm = 0;
5063:   PetscBool       flg    = PETSC_FALSE;


5069:   inassm++;
5070:   MatAssemblyEnd_InUse++;
5071:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5072:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5073:     if (mat->ops->assemblyend) {
5074:       (*mat->ops->assemblyend)(mat,type);
5075:     }
5076:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5077:   } else if (mat->ops->assemblyend) {
5078:     (*mat->ops->assemblyend)(mat,type);
5079:   }

5081:   /* Flush assembly is not a true assembly */
5082:   if (type != MAT_FLUSH_ASSEMBLY) {
5083:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5084:   }
5085:   mat->insertmode = NOT_SET_VALUES;
5086:   MatAssemblyEnd_InUse--;
5087:   PetscObjectStateIncrease((PetscObject)mat);
5088:   if (!mat->symmetric_eternal) {
5089:     mat->symmetric_set              = PETSC_FALSE;
5090:     mat->hermitian_set              = PETSC_FALSE;
5091:     mat->structurally_symmetric_set = PETSC_FALSE;
5092:   }
5093: #if defined(PETSC_HAVE_CUSP)
5094:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5095:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5096:   }
5097: #endif
5098: #if defined(PETSC_HAVE_VIENNACL)
5099:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5100:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5101:   }
5102: #endif
5103:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5104:     MatViewFromOptions(mat,NULL,"-mat_view");

5106:     if (mat->checksymmetryonassembly) {
5107:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5108:       if (flg) {
5109:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5110:       } else {
5111:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5112:       }
5113:     }
5114:     if (mat->nullsp && mat->checknullspaceonassembly) {
5115:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5116:     }
5117:   }
5118:   inassm--;
5119:   return(0);
5120: }

5124: /*@
5125:    MatSetOption - Sets a parameter option for a matrix. Some options
5126:    may be specific to certain storage formats.  Some options
5127:    determine how values will be inserted (or added). Sorted,
5128:    row-oriented input will generally assemble the fastest. The default
5129:    is row-oriented.

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

5133:    Input Parameters:
5134: +  mat - the matrix
5135: .  option - the option, one of those listed below (and possibly others),
5136: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5138:   Options Describing Matrix Structure:
5139: +    MAT_SPD - symmetric positive definite
5140: -    MAT_SYMMETRIC - symmetric in terms of both structure and value
5141: .    MAT_HERMITIAN - transpose is the complex conjugation
5142: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5143: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5144:                             you set to be kept with all future use of the matrix
5145:                             including after MatAssemblyBegin/End() which could
5146:                             potentially change the symmetry structure, i.e. you
5147:                             KNOW the matrix will ALWAYS have the property you set.


5150:    Options For Use with MatSetValues():
5151:    Insert a logically dense subblock, which can be
5152: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

5169:    Notes:
5170:    Some options are relevant only for particular matrix types and
5171:    are thus ignored by others.  Other options are not supported by
5172:    certain matrix types and will generate an error message if set.

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

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

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

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

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

5200:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5201:    searches during matrix assembly. When this flag is set, the hash table
5202:    is created during the first Matrix Assembly. This hash table is
5203:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5204:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5205:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5206:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5225:    Level: intermediate

5227:    Concepts: matrices^setting options

5229: .seealso:  MatOption, Mat

5231: @*/
5232: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool flg)
5233: {

5239:   if (op > 0) {
5242:   }

5244:   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);
5245:   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()");

5247:   switch (op) {
5248:   case MAT_NO_OFF_PROC_ENTRIES:
5249:     mat->nooffprocentries = flg;
5250:     return(0);
5251:     break;
5252:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5253:     mat->nooffproczerorows = flg;
5254:     return(0);
5255:     break;
5256:   case MAT_SPD:
5257:     mat->spd_set = PETSC_TRUE;
5258:     mat->spd     = flg;
5259:     if (flg) {
5260:       mat->symmetric                  = PETSC_TRUE;
5261:       mat->structurally_symmetric     = PETSC_TRUE;
5262:       mat->symmetric_set              = PETSC_TRUE;
5263:       mat->structurally_symmetric_set = PETSC_TRUE;
5264:     }
5265:     break;
5266:   case MAT_SYMMETRIC:
5267:     mat->symmetric = flg;
5268:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5269:     mat->symmetric_set              = PETSC_TRUE;
5270:     mat->structurally_symmetric_set = flg;
5271:     break;
5272:   case MAT_HERMITIAN:
5273:     mat->hermitian = flg;
5274:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5275:     mat->hermitian_set              = PETSC_TRUE;
5276:     mat->structurally_symmetric_set = flg;
5277:     break;
5278:   case MAT_STRUCTURALLY_SYMMETRIC:
5279:     mat->structurally_symmetric     = flg;
5280:     mat->structurally_symmetric_set = PETSC_TRUE;
5281:     break;
5282:   case MAT_SYMMETRY_ETERNAL:
5283:     mat->symmetric_eternal = flg;
5284:     break;
5285:   default:
5286:     break;
5287:   }
5288:   if (mat->ops->setoption) {
5289:     (*mat->ops->setoption)(mat,op,flg);
5290:   }
5291:   return(0);
5292: }

5296: /*@
5297:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5298:    this routine retains the old nonzero structure.

5300:    Logically Collective on Mat

5302:    Input Parameters:
5303: .  mat - the matrix

5305:    Level: intermediate

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

5310:    Concepts: matrices^zeroing

5312: .seealso: MatZeroRows()
5313: @*/
5314: PetscErrorCode  MatZeroEntries(Mat mat)
5315: {

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

5326:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5327:   (*mat->ops->zeroentries)(mat);
5328:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5329:   PetscObjectStateIncrease((PetscObject)mat);
5330: #if defined(PETSC_HAVE_CUSP)
5331:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5332:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5333:   }
5334: #endif
5335: #if defined(PETSC_HAVE_VIENNACL)
5336:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5337:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5338:   }
5339: #endif
5340:   return(0);
5341: }

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

5349:    Collective on Mat

5351:    Input Parameters:
5352: +  mat - the matrix
5353: .  numRows - the number of rows to remove
5354: .  rows - the global row indices
5355: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5356: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5357: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5376:    Level: intermediate

5378:    Concepts: matrices^zeroing rows

5380: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5381: @*/
5382: PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5383: {

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

5395:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5396:   MatViewFromOptions(mat,NULL,"-mat_view");
5397:   PetscObjectStateIncrease((PetscObject)mat);
5398: #if defined(PETSC_HAVE_CUSP)
5399:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5400:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5401:   }
5402: #endif
5403: #if defined(PETSC_HAVE_VIENNACL)
5404:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5405:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5406:   }
5407: #endif
5408:   return(0);
5409: }

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

5417:    Collective on Mat

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

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

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

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

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

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

5443:    Level: intermediate

5445:    Concepts: matrices^zeroing rows

5447: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5448: @*/
5449: PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5450: {
5452:   PetscInt       numRows;
5453:   const PetscInt *rows;

5460:   ISGetLocalSize(is,&numRows);
5461:   ISGetIndices(is,&rows);
5462:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5463:   ISRestoreIndices(is,&rows);
5464:   return(0);
5465: }

5469: /*@C
5470:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5471:    of a set of rows of a matrix.

5473:    Collective on Mat

5475:    Input Parameters:
5476: +  mat - the matrix
5477: .  numRows - the number of rows to remove
5478: .  rows - the global row indices
5479: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5480: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5481: -  b - optional vector of right hand side, that will be adjusted by provided solution

5483:    Notes:
5484:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5485:    but does not release memory.  For the dense and block diagonal
5486:    formats this does not alter the nonzero structure.

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

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

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

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

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

5507:    Level: intermediate

5509:    Concepts: matrices^zeroing rows

5511: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5512: @*/
5513: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5514: {

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

5526:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5527:   MatViewFromOptions(mat,NULL,"-mat_view");
5528:   PetscObjectStateIncrease((PetscObject)mat);
5529: #if defined(PETSC_HAVE_CUSP)
5530:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5531:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5532:   }
5533: #endif
5534: #if defined(PETSC_HAVE_VIENNACL)
5535:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5536:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5537:   }
5538: #endif
5539:   return(0);
5540: }

5544: /*@C
5545:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5546:    of a set of rows of a matrix.

5548:    Collective on Mat

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

5557:    Notes:
5558:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5559:    but does not release memory.  For the dense and block diagonal
5560:    formats this does not alter the nonzero structure.

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

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

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

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

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

5581:    Level: intermediate

5583:    Concepts: matrices^zeroing rows

5585: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5586: @*/
5587: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5588: {
5589:   PetscInt       numRows;
5590:   const PetscInt *rows;

5597:   ISGetLocalSize(is,&numRows);
5598:   ISGetIndices(is,&rows);
5599:   MatZeroRows(mat,numRows,rows,diag,x,b);
5600:   ISRestoreIndices(is,&rows);
5601:   return(0);
5602: }

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

5610:    Collective on Mat

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

5620:    Notes:
5621:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5622:    but does not release memory.  For the dense and block diagonal
5623:    formats this does not alter the nonzero structure.

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

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

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

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

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

5643:    In Fortran idxm and idxn should be declared as
5644: $     MatStencil idxm(4,m)
5645:    and the values inserted using
5646: $    idxm(MatStencil_i,1) = i
5647: $    idxm(MatStencil_j,1) = j
5648: $    idxm(MatStencil_k,1) = k
5649: $    idxm(MatStencil_c,1) = c
5650:    etc

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

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

5660:    Level: intermediate

5662:    Concepts: matrices^zeroing rows

5664: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5665: @*/
5666: PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5667: {
5668:   PetscInt       dim     = mat->stencil.dim;
5669:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5670:   PetscInt       *dims   = mat->stencil.dims+1;
5671:   PetscInt       *starts = mat->stencil.starts;
5672:   PetscInt       *dxm    = (PetscInt*) rows;
5673:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5681:   PetscMalloc1(numRows, &jdxm);
5682:   for (i = 0; i < numRows; ++i) {
5683:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5684:     for (j = 0; j < 3-sdim; ++j) dxm++;
5685:     /* Local index in X dir */
5686:     tmp = *dxm++ - starts[0];
5687:     /* Loop over remaining dimensions */
5688:     for (j = 0; j < dim-1; ++j) {
5689:       /* If nonlocal, set index to be negative */
5690:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5691:       /* Update local index */
5692:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5693:     }
5694:     /* Skip component slot if necessary */
5695:     if (mat->stencil.noc) dxm++;
5696:     /* Local row number */
5697:     if (tmp >= 0) {
5698:       jdxm[numNewRows++] = tmp;
5699:     }
5700:   }
5701:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5702:   PetscFree(jdxm);
5703:   return(0);
5704: }

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

5712:    Collective on Mat

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

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

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

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

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

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

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

5745:    In Fortran idxm and idxn should be declared as
5746: $     MatStencil idxm(4,m)
5747:    and the values inserted using
5748: $    idxm(MatStencil_i,1) = i
5749: $    idxm(MatStencil_j,1) = j
5750: $    idxm(MatStencil_k,1) = k
5751: $    idxm(MatStencil_c,1) = c
5752:    etc

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

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

5762:    Level: intermediate

5764:    Concepts: matrices^zeroing rows

5766: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5767: @*/
5768: PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5769: {
5770:   PetscInt       dim     = mat->stencil.dim;
5771:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5772:   PetscInt       *dims   = mat->stencil.dims+1;
5773:   PetscInt       *starts = mat->stencil.starts;
5774:   PetscInt       *dxm    = (PetscInt*) rows;
5775:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5783:   PetscMalloc1(numRows, &jdxm);
5784:   for (i = 0; i < numRows; ++i) {
5785:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5786:     for (j = 0; j < 3-sdim; ++j) dxm++;
5787:     /* Local index in X dir */
5788:     tmp = *dxm++ - starts[0];
5789:     /* Loop over remaining dimensions */
5790:     for (j = 0; j < dim-1; ++j) {
5791:       /* If nonlocal, set index to be negative */
5792:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5793:       /* Update local index */
5794:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5795:     }
5796:     /* Skip component slot if necessary */
5797:     if (mat->stencil.noc) dxm++;
5798:     /* Local row number */
5799:     if (tmp >= 0) {
5800:       jdxm[numNewRows++] = tmp;
5801:     }
5802:   }
5803:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5804:   PetscFree(jdxm);
5805:   return(0);
5806: }

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

5814:    Collective on Mat

5816:    Input Parameters:
5817: +  mat - the matrix
5818: .  numRows - the number of rows to remove
5819: .  rows - the global row indices
5820: .  diag - value put in all diagonals of eliminated rows
5821: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5822: -  b - optional vector of right hand side, that will be adjusted by provided solution

5824:    Notes:
5825:    Before calling MatZeroRowsLocal(), the user must first set the
5826:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5828:    For the AIJ matrix formats this removes the old nonzero structure,
5829:    but does not release memory.  For the dense and block diagonal
5830:    formats this does not alter the nonzero structure.

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

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

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

5843:    Level: intermediate

5845:    Concepts: matrices^zeroing

5847: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5848: @*/
5849: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5850: {

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

5861:   if (mat->ops->zerorowslocal) {
5862:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5863:   } else {
5864:     IS             is, newis;
5865:     const PetscInt *newRows;

5867:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5868:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5869:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5870:     ISGetIndices(newis,&newRows);
5871:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5872:     ISRestoreIndices(newis,&newRows);
5873:     ISDestroy(&newis);
5874:     ISDestroy(&is);
5875:   }
5876:   PetscObjectStateIncrease((PetscObject)mat);
5877: #if defined(PETSC_HAVE_CUSP)
5878:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5879:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5880:   }
5881: #endif
5882: #if defined(PETSC_HAVE_VIENNACL)
5883:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5884:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5885:   }
5886: #endif
5887:   return(0);
5888: }

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

5896:    Collective on Mat

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

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

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

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

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

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

5924:    Level: intermediate

5926:    Concepts: matrices^zeroing

5928: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5929: @*/
5930: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5931: {
5933:   PetscInt       numRows;
5934:   const PetscInt *rows;

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

5944:   ISGetLocalSize(is,&numRows);
5945:   ISGetIndices(is,&rows);
5946:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5947:   ISRestoreIndices(is,&rows);
5948:   return(0);
5949: }

5953: /*@C
5954:    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5955:    of a set of rows and columns 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 MatZeroRowsColumnsLocal(), the user must first set the
5969:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5975:    Level: intermediate

5977:    Concepts: matrices^zeroing

5979: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5980: @*/
5981: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5982: {
5984:   IS             is, newis;
5985:   const PetscInt *newRows;

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

5995:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5996:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5997:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5998:   ISGetIndices(newis,&newRows);
5999:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6000:   ISRestoreIndices(newis,&newRows);
6001:   ISDestroy(&newis);
6002:   ISDestroy(&is);
6003:   PetscObjectStateIncrease((PetscObject)mat);
6004: #if defined(PETSC_HAVE_CUSP)
6005:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6006:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6007:   }
6008: #endif
6009: #if defined(PETSC_HAVE_VIENNACL)
6010:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6011:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6012:   }
6013: #endif
6014:   return(0);
6015: }

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

6023:    Collective on Mat

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

6032:    Notes:
6033:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6034:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6040:    Level: intermediate

6042:    Concepts: matrices^zeroing

6044: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6045: @*/
6046: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6047: {
6049:   PetscInt       numRows;
6050:   const PetscInt *rows;

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

6060:   ISGetLocalSize(is,&numRows);
6061:   ISGetIndices(is,&rows);
6062:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6063:   ISRestoreIndices(is,&rows);
6064:   return(0);
6065: }

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

6072:    Not Collective

6074:    Input Parameter:
6075: .  mat - the matrix

6077:    Output Parameters:
6078: +  m - the number of global rows
6079: -  n - the number of global columns

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

6083:    Level: beginner

6085:    Concepts: matrices^size

6087: .seealso: MatGetLocalSize()
6088: @*/
6089: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6090: {
6093:   if (m) *m = mat->rmap->N;
6094:   if (n) *n = mat->cmap->N;
6095:   return(0);
6096: }

6100: /*@
6101:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6102:    stored locally.  This information may be implementation dependent, so
6103:    use with care.

6105:    Not Collective

6107:    Input Parameters:
6108: .  mat - the matrix

6110:    Output Parameters:
6111: +  m - the number of local rows
6112: -  n - the number of local columns

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

6116:    Level: beginner

6118:    Concepts: matrices^local size

6120: .seealso: MatGetSize()
6121: @*/
6122: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6123: {
6128:   if (m) *m = mat->rmap->n;
6129:   if (n) *n = mat->cmap->n;
6130:   return(0);
6131: }

6135: /*@
6136:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6137:    this processor. (The columns of the "diagonal block")

6139:    Not Collective, unless matrix has not been allocated, then collective on Mat

6141:    Input Parameters:
6142: .  mat - the matrix

6144:    Output Parameters:
6145: +  m - the global index of the first local column
6146: -  n - one more than the global index of the last local column

6148:    Notes: both output parameters can be NULL on input.

6150:    Level: developer

6152:    Concepts: matrices^column ownership

6154: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

6156: @*/
6157: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6158: {
6164:   MatCheckPreallocated(mat,1);
6165:   if (m) *m = mat->cmap->rstart;
6166:   if (n) *n = mat->cmap->rend;
6167:   return(0);
6168: }

6172: /*@
6173:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6174:    this processor, assuming that the matrix is laid out with the first
6175:    n1 rows on the first processor, the next n2 rows on the second, etc.
6176:    For certain parallel layouts this range may not be well defined.

6178:    Not Collective

6180:    Input Parameters:
6181: .  mat - the matrix

6183:    Output Parameters:
6184: +  m - the global index of the first local row
6185: -  n - one more than the global index of the last local row

6187:    Note: Both output parameters can be NULL on input.
6188: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6189: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6190: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

6192:    Level: beginner

6194:    Concepts: matrices^row ownership

6196: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

6198: @*/
6199: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6200: {
6206:   MatCheckPreallocated(mat,1);
6207:   if (m) *m = mat->rmap->rstart;
6208:   if (n) *n = mat->rmap->rend;
6209:   return(0);
6210: }

6214: /*@C
6215:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6216:    each process

6218:    Not Collective, unless matrix has not been allocated, then collective on Mat

6220:    Input Parameters:
6221: .  mat - the matrix

6223:    Output Parameters:
6224: .  ranges - start of each processors portion plus one more then the total length at the end

6226:    Level: beginner

6228:    Concepts: matrices^row ownership

6230: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6232: @*/
6233: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6234: {

6240:   MatCheckPreallocated(mat,1);
6241:   PetscLayoutGetRanges(mat->rmap,ranges);
6242:   return(0);
6243: }

6247: /*@C
6248:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6249:    this processor. (The columns of the "diagonal blocks" for each process)

6251:    Not Collective, unless matrix has not been allocated, then collective on Mat

6253:    Input Parameters:
6254: .  mat - the matrix

6256:    Output Parameters:
6257: .  ranges - start of each processors portion plus one more then the total length at the end

6259:    Level: beginner

6261:    Concepts: matrices^column ownership

6263: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6265: @*/
6266: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6267: {

6273:   MatCheckPreallocated(mat,1);
6274:   PetscLayoutGetRanges(mat->cmap,ranges);
6275:   return(0);
6276: }

6280: /*@C
6281:    MatGetOwnershipIS - Get row and column ownership as index sets

6283:    Not Collective

6285:    Input Arguments:
6286: .  A - matrix of type Elemental

6288:    Output Arguments:
6289: +  rows - rows in which this process owns elements
6290: .  cols - columns in which this process owns elements

6292:    Level: intermediate

6294: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6295: @*/
6296: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6297: {
6298:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6301:   MatCheckPreallocated(A,1);
6302:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6303:   if (f) {
6304:     (*f)(A,rows,cols);
6305:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6306:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6307:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6308:   }
6309:   return(0);
6310: }

6314: /*@C
6315:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6316:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6317:    to complete the factorization.

6319:    Collective on Mat

6321:    Input Parameters:
6322: +  mat - the matrix
6323: .  row - row permutation
6324: .  column - column permutation
6325: -  info - structure containing
6326: $      levels - number of levels of fill.
6327: $      expected fill - as ratio of original fill.
6328: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6329:                 missing diagonal entries)

6331:    Output Parameters:
6332: .  fact - new matrix that has been symbolically factored

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

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

6340:    Level: developer

6342:   Concepts: matrices^symbolic LU factorization
6343:   Concepts: matrices^factorization
6344:   Concepts: LU^symbolic factorization

6346: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6347:           MatGetOrdering(), MatFactorInfo

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

6352: @*/
6353: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6354: {

6364:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6365:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6366:   if (!(fact)->ops->ilufactorsymbolic) {
6367:     const MatSolverPackage spackage;
6368:     MatFactorGetSolverPackage(fact,&spackage);
6369:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6370:   }
6371:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6372:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6373:   MatCheckPreallocated(mat,2);

6375:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6376:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6377:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6378:   return(0);
6379: }

6383: /*@C
6384:    MatICCFactorSymbolic - Performs symbolic incomplete
6385:    Cholesky factorization for a symmetric matrix.  Use
6386:    MatCholeskyFactorNumeric() to complete the factorization.

6388:    Collective on Mat

6390:    Input Parameters:
6391: +  mat - the matrix
6392: .  perm - row and column permutation
6393: -  info - structure containing
6394: $      levels - number of levels of fill.
6395: $      expected fill - as ratio of original fill.

6397:    Output Parameter:
6398: .  fact - the factored matrix

6400:    Notes:
6401:    Most users should employ the KSP interface for linear solvers
6402:    instead of working directly with matrix algebra routines such as this.
6403:    See, e.g., KSPCreate().

6405:    Level: developer

6407:   Concepts: matrices^symbolic incomplete Cholesky factorization
6408:   Concepts: matrices^factorization
6409:   Concepts: Cholsky^symbolic factorization

6411: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

6416: @*/
6417: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6418: {

6427:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6428:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6429:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6430:   if (!(fact)->ops->iccfactorsymbolic) {
6431:     const MatSolverPackage spackage;
6432:     MatFactorGetSolverPackage(fact,&spackage);
6433:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6434:   }
6435:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6436:   MatCheckPreallocated(mat,2);

6438:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6439:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6440:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6441:   return(0);
6442: }

6446: /*@C
6447:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6448:    points to an array of valid matrices, they may be reused to store the new
6449:    submatrices.

6451:    Collective on Mat

6453:    Input Parameters:
6454: +  mat - the matrix
6455: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6456: .  irow, icol - index sets of rows and columns to extract (must be sorted)
6457: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6459:    Output Parameter:
6460: .  submat - the array of submatrices

6462:    Notes:
6463:    MatGetSubMatrices() can extract ONLY sequential submatrices
6464:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6465:    to extract a parallel submatrix.

6467:    Currently both row and column indices must be sorted to guarantee
6468:    correctness with all matrix types.

6470:    When extracting submatrices from a parallel matrix, each processor can
6471:    form a different submatrix by setting the rows and columns of its
6472:    individual index sets according to the local submatrix desired.

6474:    When finished using the submatrices, the user should destroy
6475:    them with MatDestroyMatrices().

6477:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6478:    original matrix has not changed from that last call to MatGetSubMatrices().

6480:    This routine creates the matrices in submat; you should NOT create them before
6481:    calling it. It also allocates the array of matrix pointers submat.

6483:    For BAIJ matrices the index sets must respect the block structure, that is if they
6484:    request one row/column in a block, they must request all rows/columns that are in
6485:    that block. For example, if the block size is 2 you cannot request just row 0 and
6486:    column 0.

6488:    Fortran Note:
6489:    The Fortran interface is slightly different from that given below; it
6490:    requires one to pass in  as submat a Mat (integer) array of size at least m.

6492:    Level: advanced

6494:    Concepts: matrices^accessing submatrices
6495:    Concepts: submatrices

6497: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6498: @*/
6499: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6500: {
6502:   PetscInt       i;
6503:   PetscBool      eq;

6508:   if (n) {
6513:   }
6515:   if (n && scall == MAT_REUSE_MATRIX) {
6518:   }
6519:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6520:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6521:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6522:   MatCheckPreallocated(mat,1);

6524:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6525:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6526:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6527:   for (i=0; i<n; i++) {
6528:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6529:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6530:       ISEqual(irow[i],icol[i],&eq);
6531:       if (eq) {
6532:         if (mat->symmetric) {
6533:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6534:         } else if (mat->hermitian) {
6535:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6536:         } else if (mat->structurally_symmetric) {
6537:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6538:         }
6539:       }
6540:     }
6541:   }
6542:   return(0);
6543: }

6547: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6548: {
6550:   PetscInt       i;
6551:   PetscBool      eq;

6556:   if (n) {
6561:   }
6563:   if (n && scall == MAT_REUSE_MATRIX) {
6566:   }
6567:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6568:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6569:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6570:   MatCheckPreallocated(mat,1);

6572:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6573:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6574:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6575:   for (i=0; i<n; i++) {
6576:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6577:       ISEqual(irow[i],icol[i],&eq);
6578:       if (eq) {
6579:         if (mat->symmetric) {
6580:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6581:         } else if (mat->hermitian) {
6582:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6583:         } else if (mat->structurally_symmetric) {
6584:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6585:         }
6586:       }
6587:     }
6588:   }
6589:   return(0);
6590: }

6594: /*@C
6595:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().

6597:    Collective on Mat

6599:    Input Parameters:
6600: +  n - the number of local matrices
6601: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6602:                        sequence of MatGetSubMatrices())

6604:    Level: advanced

6606:     Notes: Frees not only the matrices, but also the array that contains the matrices
6607:            In Fortran will not free the array.

6609: .seealso: MatGetSubMatrices()
6610: @*/
6611: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6612: {
6614:   PetscInt       i;

6617:   if (!*mat) return(0);
6618:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6620:   for (i=0; i<n; i++) {
6621:     MatDestroy(&(*mat)[i]);
6622:   }
6623:   /* memory is allocated even if n = 0 */
6624:   PetscFree(*mat);
6625:   *mat = NULL;
6626:   return(0);
6627: }

6631: /*@C
6632:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.

6634:    Collective on Mat

6636:    Input Parameters:
6637: .  mat - the matrix

6639:    Output Parameter:
6640: .  matstruct - the sequential matrix with the nonzero structure of mat

6642:   Level: intermediate

6644: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6645: @*/
6646: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6647: {


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

6658:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6659:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6660:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6661:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6662:   return(0);
6663: }

6667: /*@C
6668:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6670:    Collective on Mat

6672:    Input Parameters:
6673: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6674:                        sequence of MatGetSequentialNonzeroStructure())

6676:    Level: advanced

6678:     Notes: Frees not only the matrices, but also the array that contains the matrices

6680: .seealso: MatGetSeqNonzeroStructure()
6681: @*/
6682: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6683: {

6688:   MatDestroy(mat);
6689:   return(0);
6690: }

6694: /*@
6695:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6696:    replaces the index sets by larger ones that represent submatrices with
6697:    additional overlap.

6699:    Collective on Mat

6701:    Input Parameters:
6702: +  mat - the matrix
6703: .  n   - the number of index sets
6704: .  is  - the array of index sets (these index sets will changed during the call)
6705: -  ov  - the additional overlap requested

6707:    Level: developer

6709:    Concepts: overlap
6710:    Concepts: ASM^computing overlap

6712: .seealso: MatGetSubMatrices()
6713: @*/
6714: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6715: {

6721:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6722:   if (n) {
6725:   }
6726:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6727:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6728:   MatCheckPreallocated(mat,1);

6730:   if (!ov) return(0);
6731:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6732:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6733:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6734:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6735:   return(0);
6736: }

6740: /*@
6741:    MatGetBlockSize - Returns the matrix block size.

6743:    Not Collective

6745:    Input Parameter:
6746: .  mat - the matrix

6748:    Output Parameter:
6749: .  bs - block size

6751:    Notes:
6752:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

6754:    If the block size has not been set yet this routine returns 1.

6756:    Level: intermediate

6758:    Concepts: matrices^block size

6760: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6761: @*/
6762: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6763: {
6767:   *bs = PetscAbs(mat->rmap->bs);
6768:   return(0);
6769: }

6773: /*@
6774:    MatGetBlockSizes - Returns the matrix block row and column sizes.

6776:    Not Collective

6778:    Input Parameter:
6779: .  mat - the matrix

6781:    Output Parameter:
6782: .  rbs - row block size
6783: .  cbs - coumn block size

6785:    Notes:
6786:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6787:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

6789:    If a block size has not been set yet this routine returns 1.

6791:    Level: intermediate

6793:    Concepts: matrices^block size

6795: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
6796: @*/
6797: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6798: {
6803:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
6804:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
6805:   return(0);
6806: }

6810: /*@
6811:    MatSetBlockSize - Sets the matrix block size.

6813:    Logically Collective on Mat

6815:    Input Parameters:
6816: +  mat - the matrix
6817: -  bs - block size

6819:    Notes:
6820:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

6822:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6824:    Level: intermediate

6826:    Concepts: matrices^block size

6828: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
6829: @*/
6830: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6831: {

6837:   PetscLayoutSetBlockSize(mat->rmap,bs);
6838:   PetscLayoutSetBlockSize(mat->cmap,bs);
6839:   return(0);
6840: }

6844: /*@
6845:    MatSetBlockSizes - Sets the matrix block row and column sizes.

6847:    Logically Collective on Mat

6849:    Input Parameters:
6850: +  mat - the matrix
6851: -  rbs - row block size
6852: -  cbs - column block size

6854:    Notes:
6855:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6856:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

6858:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6860:     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().

6862:    Level: intermediate

6864:    Concepts: matrices^block size

6866: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
6867: @*/
6868: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6869: {

6876:   PetscLayoutSetBlockSize(mat->rmap,rbs);
6877:   PetscLayoutSetBlockSize(mat->cmap,cbs);
6878:   return(0);
6879: }

6883: /*@
6884:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

6886:    Logically Collective on Mat

6888:    Input Parameters:
6889: +  mat - the matrix
6890: .  fromRow - matrix from which to copy row block size
6891: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

6893:    Level: developer

6895:    Concepts: matrices^block size

6897: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
6898: @*/
6899: PetscErrorCode  MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
6900: {

6907:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
6908:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
6909:   return(0);
6910: }

6914: /*@
6915:    MatResidual - Default routine to calculate the residual.

6917:    Collective on Mat and Vec

6919:    Input Parameters:
6920: +  mat - the matrix
6921: .  b   - the right-hand-side
6922: -  x   - the approximate solution

6924:    Output Parameter:
6925: .  r - location to store the residual

6927:    Level: developer

6929: .keywords: MG, default, multigrid, residual

6931: .seealso: PCMGSetResidual()
6932: @*/
6933: PetscErrorCode  MatResidual(Mat mat,Vec b,Vec x,Vec r)
6934: {

6943:   MatCheckPreallocated(mat,1);
6944:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
6945:   if (!mat->ops->residual) {
6946:     MatMult(mat,x,r);
6947:     VecAYPX(r,-1.0,b);
6948:   } else {
6949:     (*mat->ops->residual)(mat,b,x,r);
6950:   }
6951:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
6952:   return(0);
6953: }

6957: /*@C
6958:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.

6960:    Collective on Mat

6962:     Input Parameters:
6963: +   mat - the matrix
6964: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6965: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6966: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6967:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6968:                  always used.

6970:     Output Parameters:
6971: +   n - number of rows in the (possibly compressed) matrix
6972: .   ia - the row pointers [of length n+1]
6973: .   ja - the column indices
6974: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6975:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

6977:     Level: developer

6979:     Notes: You CANNOT change any of the ia[] or ja[] values.

6981:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

6983:     Fortran Node

6985:            In Fortran use
6986: $           PetscInt ia(1), ja(1)
6987: $           PetscOffset iia, jja
6988: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6989: $
6990: $          or
6991: $
6992: $           PetscScalar, pointer :: xx_v(:)
6993: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)


6996:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

6998: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6999: @*/
7000: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7001: {

7011:   MatCheckPreallocated(mat,1);
7012:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7013:   else {
7014:     *done = PETSC_TRUE;
7015:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7016:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7017:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7018:   }
7019:   return(0);
7020: }

7024: /*@C
7025:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.

7027:     Collective on Mat

7029:     Input Parameters:
7030: +   mat - the matrix
7031: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7032: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7033:                 symmetrized
7034: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7035:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7036:                  always used.
7037: .   n - number of columns in the (possibly compressed) matrix
7038: .   ia - the column pointers
7039: -   ja - the row indices

7041:     Output Parameters:
7042: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

7044:     Note:
7045:     This routine zeros out n, ia, and ja. This is to prevent accidental
7046:     us of the array after it has been restored. If you pass NULL, it will
7047:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

7049:     Level: developer

7051: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7052: @*/
7053: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7054: {

7064:   MatCheckPreallocated(mat,1);
7065:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7066:   else {
7067:     *done = PETSC_TRUE;
7068:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7069:   }
7070:   return(0);
7071: }

7075: /*@C
7076:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7077:     MatGetRowIJ().

7079:     Collective on Mat

7081:     Input Parameters:
7082: +   mat - the matrix
7083: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7084: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7085:                 symmetrized
7086: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7087:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7088:                  always used.
7089: .   n - size of (possibly compressed) matrix
7090: .   ia - the row pointers
7091: -   ja - the column indices

7093:     Output Parameters:
7094: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7096:     Note:
7097:     This routine zeros out n, ia, and ja. This is to prevent accidental
7098:     us of the array after it has been restored. If you pass NULL, it will
7099:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

7101:     Level: developer

7103: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7104: @*/
7105: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7106: {

7115:   MatCheckPreallocated(mat,1);

7117:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7118:   else {
7119:     *done = PETSC_TRUE;
7120:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7121:     if (n)  *n = 0;
7122:     if (ia) *ia = NULL;
7123:     if (ja) *ja = NULL;
7124:   }
7125:   return(0);
7126: }

7130: /*@C
7131:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7132:     MatGetColumnIJ().

7134:     Collective on Mat

7136:     Input Parameters:
7137: +   mat - the matrix
7138: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7139: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7140:                 symmetrized
7141: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7142:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7143:                  always used.

7145:     Output Parameters:
7146: +   n - size of (possibly compressed) matrix
7147: .   ia - the column pointers
7148: .   ja - the row indices
7149: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7151:     Level: developer

7153: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7154: @*/
7155: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7156: {

7165:   MatCheckPreallocated(mat,1);

7167:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7168:   else {
7169:     *done = PETSC_TRUE;
7170:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7171:     if (n)  *n = 0;
7172:     if (ia) *ia = NULL;
7173:     if (ja) *ja = NULL;
7174:   }
7175:   return(0);
7176: }

7180: /*@C
7181:     MatColoringPatch -Used inside matrix coloring routines that
7182:     use MatGetRowIJ() and/or MatGetColumnIJ().

7184:     Collective on Mat

7186:     Input Parameters:
7187: +   mat - the matrix
7188: .   ncolors - max color value
7189: .   n   - number of entries in colorarray
7190: -   colorarray - array indicating color for each column

7192:     Output Parameters:
7193: .   iscoloring - coloring generated using colorarray information

7195:     Level: developer

7197: .seealso: MatGetRowIJ(), MatGetColumnIJ()

7199: @*/
7200: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7201: {

7209:   MatCheckPreallocated(mat,1);

7211:   if (!mat->ops->coloringpatch) {
7212:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);
7213:   } else {
7214:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7215:   }
7216:   return(0);
7217: }


7222: /*@
7223:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.

7225:    Logically Collective on Mat

7227:    Input Parameter:
7228: .  mat - the factored matrix to be reset

7230:    Notes:
7231:    This routine should be used only with factored matrices formed by in-place
7232:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7233:    format).  This option can save memory, for example, when solving nonlinear
7234:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7235:    ILU(0) preconditioner.

7237:    Note that one can specify in-place ILU(0) factorization by calling
7238: .vb
7239:      PCType(pc,PCILU);
7240:      PCFactorSeUseInPlace(pc);
7241: .ve
7242:    or by using the options -pc_type ilu -pc_factor_in_place

7244:    In-place factorization ILU(0) can also be used as a local
7245:    solver for the blocks within the block Jacobi or additive Schwarz
7246:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7247:    for details on setting local solver options.

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

7253:    Level: developer

7255: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()

7257:    Concepts: matrices^unfactored

7259: @*/
7260: PetscErrorCode  MatSetUnfactored(Mat mat)
7261: {

7267:   MatCheckPreallocated(mat,1);
7268:   mat->factortype = MAT_FACTOR_NONE;
7269:   if (!mat->ops->setunfactored) return(0);
7270:   (*mat->ops->setunfactored)(mat);
7271:   return(0);
7272: }

7274: /*MC
7275:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7277:     Synopsis:
7278:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7280:     Not collective

7282:     Input Parameter:
7283: .   x - matrix

7285:     Output Parameters:
7286: +   xx_v - the Fortran90 pointer to the array
7287: -   ierr - error code

7289:     Example of Usage:
7290: .vb
7291:       PetscScalar, pointer xx_v(:,:)
7292:       ....
7293:       call MatDenseGetArrayF90(x,xx_v,ierr)
7294:       a = xx_v(3)
7295:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7296: .ve

7298:     Level: advanced

7300: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()

7302:     Concepts: matrices^accessing array

7304: M*/

7306: /*MC
7307:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7308:     accessed with MatDenseGetArrayF90().

7310:     Synopsis:
7311:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7313:     Not collective

7315:     Input Parameters:
7316: +   x - matrix
7317: -   xx_v - the Fortran90 pointer to the array

7319:     Output Parameter:
7320: .   ierr - error code

7322:     Example of Usage:
7323: .vb
7324:        PetscScalar, pointer xx_v(:)
7325:        ....
7326:        call MatDenseGetArrayF90(x,xx_v,ierr)
7327:        a = xx_v(3)
7328:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7329: .ve

7331:     Level: advanced

7333: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()

7335: M*/


7338: /*MC
7339:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7341:     Synopsis:
7342:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7344:     Not collective

7346:     Input Parameter:
7347: .   x - matrix

7349:     Output Parameters:
7350: +   xx_v - the Fortran90 pointer to the array
7351: -   ierr - error code

7353:     Example of Usage:
7354: .vb
7355:       PetscScalar, pointer xx_v(:,:)
7356:       ....
7357:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7358:       a = xx_v(3)
7359:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7360: .ve

7362:     Level: advanced

7364: .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()

7366:     Concepts: matrices^accessing array

7368: M*/

7370: /*MC
7371:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7372:     accessed with MatSeqAIJGetArrayF90().

7374:     Synopsis:
7375:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7377:     Not collective

7379:     Input Parameters:
7380: +   x - matrix
7381: -   xx_v - the Fortran90 pointer to the array

7383:     Output Parameter:
7384: .   ierr - error code

7386:     Example of Usage:
7387: .vb
7388:        PetscScalar, pointer xx_v(:)
7389:        ....
7390:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7391:        a = xx_v(3)
7392:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7393: .ve

7395:     Level: advanced

7397: .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()

7399: M*/


7404: /*@
7405:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7406:                       as the original matrix.

7408:     Collective on Mat

7410:     Input Parameters:
7411: +   mat - the original matrix
7412: .   isrow - parallel IS containing the rows this processor should obtain
7413: .   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.
7414: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7416:     Output Parameter:
7417: .   newmat - the new submatrix, of the same type as the old

7419:     Level: advanced

7421:     Notes:
7422:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7424:     The rows in isrow will be sorted into the same order as the original matrix on each process.

7426:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7427:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7428:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7429:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7430:    you are finished using it.

7432:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7433:     the input matrix.

7435:     If iscol is NULL then all columns are obtained (not supported in Fortran).

7437:    Example usage:
7438:    Consider the following 8x8 matrix with 34 non-zero values, that is
7439:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7440:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7441:    as follows:

7443: .vb
7444:             1  2  0  |  0  3  0  |  0  4
7445:     Proc0   0  5  6  |  7  0  0  |  8  0
7446:             9  0 10  | 11  0  0  | 12  0
7447:     -------------------------------------
7448:            13  0 14  | 15 16 17  |  0  0
7449:     Proc1   0 18  0  | 19 20 21  |  0  0
7450:             0  0  0  | 22 23  0  | 24  0
7451:     -------------------------------------
7452:     Proc2  25 26 27  |  0  0 28  | 29  0
7453:            30  0  0  | 31 32 33  |  0 34
7454: .ve

7456:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7458: .vb
7459:             2  0  |  0  3  0  |  0
7460:     Proc0   5  6  |  7  0  0  |  8
7461:     -------------------------------
7462:     Proc1  18  0  | 19 20 21  |  0
7463:     -------------------------------
7464:     Proc2  26 27  |  0  0 28  | 29
7465:             0  0  | 31 32 33  |  0
7466: .ve


7469:     Concepts: matrices^submatrices

7471: .seealso: MatGetSubMatrices()
7472: @*/
7473: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7474: {
7476:   PetscMPIInt    size;
7477:   Mat            *local;
7478:   IS             iscoltmp;

7487:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7488:   MatCheckPreallocated(mat,1);
7489:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7491:   if (!iscol) {
7492:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7493:   } else {
7494:     iscoltmp = iscol;
7495:   }

7497:   /* if original matrix is on just one processor then use submatrix generated */
7498:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7499:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7500:     if (!iscol) {ISDestroy(&iscoltmp);}
7501:     return(0);
7502:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7503:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7504:     *newmat = *local;
7505:     PetscFree(local);
7506:     if (!iscol) {ISDestroy(&iscoltmp);}
7507:     return(0);
7508:   } else if (!mat->ops->getsubmatrix) {
7509:     /* Create a new matrix type that implements the operation using the full matrix */
7510:     switch (cll) {
7511:     case MAT_INITIAL_MATRIX:
7512:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7513:       break;
7514:     case MAT_REUSE_MATRIX:
7515:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7516:       break;
7517:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7518:     }
7519:     if (!iscol) {ISDestroy(&iscoltmp);}
7520:     return(0);
7521:   }

7523:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7524:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7525:   if (!iscol) {ISDestroy(&iscoltmp);}
7526:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7527:   return(0);
7528: }

7532: /*@
7533:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7534:    used during the assembly process to store values that belong to
7535:    other processors.

7537:    Not Collective

7539:    Input Parameters:
7540: +  mat   - the matrix
7541: .  size  - the initial size of the stash.
7542: -  bsize - the initial size of the block-stash(if used).

7544:    Options Database Keys:
7545: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7546: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7548:    Level: intermediate

7550:    Notes:
7551:      The block-stash is used for values set with MatSetValuesBlocked() while
7552:      the stash is used for values set with MatSetValues()

7554:      Run with the option -info and look for output of the form
7555:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7556:      to determine the appropriate value, MM, to use for size and
7557:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7558:      to determine the value, BMM to use for bsize

7560:    Concepts: stash^setting matrix size
7561:    Concepts: matrices^stash

7563: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7565: @*/
7566: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7567: {

7573:   MatStashSetInitialSize_Private(&mat->stash,size);
7574:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7575:   return(0);
7576: }

7580: /*@
7581:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7582:      the matrix

7584:    Neighbor-wise Collective on Mat

7586:    Input Parameters:
7587: +  mat   - the matrix
7588: .  x,y - the vectors
7589: -  w - where the result is stored

7591:    Level: intermediate

7593:    Notes:
7594:     w may be the same vector as y.

7596:     This allows one to use either the restriction or interpolation (its transpose)
7597:     matrix to do the interpolation

7599:     Concepts: interpolation

7601: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7603: @*/
7604: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7605: {
7607:   PetscInt       M,N,Ny;

7615:   MatCheckPreallocated(A,1);
7616:   MatGetSize(A,&M,&N);
7617:   VecGetSize(y,&Ny);
7618:   if (M == Ny) {
7619:     MatMultAdd(A,x,y,w);
7620:   } else {
7621:     MatMultTransposeAdd(A,x,y,w);
7622:   }
7623:   return(0);
7624: }

7628: /*@
7629:    MatInterpolate - y = A*x or A'*x depending on the shape of
7630:      the matrix

7632:    Neighbor-wise Collective on Mat

7634:    Input Parameters:
7635: +  mat   - the matrix
7636: -  x,y - the vectors

7638:    Level: intermediate

7640:    Notes:
7641:     This allows one to use either the restriction or interpolation (its transpose)
7642:     matrix to do the interpolation

7644:    Concepts: matrices^interpolation

7646: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7648: @*/
7649: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7650: {
7652:   PetscInt       M,N,Ny;

7659:   MatCheckPreallocated(A,1);
7660:   MatGetSize(A,&M,&N);
7661:   VecGetSize(y,&Ny);
7662:   if (M == Ny) {
7663:     MatMult(A,x,y);
7664:   } else {
7665:     MatMultTranspose(A,x,y);
7666:   }
7667:   return(0);
7668: }

7672: /*@
7673:    MatRestrict - y = A*x or A'*x

7675:    Neighbor-wise Collective on Mat

7677:    Input Parameters:
7678: +  mat   - the matrix
7679: -  x,y - the vectors

7681:    Level: intermediate

7683:    Notes:
7684:     This allows one to use either the restriction or interpolation (its transpose)
7685:     matrix to do the restriction

7687:    Concepts: matrices^restriction

7689: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()

7691: @*/
7692: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7693: {
7695:   PetscInt       M,N,Ny;

7702:   MatCheckPreallocated(A,1);

7704:   MatGetSize(A,&M,&N);
7705:   VecGetSize(y,&Ny);
7706:   if (M == Ny) {
7707:     MatMult(A,x,y);
7708:   } else {
7709:     MatMultTranspose(A,x,y);
7710:   }
7711:   return(0);
7712: }

7716: /*@
7717:    MatGetNullSpace - retrieves the null space to a matrix.

7719:    Logically Collective on Mat and MatNullSpace

7721:    Input Parameters:
7722: +  mat - the matrix
7723: -  nullsp - the null space object

7725:    Level: developer

7727:    Notes:
7728:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7730:    Concepts: null space^attaching to matrix

7732: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7733: @*/
7734: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7735: {
7740:   *nullsp = mat->nullsp;
7741:   return(0);
7742: }

7746: /*@
7747:    MatSetNullSpace - attaches a null space to a matrix.
7748:         This null space will be removed from the resulting vector whenever
7749:         MatMult() is called

7751:    Logically Collective on Mat and MatNullSpace

7753:    Input Parameters:
7754: +  mat - the matrix
7755: -  nullsp - the null space object

7757:    Level: advanced

7759:    Notes:
7760:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7762:    Concepts: null space^attaching to matrix

7764: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7765: @*/
7766: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7767: {

7774:   MatCheckPreallocated(mat,1);
7775:   PetscObjectReference((PetscObject)nullsp);
7776:   MatNullSpaceDestroy(&mat->nullsp);

7778:   mat->nullsp = nullsp;
7779:   return(0);
7780: }

7784: /*@
7785:    MatSetNearNullSpace - attaches a null space to a matrix.
7786:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

7788:    Logically Collective on Mat and MatNullSpace

7790:    Input Parameters:
7791: +  mat - the matrix
7792: -  nullsp - the null space object

7794:    Level: advanced

7796:    Notes:
7797:       Overwrites any previous near null space that may have been attached

7799:    Concepts: null space^attaching to matrix

7801: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7802: @*/
7803: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7804: {

7811:   MatCheckPreallocated(mat,1);
7812:   PetscObjectReference((PetscObject)nullsp);
7813:   MatNullSpaceDestroy(&mat->nearnullsp);

7815:   mat->nearnullsp = nullsp;
7816:   return(0);
7817: }

7821: /*@
7822:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

7824:    Not Collective

7826:    Input Parameters:
7827: .  mat - the matrix

7829:    Output Parameters:
7830: .  nullsp - the null space object, NULL if not set

7832:    Level: developer

7834:    Concepts: null space^attaching to matrix

7836: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7837: @*/
7838: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7839: {
7844:   MatCheckPreallocated(mat,1);
7845:   *nullsp = mat->nearnullsp;
7846:   return(0);
7847: }

7851: /*@C
7852:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

7854:    Collective on Mat

7856:    Input Parameters:
7857: +  mat - the matrix
7858: .  row - row/column permutation
7859: .  fill - expected fill factor >= 1.0
7860: -  level - level of fill, for ICC(k)

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

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

7870:    Level: developer

7872:    Concepts: matrices^incomplete Cholesky factorization
7873:    Concepts: Cholesky factorization

7875: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

7880: @*/
7881: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7882: {

7890:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
7891:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7892:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7893:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7894:   MatCheckPreallocated(mat,1);
7895:   (*mat->ops->iccfactor)(mat,row,info);
7896:   PetscObjectStateIncrease((PetscObject)mat);
7897:   return(0);
7898: }

7902: /*@
7903:    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.

7905:    Not Collective

7907:    Input Parameters:
7908: +  mat - the matrix
7909: .  nl - leading dimension of v
7910: -  v - the values compute with ADIFOR

7912:    Level: developer

7914:    Notes:
7915:      Must call MatSetColoring() before using this routine. Also this matrix must already
7916:      have its nonzero pattern determined.

7918: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7919:           MatSetValues(), MatSetColoring()
7920: @*/
7921: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7922: {


7930:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7931:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7932:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7933:   (*mat->ops->setvaluesadifor)(mat,nl,v);
7934:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7935:   PetscObjectStateIncrease((PetscObject)mat);
7936:   return(0);
7937: }

7941: /*@
7942:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7943:          ghosted ones.

7945:    Not Collective

7947:    Input Parameters:
7948: +  mat - the matrix
7949: -  diag = the diagonal values, including ghost ones

7951:    Level: developer

7953:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

7955: .seealso: MatDiagonalScale()
7956: @*/
7957: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7958: {
7960:   PetscMPIInt    size;


7967:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7968:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7969:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7970:   if (size == 1) {
7971:     PetscInt n,m;
7972:     VecGetSize(diag,&n);
7973:     MatGetSize(mat,0,&m);
7974:     if (m == n) {
7975:       MatDiagonalScale(mat,0,diag);
7976:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7977:   } else {
7978:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7979:   }
7980:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7981:   PetscObjectStateIncrease((PetscObject)mat);
7982:   return(0);
7983: }

7987: /*@
7988:    MatGetInertia - Gets the inertia from a factored matrix

7990:    Collective on Mat

7992:    Input Parameter:
7993: .  mat - the matrix

7995:    Output Parameters:
7996: +   nneg - number of negative eigenvalues
7997: .   nzero - number of zero eigenvalues
7998: -   npos - number of positive eigenvalues

8000:    Level: advanced

8002:    Notes: Matrix must have been factored by MatCholeskyFactor()


8005: @*/
8006: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8007: {

8013:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8014:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8015:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8016:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8017:   return(0);
8018: }

8020: /* ----------------------------------------------------------------*/
8023: /*@C
8024:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

8026:    Neighbor-wise Collective on Mat and Vecs

8028:    Input Parameters:
8029: +  mat - the factored matrix
8030: -  b - the right-hand-side vectors

8032:    Output Parameter:
8033: .  x - the result vectors

8035:    Notes:
8036:    The vectors b and x cannot be the same.  I.e., one cannot
8037:    call MatSolves(A,x,x).

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

8044:    Level: developer

8046:    Concepts: matrices^triangular solves

8048: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8049: @*/
8050: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
8051: {

8057:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8058:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8059:   if (!mat->rmap->N && !mat->cmap->N) return(0);

8061:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8062:   MatCheckPreallocated(mat,1);
8063:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8064:   (*mat->ops->solves)(mat,b,x);
8065:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8066:   return(0);
8067: }

8071: /*@
8072:    MatIsSymmetric - Test whether a matrix is symmetric

8074:    Collective on Mat

8076:    Input Parameter:
8077: +  A - the matrix to test
8078: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

8080:    Output Parameters:
8081: .  flg - the result

8083:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

8085:    Level: intermediate

8087:    Concepts: matrix^symmetry

8089: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8090: @*/
8091: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8092: {


8099:   if (!A->symmetric_set) {
8100:     if (!A->ops->issymmetric) {
8101:       MatType mattype;
8102:       MatGetType(A,&mattype);
8103:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8104:     }
8105:     (*A->ops->issymmetric)(A,tol,flg);
8106:     if (!tol) {
8107:       A->symmetric_set = PETSC_TRUE;
8108:       A->symmetric     = *flg;
8109:       if (A->symmetric) {
8110:         A->structurally_symmetric_set = PETSC_TRUE;
8111:         A->structurally_symmetric     = PETSC_TRUE;
8112:       }
8113:     }
8114:   } else if (A->symmetric) {
8115:     *flg = PETSC_TRUE;
8116:   } else if (!tol) {
8117:     *flg = PETSC_FALSE;
8118:   } else {
8119:     if (!A->ops->issymmetric) {
8120:       MatType mattype;
8121:       MatGetType(A,&mattype);
8122:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8123:     }
8124:     (*A->ops->issymmetric)(A,tol,flg);
8125:   }
8126:   return(0);
8127: }

8131: /*@
8132:    MatIsHermitian - Test whether a matrix is Hermitian

8134:    Collective on Mat

8136:    Input Parameter:
8137: +  A - the matrix to test
8138: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

8140:    Output Parameters:
8141: .  flg - the result

8143:    Level: intermediate

8145:    Concepts: matrix^symmetry

8147: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8148:           MatIsSymmetricKnown(), MatIsSymmetric()
8149: @*/
8150: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8151: {


8158:   if (!A->hermitian_set) {
8159:     if (!A->ops->ishermitian) {
8160:       MatType mattype;
8161:       MatGetType(A,&mattype);
8162:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8163:     }
8164:     (*A->ops->ishermitian)(A,tol,flg);
8165:     if (!tol) {
8166:       A->hermitian_set = PETSC_TRUE;
8167:       A->hermitian     = *flg;
8168:       if (A->hermitian) {
8169:         A->structurally_symmetric_set = PETSC_TRUE;
8170:         A->structurally_symmetric     = PETSC_TRUE;
8171:       }
8172:     }
8173:   } else if (A->hermitian) {
8174:     *flg = PETSC_TRUE;
8175:   } else if (!tol) {
8176:     *flg = PETSC_FALSE;
8177:   } else {
8178:     if (!A->ops->ishermitian) {
8179:       MatType mattype;
8180:       MatGetType(A,&mattype);
8181:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8182:     }
8183:     (*A->ops->ishermitian)(A,tol,flg);
8184:   }
8185:   return(0);
8186: }

8190: /*@
8191:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

8193:    Not Collective

8195:    Input Parameter:
8196: .  A - the matrix to check

8198:    Output Parameters:
8199: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8200: -  flg - the result

8202:    Level: advanced

8204:    Concepts: matrix^symmetry

8206:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8207:          if you want it explicitly checked

8209: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8210: @*/
8211: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8212: {
8217:   if (A->symmetric_set) {
8218:     *set = PETSC_TRUE;
8219:     *flg = A->symmetric;
8220:   } else {
8221:     *set = PETSC_FALSE;
8222:   }
8223:   return(0);
8224: }

8228: /*@
8229:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8231:    Not Collective

8233:    Input Parameter:
8234: .  A - the matrix to check

8236:    Output Parameters:
8237: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8238: -  flg - the result

8240:    Level: advanced

8242:    Concepts: matrix^symmetry

8244:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8245:          if you want it explicitly checked

8247: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8248: @*/
8249: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8250: {
8255:   if (A->hermitian_set) {
8256:     *set = PETSC_TRUE;
8257:     *flg = A->hermitian;
8258:   } else {
8259:     *set = PETSC_FALSE;
8260:   }
8261:   return(0);
8262: }

8266: /*@
8267:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8269:    Collective on Mat

8271:    Input Parameter:
8272: .  A - the matrix to test

8274:    Output Parameters:
8275: .  flg - the result

8277:    Level: intermediate

8279:    Concepts: matrix^symmetry

8281: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8282: @*/
8283: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8284: {

8290:   if (!A->structurally_symmetric_set) {
8291:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8292:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);

8294:     A->structurally_symmetric_set = PETSC_TRUE;
8295:   }
8296:   *flg = A->structurally_symmetric;
8297:   return(0);
8298: }

8302: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8303: /*@
8304:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8305:        to be communicated to other processors during the MatAssemblyBegin/End() process

8307:     Not collective

8309:    Input Parameter:
8310: .   vec - the vector

8312:    Output Parameters:
8313: +   nstash   - the size of the stash
8314: .   reallocs - the number of additional mallocs incurred.
8315: .   bnstash   - the size of the block stash
8316: -   breallocs - the number of additional mallocs incurred.in the block stash

8318:    Level: advanced

8320: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()

8322: @*/
8323: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8324: {

8328:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8329:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8330:   return(0);
8331: }

8335: /*@C
8336:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8337:      parallel layout

8339:    Collective on Mat

8341:    Input Parameter:
8342: .  mat - the matrix

8344:    Output Parameter:
8345: +   right - (optional) vector that the matrix can be multiplied against
8346: -   left - (optional) vector that the matrix vector product can be stored in

8348:    Notes:
8349:     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().

8351:   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed

8353:   Level: advanced

8355: .seealso: MatCreate(), VecDestroy()
8356: @*/
8357: PetscErrorCode  MatCreateVecs(Mat mat,Vec *right,Vec *left)
8358: {

8364:   MatCheckPreallocated(mat,1);
8365:   if (mat->ops->getvecs) {
8366:     (*mat->ops->getvecs)(mat,right,left);
8367:   } else {
8368:     PetscMPIInt size;
8369:     PetscInt    rbs,cbs;
8370:     MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8371:     MatGetBlockSizes(mat,&rbs,&cbs);
8372:     if (right) {
8373:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8374:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8375:       VecSetBlockSize(*right,cbs);
8376:       VecSetType(*right,VECSTANDARD);
8377:       PetscLayoutReference(mat->cmap,&(*right)->map);
8378:     }
8379:     if (left) {
8380:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8381:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8382:       VecSetBlockSize(*left,rbs);
8383:       VecSetType(*left,VECSTANDARD);
8384:       PetscLayoutReference(mat->rmap,&(*left)->map);
8385:     }
8386:   }
8387:   return(0);
8388: }

8392: /*@C
8393:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8394:      with default values.

8396:    Not Collective

8398:    Input Parameters:
8399: .    info - the MatFactorInfo data structure


8402:    Notes: The solvers are generally used through the KSP and PC objects, for example
8403:           PCLU, PCILU, PCCHOLESKY, PCICC

8405:    Level: developer

8407: .seealso: MatFactorInfo

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

8412: @*/

8414: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8415: {

8419:   PetscMemzero(info,sizeof(MatFactorInfo));
8420:   return(0);
8421: }

8425: /*@
8426:    MatPtAP - Creates the matrix product C = P^T * A * P

8428:    Neighbor-wise Collective on Mat

8430:    Input Parameters:
8431: +  A - the matrix
8432: .  P - the projection matrix
8433: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8434: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

8436:    Output Parameters:
8437: .  C - the product matrix

8439:    Notes:
8440:    C will be created and must be destroyed by the user with MatDestroy().

8442:    This routine is currently only implemented for pairs of AIJ matrices and classes
8443:    which inherit from AIJ.

8445:    Level: intermediate

8447: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8448: @*/
8449: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8450: {
8452:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8453:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8454:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8455:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

8458:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8459:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

8463:   MatCheckPreallocated(A,1);
8464:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8465:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8468:   MatCheckPreallocated(P,2);
8469:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8470:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8472:   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);
8473:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8475:   if (scall == MAT_REUSE_MATRIX) {
8478:     if (viatranspose || viamatmatmatmult) {
8479:       Mat Pt;
8480:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8481:       if (viamatmatmatmult) {
8482:         MatMatMatMult(Pt,A,P,scall,fill,C);
8483:       } else {
8484:         Mat AP;
8485:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8486:         MatMatMult(Pt,AP,scall,fill,C);
8487:         MatDestroy(&AP);
8488:       }
8489:       MatDestroy(&Pt);
8490:     } else {
8491:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8492:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8493:       (*(*C)->ops->ptapnumeric)(A,P,*C);
8494:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8495:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8496:     }
8497:     return(0);
8498:   }

8500:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8501:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8503:   fA = A->ops->ptap;
8504:   fP = P->ops->ptap;
8505:   if (fP == fA) {
8506:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8507:     ptap = fA;
8508:   } else {
8509:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8510:     char ptapname[256];
8511:     PetscStrcpy(ptapname,"MatPtAP_");
8512:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
8513:     PetscStrcat(ptapname,"_");
8514:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
8515:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8516:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8517:     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);
8518:   }

8520:   if (viatranspose || viamatmatmatmult) {
8521:     Mat Pt;
8522:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8523:     if (viamatmatmatmult) {
8524:       MatMatMatMult(Pt,A,P,scall,fill,C);
8525:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8526:     } else {
8527:       Mat AP;
8528:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8529:       MatMatMult(Pt,AP,scall,fill,C);
8530:       MatDestroy(&AP);
8531:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8532:     }
8533:     MatDestroy(&Pt);
8534:   } else {
8535:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8536:     (*ptap)(A,P,scall,fill,C);
8537:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8538:   }
8539:   return(0);
8540: }

8544: /*@
8545:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

8547:    Neighbor-wise Collective on Mat

8549:    Input Parameters:
8550: +  A - the matrix
8551: -  P - the projection matrix

8553:    Output Parameters:
8554: .  C - the product matrix

8556:    Notes:
8557:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8558:    the user using MatDeatroy().

8560:    This routine is currently only implemented for pairs of AIJ matrices and classes
8561:    which inherit from AIJ.  C will be of type MATAIJ.

8563:    Level: intermediate

8565: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8566: @*/
8567: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8568: {

8574:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8575:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8578:   MatCheckPreallocated(P,2);
8579:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8580:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8583:   MatCheckPreallocated(C,3);
8584:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8585:   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);
8586:   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);
8587:   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);
8588:   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);
8589:   MatCheckPreallocated(A,1);

8591:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8592:   (*C->ops->ptapnumeric)(A,P,C);
8593:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8594:   return(0);
8595: }

8599: /*@
8600:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

8602:    Neighbor-wise Collective on Mat

8604:    Input Parameters:
8605: +  A - the matrix
8606: -  P - the projection matrix

8608:    Output Parameters:
8609: .  C - the (i,j) structure of the product matrix

8611:    Notes:
8612:    C will be created and must be destroyed by the user with MatDestroy().

8614:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8615:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8616:    this (i,j) structure by calling MatPtAPNumeric().

8618:    Level: intermediate

8620: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8621: @*/
8622: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8623: {

8629:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8630:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8631:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8634:   MatCheckPreallocated(P,2);
8635:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8636:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8639:   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);
8640:   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);
8641:   MatCheckPreallocated(A,1);
8642:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8643:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8644:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

8646:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8647:   return(0);
8648: }

8652: /*@
8653:    MatRARt - Creates the matrix product C = R * A * R^T

8655:    Neighbor-wise Collective on Mat

8657:    Input Parameters:
8658: +  A - the matrix
8659: .  R - the projection matrix
8660: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8661: -  fill - expected fill as ratio of nnz(C)/nnz(A)

8663:    Output Parameters:
8664: .  C - the product matrix

8666:    Notes:
8667:    C will be created and must be destroyed by the user with MatDestroy().

8669:    This routine is currently only implemented for pairs of AIJ matrices and classes
8670:    which inherit from AIJ.

8672:    Level: intermediate

8674: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8675: @*/
8676: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8677: {

8683:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8684:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8687:   MatCheckPreallocated(R,2);
8688:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8689:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8691:   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);
8692:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8693:   MatCheckPreallocated(A,1);

8695:   if (!A->ops->rart) {
8696:     MatType mattype;
8697:     MatGetType(A,&mattype);
8698:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8699:   }
8700:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
8701:   (*A->ops->rart)(A,R,scall,fill,C);
8702:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
8703:   return(0);
8704: }

8708: /*@
8709:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

8711:    Neighbor-wise Collective on Mat

8713:    Input Parameters:
8714: +  A - the matrix
8715: -  R - the projection matrix

8717:    Output Parameters:
8718: .  C - the product matrix

8720:    Notes:
8721:    C must have been created by calling MatRARtSymbolic and must be destroyed by
8722:    the user using MatDeatroy().

8724:    This routine is currently only implemented for pairs of AIJ matrices and classes
8725:    which inherit from AIJ.  C will be of type MATAIJ.

8727:    Level: intermediate

8729: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8730: @*/
8731: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8732: {

8738:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8739:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8742:   MatCheckPreallocated(R,2);
8743:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8744:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8747:   MatCheckPreallocated(C,3);
8748:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8749:   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);
8750:   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);
8751:   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);
8752:   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);
8753:   MatCheckPreallocated(A,1);

8755:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8756:   (*A->ops->rartnumeric)(A,R,C);
8757:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8758:   return(0);
8759: }

8763: /*@
8764:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

8766:    Neighbor-wise Collective on Mat

8768:    Input Parameters:
8769: +  A - the matrix
8770: -  R - the projection matrix

8772:    Output Parameters:
8773: .  C - the (i,j) structure of the product matrix

8775:    Notes:
8776:    C will be created and must be destroyed by the user with MatDestroy().

8778:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8779:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8780:    this (i,j) structure by calling MatRARtNumeric().

8782:    Level: intermediate

8784: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8785: @*/
8786: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8787: {

8793:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8794:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8795:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8798:   MatCheckPreallocated(R,2);
8799:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8800:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8803:   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8804:   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);
8805:   MatCheckPreallocated(A,1);
8806:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8807:   (*A->ops->rartsymbolic)(A,R,fill,C);
8808:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

8810:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
8811:   return(0);
8812: }

8816: /*@
8817:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

8819:    Neighbor-wise Collective on Mat

8821:    Input Parameters:
8822: +  A - the left matrix
8823: .  B - the right matrix
8824: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8825: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8826:           if the result is a dense matrix this is irrelevent

8828:    Output Parameters:
8829: .  C - the product matrix

8831:    Notes:
8832:    Unless scall is MAT_REUSE_MATRIX C will be created.

8834:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8836:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8837:    actually needed.

8839:    If you have many matrices with the same non-zero structure to multiply, you
8840:    should either
8841: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8842: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

8844:    Level: intermediate

8846: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8847: @*/
8848: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8849: {
8851:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8852:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8853:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

8858:   MatCheckPreallocated(A,1);
8859:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8860:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8863:   MatCheckPreallocated(B,2);
8864:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8865:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8867:   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);
8868:   if (scall == MAT_REUSE_MATRIX) {
8871:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8872:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8873:     (*(*C)->ops->matmultnumeric)(A,B,*C);
8874:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8875:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8876:     return(0);
8877:   }
8878:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8879:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8881:   fA = A->ops->matmult;
8882:   fB = B->ops->matmult;
8883:   if (fB == fA) {
8884:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8885:     mult = fB;
8886:   } else {
8887:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8888:     char multname[256];
8889:     PetscStrcpy(multname,"MatMatMult_");
8890:     PetscStrcat(multname,((PetscObject)A)->type_name);
8891:     PetscStrcat(multname,"_");
8892:     PetscStrcat(multname,((PetscObject)B)->type_name);
8893:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8894:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
8895:     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);
8896:   }
8897:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8898:   (*mult)(A,B,scall,fill,C);
8899:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8900:   return(0);
8901: }

8905: /*@
8906:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8907:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

8909:    Neighbor-wise Collective on Mat

8911:    Input Parameters:
8912: +  A - the left matrix
8913: .  B - the right matrix
8914: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8915:       if C is a dense matrix this is irrelevent

8917:    Output Parameters:
8918: .  C - the product matrix

8920:    Notes:
8921:    Unless scall is MAT_REUSE_MATRIX C will be created.

8923:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8924:    actually needed.

8926:    This routine is currently implemented for
8927:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8928:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8929:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8931:    Level: intermediate

8933:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8934:      We should incorporate them into PETSc.

8936: .seealso: MatMatMult(), MatMatMultNumeric()
8937: @*/
8938: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8939: {
8941:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
8942:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
8943:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

8948:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8949:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8953:   MatCheckPreallocated(B,2);
8954:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8955:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8958:   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);
8959:   if (fill == PETSC_DEFAULT) fill = 2.0;
8960:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
8961:   MatCheckPreallocated(A,1);

8963:   Asymbolic = A->ops->matmultsymbolic;
8964:   Bsymbolic = B->ops->matmultsymbolic;
8965:   if (Asymbolic == Bsymbolic) {
8966:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8967:     symbolic = Bsymbolic;
8968:   } else { /* dispatch based on the type of A and B */
8969:     char symbolicname[256];
8970:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8971:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8972:     PetscStrcat(symbolicname,"_");
8973:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8974:     PetscStrcat(symbolicname,"_C");
8975:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
8976:     if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8977:   }
8978:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8979:   (*symbolic)(A,B,fill,C);
8980:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8981:   return(0);
8982: }

8986: /*@
8987:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8988:    Call this routine after first calling MatMatMultSymbolic().

8990:    Neighbor-wise Collective on Mat

8992:    Input Parameters:
8993: +  A - the left matrix
8994: -  B - the right matrix

8996:    Output Parameters:
8997: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

8999:    Notes:
9000:    C must have been created with MatMatMultSymbolic().

9002:    This routine is currently implemented for
9003:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9004:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9005:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9007:    Level: intermediate

9009: .seealso: MatMatMult(), MatMatMultSymbolic()
9010: @*/
9011: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
9012: {

9016:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9017:   return(0);
9018: }

9022: /*@
9023:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

9025:    Neighbor-wise Collective on Mat

9027:    Input Parameters:
9028: +  A - the left matrix
9029: .  B - the right matrix
9030: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9031: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9033:    Output Parameters:
9034: .  C - the product matrix

9036:    Notes:
9037:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

9039:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9041:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9042:    actually needed.

9044:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

9046:    Level: intermediate

9048: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9049: @*/
9050: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9051: {
9053:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9054:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

9059:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9060:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9063:   MatCheckPreallocated(B,2);
9064:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9065:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9067:   if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
9068:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9069:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9070:   MatCheckPreallocated(A,1);

9072:   fA = A->ops->mattransposemult;
9073:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9074:   fB = B->ops->mattransposemult;
9075:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9076:   if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);

9078:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9079:   if (scall == MAT_INITIAL_MATRIX) {
9080:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9081:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9082:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9083:   }
9084:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9085:   (*A->ops->mattransposemultnumeric)(A,B,*C);
9086:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9087:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9088:   return(0);
9089: }

9093: /*@
9094:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

9096:    Neighbor-wise Collective on Mat

9098:    Input Parameters:
9099: +  A - the left matrix
9100: .  B - the right matrix
9101: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9102: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9104:    Output Parameters:
9105: .  C - the product matrix

9107:    Notes:
9108:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

9110:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9112:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9113:    actually needed.

9115:    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9116:    which inherit from SeqAIJ.  C will be of same type as the input matrices.

9118:    Level: intermediate

9120: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9121: @*/
9122: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9123: {
9125:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9126:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9127:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

9132:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9133:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9136:   MatCheckPreallocated(B,2);
9137:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9138:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9140:   if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
9141:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9142:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9143:   MatCheckPreallocated(A,1);

9145:   fA = A->ops->transposematmult;
9146:   fB = B->ops->transposematmult;
9147:   if (fB==fA) {
9148:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9149:     transposematmult = fA;
9150:   } else {
9151:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9152:     char multname[256];
9153:     PetscStrcpy(multname,"MatTransposeMatMult_");
9154:     PetscStrcat(multname,((PetscObject)A)->type_name);
9155:     PetscStrcat(multname,"_");
9156:     PetscStrcat(multname,((PetscObject)B)->type_name);
9157:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9158:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9159:     if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9160:   }
9161:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9162:   (*transposematmult)(A,B,scall,fill,C);
9163:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9164:   return(0);
9165: }

9169: /*@
9170:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

9172:    Neighbor-wise Collective on Mat

9174:    Input Parameters:
9175: +  A - the left matrix
9176: .  B - the middle matrix
9177: .  C - the right matrix
9178: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9179: -  fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate
9180:           if the result is a dense matrix this is irrelevent

9182:    Output Parameters:
9183: .  D - the product matrix

9185:    Notes:
9186:    Unless scall is MAT_REUSE_MATRIX D will be created.

9188:    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call

9190:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9191:    actually needed.

9193:    If you have many matrices with the same non-zero structure to multiply, you
9194:    should either
9195: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9196: $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed

9198:    Level: intermediate

9200: .seealso: MatMatMult, MatPtAP()
9201: @*/
9202: PetscErrorCode  MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9203: {
9205:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9206:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9207:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9208:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9213:   MatCheckPreallocated(A,1);
9214:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9215:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9218:   MatCheckPreallocated(B,2);
9219:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9220:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9223:   MatCheckPreallocated(C,3);
9224:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9225:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9226:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9227:   if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
9228:   if (scall == MAT_REUSE_MATRIX) {
9231:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9232:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9233:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9234:     return(0);
9235:   }
9236:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9237:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9239:   fA = A->ops->matmatmult;
9240:   fB = B->ops->matmatmult;
9241:   fC = C->ops->matmatmult;
9242:   if (fA == fB && fA == fC) {
9243:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9244:     mult = fA;
9245:   } else {
9246:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9247:     char multname[256];
9248:     PetscStrcpy(multname,"MatMatMatMult_");
9249:     PetscStrcat(multname,((PetscObject)A)->type_name);
9250:     PetscStrcat(multname,"_");
9251:     PetscStrcat(multname,((PetscObject)B)->type_name);
9252:     PetscStrcat(multname,"_");
9253:     PetscStrcat(multname,((PetscObject)C)->type_name);
9254:     PetscStrcat(multname,"_C");
9255:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9256:     if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9257:   }
9258:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9259:   (*mult)(A,B,C,scall,fill,D);
9260:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9261:   return(0);
9262: }

9266: /*@C
9267:    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

9269:    Collective on Mat

9271:    Input Parameters:
9272: +  mat - the matrix
9273: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9274: .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9275: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9277:    Output Parameter:
9278: .  matredundant - redundant matrix

9280:    Notes:
9281:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9282:    original matrix has not changed from that last call to MatCreateRedundantMatrix().

9284:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9285:    calling it.

9287:    Level: advanced

9289:    Concepts: subcommunicator
9290:    Concepts: duplicate matrix

9292: .seealso: MatDestroy()
9293: @*/
9294: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9295: {
9297:   MPI_Comm       comm;
9298:   PetscMPIInt    size;
9299:   PetscInt       mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9300:   Mat_Redundant  *redund=NULL;
9301:   PetscSubcomm   psubcomm=NULL;
9302:   MPI_Comm       subcomm_in=subcomm;
9303:   Mat            *matseq;
9304:   IS             isrow,iscol;
9305:   PetscBool      newsubcomm=PETSC_FALSE;
9306: 
9308:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
9309:   if (size == 1 || nsubcomm == 1) {
9310:     if (reuse == MAT_INITIAL_MATRIX) {
9311:       MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
9312:     } else {
9313:       MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
9314:     }
9315:     return(0);
9316:   }

9319:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9322:   }
9323:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9324:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9325:   MatCheckPreallocated(mat,1);

9327:   PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
9328:   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9329:     /* create psubcomm, then get subcomm */
9330:     PetscObjectGetComm((PetscObject)mat,&comm);
9331:     MPI_Comm_size(comm,&size);
9332:     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);

9334:     PetscSubcommCreate(comm,&psubcomm);
9335:     PetscSubcommSetNumber(psubcomm,nsubcomm);
9336:     PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
9337:     PetscSubcommSetFromOptions(psubcomm);
9338:     PetscCommDuplicate(psubcomm->comm,&subcomm,NULL);
9339:     newsubcomm = PETSC_TRUE;
9340:     PetscSubcommDestroy(&psubcomm);
9341:   }

9343:   /* get isrow, iscol and a local sequential matrix matseq[0] */
9344:   if (reuse == MAT_INITIAL_MATRIX) {
9345:     mloc_sub = PETSC_DECIDE;
9346:     if (bs < 1) {
9347:       PetscSplitOwnership(subcomm,&mloc_sub,&M);
9348:     } else {
9349:       PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
9350:     }
9351:     MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
9352:     rstart = rend - mloc_sub;
9353:     ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
9354:     ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
9355:   } else { /* reuse == MAT_REUSE_MATRIX */
9356:     /* retrieve subcomm */
9357:     PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
9358:     redund = (*matredundant)->redundant;
9359:     isrow  = redund->isrow;
9360:     iscol  = redund->iscol;
9361:     matseq = redund->matseq;
9362:   }
9363:   MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);
9364: 
9365:   /* get matredundant over subcomm */
9366:   if (reuse == MAT_INITIAL_MATRIX) {
9367:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);

9369:     /* create a supporting struct and attach it to C for reuse */
9370:     PetscNewLog(*matredundant,&redund);
9371:     (*matredundant)->redundant = redund;
9372:     redund->isrow              = isrow;
9373:     redund->iscol              = iscol;
9374:     redund->matseq             = matseq;
9375:     if (newsubcomm) {
9376:       redund->subcomm          = subcomm;
9377:     } else {
9378:       redund->subcomm          = MPI_COMM_NULL;
9379:     }
9380:   } else {
9381:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
9382:   }
9383:   PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
9384:   return(0);
9385: }

9389: /*@C
9390:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9391:    a given 'mat' object. Each submatrix can span multiple procs.

9393:    Collective on Mat

9395:    Input Parameters:
9396: +  mat - the matrix
9397: .  subcomm - the subcommunicator obtained by com_split(comm)
9398: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9400:    Output Parameter:
9401: .  subMat - 'parallel submatrices each spans a given subcomm

9403:   Notes:
9404:   The submatrix partition across processors is dictated by 'subComm' a
9405:   communicator obtained by com_split(comm). The comm_split
9406:   is not restriced to be grouped with consecutive original ranks.

9408:   Due the comm_split() usage, the parallel layout of the submatrices
9409:   map directly to the layout of the original matrix [wrt the local
9410:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9411:   into the 'DiagonalMat' of the subMat, hence it is used directly from
9412:   the subMat. However the offDiagMat looses some columns - and this is
9413:   reconstructed with MatSetValues()

9415:   Level: advanced

9417:   Concepts: subcommunicator
9418:   Concepts: submatrices

9420: .seealso: MatGetSubMatrices()
9421: @*/
9422: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9423: {
9425:   PetscMPIInt    commsize,subCommSize;

9428:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9429:   MPI_Comm_size(subComm,&subCommSize);
9430:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

9432:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9433:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9434:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9435:   return(0);
9436: }

9440: /*@
9441:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

9443:    Not Collective

9445:    Input Arguments:
9446:    mat - matrix to extract local submatrix from
9447:    isrow - local row indices for submatrix
9448:    iscol - local column indices for submatrix

9450:    Output Arguments:
9451:    submat - the submatrix

9453:    Level: intermediate

9455:    Notes:
9456:    The submat should be returned with MatRestoreLocalSubMatrix().

9458:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9459:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

9461:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9462:    MatSetValuesBlockedLocal() will also be implemented.

9464: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9465: @*/
9466: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9467: {


9477:   if (mat->ops->getlocalsubmatrix) {
9478:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9479:   } else {
9480:     MatCreateLocalRef(mat,isrow,iscol,submat);
9481:   }
9482:   return(0);
9483: }

9487: /*@
9488:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

9490:    Not Collective

9492:    Input Arguments:
9493:    mat - matrix to extract local submatrix from
9494:    isrow - local row indices for submatrix
9495:    iscol - local column indices for submatrix
9496:    submat - the submatrix

9498:    Level: intermediate

9500: .seealso: MatGetLocalSubMatrix()
9501: @*/
9502: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9503: {

9512:   if (*submat) {
9514:   }

9516:   if (mat->ops->restorelocalsubmatrix) {
9517:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9518:   } else {
9519:     MatDestroy(submat);
9520:   }
9521:   *submat = NULL;
9522:   return(0);
9523: }

9525: /* --------------------------------------------------------*/
9528: /*@
9529:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

9531:    Collective on Mat

9533:    Input Parameter:
9534: .  mat - the matrix

9536:    Output Parameter:
9537: .  is - if any rows have zero diagonals this contains the list of them

9539:    Level: developer

9541:    Concepts: matrix-vector product

9543: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9544: @*/
9545: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9546: {

9552:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9553:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9555:   if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9556:   (*mat->ops->findzerodiagonals)(mat,is);
9557:   return(0);
9558: }

9562: /*@
9563:    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)

9565:    Collective on Mat

9567:    Input Parameter:
9568: .  mat - the matrix

9570:    Output Parameter:
9571: .  is - contains the list of rows with off block diagonal entries

9573:    Level: developer

9575:    Concepts: matrix-vector product

9577: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9578: @*/
9579: PetscErrorCode  MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
9580: {

9586:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9587:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9589:   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
9590:   (*mat->ops->findoffblockdiagonalentries)(mat,is);
9591:   return(0);
9592: }

9596: /*@C
9597:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

9599:   Collective on Mat

9601:   Input Parameters:
9602: . mat - the matrix

9604:   Output Parameters:
9605: . values - the block inverses in column major order (FORTRAN-like)

9607:    Note:
9608:    This routine is not available from Fortran.

9610:   Level: advanced
9611: @*/
9612: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9613: {

9618:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9619:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9620:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9621:   (*mat->ops->invertblockdiagonal)(mat,values);
9622:   return(0);
9623: }

9627: /*@C
9628:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9629:     via MatTransposeColoringCreate().

9631:     Collective on MatTransposeColoring

9633:     Input Parameter:
9634: .   c - coloring context

9636:     Level: intermediate

9638: .seealso: MatTransposeColoringCreate()
9639: @*/
9640: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9641: {
9642:   PetscErrorCode       ierr;
9643:   MatTransposeColoring matcolor=*c;

9646:   if (!matcolor) return(0);
9647:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

9649:   PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
9650:   PetscFree(matcolor->rows);
9651:   PetscFree(matcolor->den2sp);
9652:   PetscFree(matcolor->colorforcol);
9653:   PetscFree(matcolor->columns);
9654:   if (matcolor->brows>0) {
9655:     PetscFree(matcolor->lstart);
9656:   }
9657:   PetscHeaderDestroy(c);
9658:   return(0);
9659: }

9663: /*@C
9664:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9665:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9666:     MatTransposeColoring to sparse B.

9668:     Collective on MatTransposeColoring

9670:     Input Parameters:
9671: +   B - sparse matrix B
9672: .   Btdense - symbolic dense matrix B^T
9673: -   coloring - coloring context created with MatTransposeColoringCreate()

9675:     Output Parameter:
9676: .   Btdense - dense matrix B^T

9678:     Options Database Keys:
9679: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9680: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9681: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

9683:     Level: intermediate

9685: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

9687: .keywords: coloring
9688: @*/
9689: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9690: {


9698:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9699:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9700:   return(0);
9701: }

9705: /*@C
9706:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9707:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9708:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9709:     Csp from Cden.

9711:     Collective on MatTransposeColoring

9713:     Input Parameters:
9714: +   coloring - coloring context created with MatTransposeColoringCreate()
9715: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

9717:     Output Parameter:
9718: .   Csp - sparse matrix

9720:     Options Database Keys:
9721: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9722: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9723: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

9725:     Level: intermediate

9727: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

9729: .keywords: coloring
9730: @*/
9731: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9732: {


9740:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9741:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9742:   return(0);
9743: }

9747: /*@C
9748:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

9750:    Collective on Mat

9752:    Input Parameters:
9753: +  mat - the matrix product C
9754: -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()

9756:     Output Parameter:
9757: .   color - the new coloring context

9759:     Level: intermediate

9761: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9762:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9763: @*/
9764: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9765: {
9766:   MatTransposeColoring c;
9767:   MPI_Comm             comm;
9768:   PetscErrorCode       ierr;

9771:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9772:   PetscObjectGetComm((PetscObject)mat,&comm);
9773:   PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);

9775:   c->ctype = iscoloring->ctype;
9776:   if (mat->ops->transposecoloringcreate) {
9777:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9778:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

9780:   *color = c;
9781:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9782:   return(0);
9783: }

9787: /*@
9788:       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 
9789:         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 
9790:         same, otherwise it will be larger

9792:      Not Collective

9794:   Input Parameter:
9795: .    A  - the matrix

9797:   Output Parameter:
9798: .    state - the current state

9800:   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 
9801:          different matrices

9803:   Level: intermediate

9805: @*/
9806: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
9807: {
9809:   *state = mat->nonzerostate;
9810:   return(0);
9811: }

9815: /*@
9816:       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
9817:                  matrices from each processor

9819:     Collective on MPI_Comm

9821:    Input Parameters:
9822: +    comm - the communicators the parallel matrix will live on
9823: .    seqmat - the input sequential matrices
9824: .    n - number of local columns (or PETSC_DECIDE)
9825: -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9827:    Output Parameter:
9828: .    mpimat - the parallel matrix generated

9830:     Level: advanced

9832:    Notes: The number of columns of the matrix in EACH processor MUST be the same.

9834: @*/
9835: PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
9836: {
9838:   PetscMPIInt    size;

9841:   MPI_Comm_size(comm,&size);
9842:   if (size == 1) {
9843:     if (reuse == MAT_INITIAL_MATRIX) {
9844:       MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);
9845:     } else {
9846:       MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);
9847:     }
9848:     return(0);
9849:   }

9851:   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
9852:   PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);
9853:   (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);
9854:   PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);
9855:   return(0);
9856: }