Actual source code: matrix.c

petsc-3.7.7 2017-09-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>
  8: #include <petsc/private/isimpl.h>

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

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

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

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

 47:    Logically Collective on Vec

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

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

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

 64:    Level: intermediate

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

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


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

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

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


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

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

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

110:   Level: intermediate

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

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

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

131:    Not Collective

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

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

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

143:    Level: advanced

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

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

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

176:    Collective on Mat

178:    Input Parameters:
179: .  mat - the matrix

181:    Output Parameter:
182: .   trace - the sum of the diagonal entries

184:    Level: advanced

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

193:   MatCreateVecs(mat,&diag,NULL);
194:   MatGetDiagonal(mat,diag);
195:   VecSum(diag,trace);
196:   VecDestroy(&diag);
197:   return(0);
198: }

202: /*@
203:    MatRealPart - Zeros out the imaginary part of the matrix

205:    Logically Collective on Mat

207:    Input Parameters:
208: .  mat - the matrix

210:    Level: advanced


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

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

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

248:    Collective on Mat

250:    Input Parameter:
251: .  mat - the matrix

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

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

259:    Level: advanced

261: @*/
262: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
263: {

269:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
270:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
271:   if (!mat->ops->getghosts) {
272:     if (nghosts) *nghosts = 0;
273:     if (ghosts) *ghosts = 0;
274:   } else {
275:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
276:   }
277:   return(0);
278: }


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

286:    Logically Collective on Mat

288:    Input Parameters:
289: .  mat - the matrix

291:    Level: advanced


294: .seealso: MatRealPart()
295: @*/
296: PetscErrorCode MatImaginaryPart(Mat mat)
297: {

303:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
304:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
305:   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
306:   MatCheckPreallocated(mat,1);
307:   (*mat->ops->imaginarypart)(mat);
308: #if defined(PETSC_HAVE_CUSP)
309:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
310:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
311:   }
312: #elif defined(PETSC_HAVE_VIENNACL)
313:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
314:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
315:   }
316: #elif defined(PETSC_HAVE_VECCUDA)
317:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
318:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
319:   }
320: #endif
321:   return(0);
322: }

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

329:    Collective on Mat

331:    Input Parameter:
332: .  mat - the matrix

334:    Output Parameters:
335: +  missing - is any diagonal missing
336: -  dd - first diagonal entry that is missing (optional)

338:    Level: advanced


341: .seealso: MatRealPart()
342: @*/
343: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
344: {

350:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
351:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
352:   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
353:   (*mat->ops->missingdiagonal)(mat,missing,dd);
354:   return(0);
355: }

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

364:    Not Collective

366:    Input Parameters:
367: +  mat - the matrix
368: -  row - the row to get

370:    Output Parameters:
371: +  ncols -  if not NULL, the number of nonzeros in the row
372: .  cols - if not NULL, the column numbers
373: -  vals - if not NULL, the values

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

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

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

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

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

397:    Fortran Notes:
398:    The calling sequence from Fortran is
399: .vb
400:    MatGetRow(matrix,row,ncols,cols,values,ierr)
401:          Mat     matrix (input)
402:          integer row    (input)
403:          integer ncols  (output)
404:          integer cols(maxcols) (output)
405:          double precision (or double complex) values(maxcols) output
406: .ve
407:    where maxcols >= maximum nonzeros in any row of the matrix.


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

414:    Level: advanced

416:    Concepts: matrices^row access

418: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
419: @*/
420: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
421: {
423:   PetscInt       incols;

428:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
429:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
430:   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
431:   MatCheckPreallocated(mat,1);
432:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
433:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
434:   if (ncols) *ncols = incols;
435:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
436:   return(0);
437: }

441: /*@
442:    MatConjugate - replaces the matrix values with their complex conjugates

444:    Logically Collective on Mat

446:    Input Parameters:
447: .  mat - the matrix

449:    Level: advanced

451: .seealso:  VecConjugate()
452: @*/
453: PetscErrorCode MatConjugate(Mat mat)
454: {
455: #if defined(PETSC_USE_COMPLEX)

460:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
461:   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");
462:   (*mat->ops->conjugate)(mat);
463: #if defined(PETSC_HAVE_CUSP)
464:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
465:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
466:   }
467: #elif defined(PETSC_HAVE_VIENNACL)
468:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
469:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
470:   }
471: #elif defined(PETSC_HAVE_VECCUDA)
472:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
473:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
474:   }
475: #endif
476:   return(0);
477: #else
478:   return 0;
479: #endif
480: }

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

487:    Not Collective

489:    Input Parameters:
490: +  mat - the matrix
491: .  row - the row to get
492: .  ncols, cols - the number of nonzeros and their columns
493: -  vals - if nonzero the column values

495:    Notes:
496:    This routine should be called after you have finished examining the entries.

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

502:    Fortran Notes:
503:    The calling sequence from Fortran is
504: .vb
505:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
506:       Mat     matrix (input)
507:       integer row    (input)
508:       integer ncols  (output)
509:       integer cols(maxcols) (output)
510:       double precision (or double complex) values(maxcols) output
511: .ve
512:    Where maxcols >= maximum nonzeros in any row of the matrix.

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

517:    Level: advanced

519: .seealso:  MatGetRow()
520: @*/
521: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
522: {

528:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
529:   if (!mat->ops->restorerow) return(0);
530:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
531:   if (ncols) *ncols = 0;
532:   if (cols)  *cols = NULL;
533:   if (vals)  *vals = NULL;
534:   return(0);
535: }

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

543:    Not Collective

545:    Input Parameters:
546: +  mat - the matrix

548:    Notes:
549:    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.

551:    Level: advanced

553:    Concepts: matrices^row access

555: .seealso: MatRestoreRowRowUpperTriangular()
556: @*/
557: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
558: {

564:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
565:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
566:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
567:   MatCheckPreallocated(mat,1);
568:   (*mat->ops->getrowuppertriangular)(mat);
569:   return(0);
570: }

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

577:    Not Collective

579:    Input Parameters:
580: +  mat - the matrix

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


586:    Level: advanced

588: .seealso:  MatGetRowUpperTriangular()
589: @*/
590: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
591: {

596:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
597:   if (!mat->ops->restorerowuppertriangular) return(0);
598:   (*mat->ops->restorerowuppertriangular)(mat);
599:   return(0);
600: }

604: /*@C
605:    MatSetOptionsPrefix - Sets the prefix used for searching for all
606:    Mat options in the database.

608:    Logically Collective on Mat

610:    Input Parameter:
611: +  A - the Mat context
612: -  prefix - the prefix to prepend to all option names

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

618:    Level: advanced

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

622: .seealso: MatSetFromOptions()
623: @*/
624: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
625: {

630:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
631:   return(0);
632: }

636: /*@C
637:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
638:    Mat options in the database.

640:    Logically Collective on Mat

642:    Input Parameters:
643: +  A - the Mat context
644: -  prefix - the prefix to prepend to all option names

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

650:    Level: advanced

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

654: .seealso: MatGetOptionsPrefix()
655: @*/
656: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
657: {

662:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
663:   return(0);
664: }

668: /*@C
669:    MatGetOptionsPrefix - Sets the prefix used for searching for all
670:    Mat options in the database.

672:    Not Collective

674:    Input Parameter:
675: .  A - the Mat context

677:    Output Parameter:
678: .  prefix - pointer to the prefix string used

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

683:    Level: advanced

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

687: .seealso: MatAppendOptionsPrefix()
688: @*/
689: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
690: {

695:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
696:   return(0);
697: }

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

704:    Collective on Mat

706:    Input Parameters:
707: .  A - the Mat context

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

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

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

716:    Level: beginner

718: .keywords: Mat, setup

720: .seealso: MatCreate(), MatDestroy()
721: @*/
722: PetscErrorCode MatSetUp(Mat A)
723: {
724:   PetscMPIInt    size;

729:   if (!((PetscObject)A)->type_name) {
730:     MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
731:     if (size == 1) {
732:       MatSetType(A, MATSEQAIJ);
733:     } else {
734:       MatSetType(A, MATMPIAIJ);
735:     }
736:   }
737:   if (!A->preallocated && A->ops->setup) {
738:     PetscInfo(A,"Warning not preallocating matrix storage\n");
739:     (*A->ops->setup)(A);
740:   }
741:   A->preallocated = PETSC_TRUE;
742:   return(0);
743: }

745: #if defined(PETSC_HAVE_SAWS)
746: #include <petscviewersaws.h>
747: #endif
750: /*@C
751:    MatView - Visualizes a matrix object.

753:    Collective on Mat

755:    Input Parameters:
756: +  mat - the matrix
757: -  viewer - visualization context

759:   Notes:
760:   The available visualization contexts include
761: +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
762: .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
763: .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
764: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

766:    The user can open alternative visualization contexts with
767: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
768: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
769:          specified file; corresponding input uses MatLoad()
770: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
771:          an X window display
772: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
773:          Currently only the sequential dense and AIJ
774:          matrix types support the Socket viewer.

776:    The user can call PetscViewerPushFormat() to specify the output
777:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
778:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
779: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
780: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
781: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
782: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
783:          format common among all matrix types
784: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
785:          format (which is in many cases the same as the default)
786: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
787:          size and structure (not the matrix entries)
788: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
789:          the matrix structure

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

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

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

812:       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
813:       And then use the following mouse functions:
814:           left mouse: zoom in
815:           middle mouse: zoom out
816:           right mouse: continue with the simulation

818:    Concepts: matrices^viewing
819:    Concepts: matrices^plotting
820:    Concepts: matrices^printing

822: .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
823:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
824: @*/
825: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
826: {
827:   PetscErrorCode    ierr;
828:   PetscInt          rows,cols,rbs,cbs;
829:   PetscBool         iascii,ibinary;
830:   PetscViewerFormat format;
831: #if defined(PETSC_HAVE_SAWS)
832:   PetscBool         issaws;
833: #endif

838:   if (!viewer) {
839:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
840:   }
843:   MatCheckPreallocated(mat,1);
844:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
845:   if (ibinary) {
846:     PetscBool mpiio;
847:     PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
848:     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
849:   }

851:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
852:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
853:   PetscViewerGetFormat(viewer,&format);
854:   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
855:     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
856:   }

858: #if defined(PETSC_HAVE_SAWS)
859:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
860: #endif
861:   if (iascii) {
862:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
863:     PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
864:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
865:       PetscViewerASCIIPushTab(viewer);
866:       MatGetSize(mat,&rows,&cols);
867:       MatGetBlockSizes(mat,&rbs,&cbs);
868:       if (rbs != 1 || cbs != 1) {
869:         if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
870:         else            {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
871:       } else {
872:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
873:       }
874:       if (mat->factortype) {
875:         const MatSolverPackage solver;
876:         MatFactorGetSolverPackage(mat,&solver);
877:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
878:       }
879:       if (mat->ops->getinfo) {
880:         MatInfo info;
881:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
882:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
883:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
884:       }
885:       if (mat->nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached null space\n");}
886:       if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");}
887:     }
888: #if defined(PETSC_HAVE_SAWS)
889:   } else if (issaws) {
890:     PetscMPIInt rank;

892:     PetscObjectName((PetscObject)mat);
893:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
894:     if (!((PetscObject)mat)->amsmem && !rank) {
895:       PetscObjectViewSAWs((PetscObject)mat,viewer);
896:     }
897: #endif
898:   }
899:   if (mat->ops->view) {
900:     PetscViewerASCIIPushTab(viewer);
901:     (*mat->ops->view)(mat,viewer);
902:     PetscViewerASCIIPopTab(viewer);
903:   }
904:   if (iascii) {
905:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
906:     PetscViewerGetFormat(viewer,&format);
907:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
908:       PetscViewerASCIIPopTab(viewer);
909:     }
910:   }
911:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
912:   return(0);
913: }

915: #if defined(PETSC_USE_DEBUG)
916: #include <../src/sys/totalview/tv_data_display.h>
917: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
918: {
919:   TV_add_row("Local rows", "int", &mat->rmap->n);
920:   TV_add_row("Local columns", "int", &mat->cmap->n);
921:   TV_add_row("Global rows", "int", &mat->rmap->N);
922:   TV_add_row("Global columns", "int", &mat->cmap->N);
923:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
924:   return TV_format_OK;
925: }
926: #endif

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

936:    Collective on PetscViewer

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

943:    Options Database Keys:
944:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
945:    block size
946: .    -matload_block_size <bs>

948:    Level: beginner

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

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

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

963:    In parallel, each processor can load a subset of rows (or the
964:    entire matrix).  This routine is especially useful when a large
965:    matrix is stored on disk and only part of it is desired on each
966:    processor.  For example, a parallel solver may access only some of
967:    the rows from each processor.  The algorithm used here reads
968:    relatively small blocks of data rather than reading the entire
969:    matrix and then subsetting it.

971:    Notes for advanced users:
972:    Most users should not need to know the details of the binary storage
973:    format, since MatLoad() and MatView() completely hide these details.
974:    But for anyone who's interested, the standard binary matrix storage
975:    format is

977: $    int    MAT_FILE_CLASSID
978: $    int    number of rows
979: $    int    number of columns
980: $    int    total number of nonzeros
981: $    int    *number nonzeros in each row
982: $    int    *column indices of all nonzeros (starting index is zero)
983: $    PetscScalar *values of all nonzeros

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

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

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

995:  @*/
996: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
997: {
999:   PetscBool      isbinary,flg;

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

1007:   if (!((PetscObject)newmat)->type_name) {
1008:     MatSetType(newmat,MATAIJ);
1009:   }

1011:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1012:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1013:   (*newmat->ops->load)(newmat,viewer);
1014:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

1016:   flg  = PETSC_FALSE;
1017:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1018:   if (flg) {
1019:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1020:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1021:   }
1022:   flg  = PETSC_FALSE;
1023:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1024:   if (flg) {
1025:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1026:   }
1027:   return(0);
1028: }

1032: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1033: {
1035:   Mat_Redundant  *redund = *redundant;
1036:   PetscInt       i;

1039:   if (redund){
1040:     if (redund->matseq) { /* via MatGetSubMatrices()  */
1041:       ISDestroy(&redund->isrow);
1042:       ISDestroy(&redund->iscol);
1043:       MatDestroy(&redund->matseq[0]);
1044:       PetscFree(redund->matseq);
1045:     } else {
1046:       PetscFree2(redund->send_rank,redund->recv_rank);
1047:       PetscFree(redund->sbuf_j);
1048:       PetscFree(redund->sbuf_a);
1049:       for (i=0; i<redund->nrecvs; i++) {
1050:         PetscFree(redund->rbuf_j[i]);
1051:         PetscFree(redund->rbuf_a[i]);
1052:       }
1053:       PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1054:     }

1056:     if (redund->subcomm) {
1057:       PetscCommDestroy(&redund->subcomm);
1058:     }
1059:     PetscFree(redund);
1060:   }
1061:   return(0);
1062: }

1066: /*@
1067:    MatDestroy - Frees space taken by a matrix.

1069:    Collective on Mat

1071:    Input Parameter:
1072: .  A - the matrix

1074:    Level: beginner

1076: @*/
1077: PetscErrorCode MatDestroy(Mat *A)
1078: {

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

1086:   /* if memory was published with SAWs then destroy it */
1087:   PetscObjectSAWsViewOff((PetscObject)*A);
1088:   if ((*A)->ops->destroy) {
1089:     (*(*A)->ops->destroy)(*A);
1090:   }

1092:   PetscFree((*A)->solvertype);
1093:   MatDestroy_Redundant(&(*A)->redundant);
1094:   MatNullSpaceDestroy(&(*A)->nullsp);
1095:   MatNullSpaceDestroy(&(*A)->transnullsp);
1096:   MatNullSpaceDestroy(&(*A)->nearnullsp);
1097:   PetscLayoutDestroy(&(*A)->rmap);
1098:   PetscLayoutDestroy(&(*A)->cmap);
1099:   PetscHeaderDestroy(A);
1100:   return(0);
1101: }

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

1110:    Not Collective

1112:    Input Parameters:
1113: +  mat - the matrix
1114: .  v - a logically two-dimensional array of values
1115: .  m, idxm - the number of rows and their global indices
1116: .  n, idxn - the number of columns and their global indices
1117: -  addv - either ADD_VALUES or INSERT_VALUES, where
1118:    ADD_VALUES adds values to any existing entries, and
1119:    INSERT_VALUES replaces existing entries with new values

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

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

1127:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1128:    options cannot be mixed without intervening calls to the assembly
1129:    routines.

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

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

1139:    Efficiency Alert:
1140:    The routine MatSetValuesBlocked() may offer much better efficiency
1141:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1143:    Level: beginner

1145:    Concepts: matrices^putting entries in

1147: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1148:           InsertMode, INSERT_VALUES, ADD_VALUES
1149: @*/
1150: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1151: {
1153: #if defined(PETSC_USE_DEBUG)
1154:   PetscInt       i,j;
1155: #endif

1160:   if (!m || !n) return(0); /* no values to insert */
1164:   MatCheckPreallocated(mat,1);
1165:   if (mat->insertmode == NOT_SET_VALUES) {
1166:     mat->insertmode = addv;
1167:   }
1168: #if defined(PETSC_USE_DEBUG)
1169:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1170:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1171:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);

1173:   for (i=0; i<m; i++) {
1174:     for (j=0; j<n; j++) {
1175:       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1176: #if defined(PETSC_USE_COMPLEX)
1177:         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]);
1178: #else
1179:         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1180: #endif
1181:     }
1182:   }
1183: #endif

1185:   if (mat->assembled) {
1186:     mat->was_assembled = PETSC_TRUE;
1187:     mat->assembled     = PETSC_FALSE;
1188:   }
1189:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1190:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1191:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1192: #if defined(PETSC_HAVE_CUSP)
1193:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1194:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1195:   }
1196: #elif defined(PETSC_HAVE_VIENNACL)
1197:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1198:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1199:   }
1200: #elif defined(PETSC_HAVE_VECCUDA)
1201:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1202:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1203:   }
1204: #endif
1205:   return(0);
1206: }


1211: /*@
1212:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1213:         values into a matrix

1215:    Not Collective

1217:    Input Parameters:
1218: +  mat - the matrix
1219: .  row - the (block) row to set
1220: -  v - a logically two-dimensional array of values

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

1225:    All the nonzeros in the row must be provided

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

1229:    The row must belong to this process

1231:    Level: intermediate

1233:    Concepts: matrices^putting entries in

1235: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1236:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1237: @*/
1238: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1239: {
1241:   PetscInt       globalrow;

1247:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1248:   MatSetValuesRow(mat,globalrow,v);
1249: #if defined(PETSC_HAVE_CUSP)
1250:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1251:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1252:   }
1253: #elif defined(PETSC_HAVE_VIENNACL)
1254:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1255:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1256:   }
1257: #elif defined(PETSC_HAVE_VECCUDA)
1258:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1259:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1260:   }
1261: #endif
1262:   return(0);
1263: }

1267: /*@
1268:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1269:         values into a matrix

1271:    Not Collective

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

1278:    Notes:
1279:    The values, v, are column-oriented for the block version.

1281:    All the nonzeros in the row must be provided

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

1285:    The row must belong to this process

1287:    Level: advanced

1289:    Concepts: matrices^putting entries in

1291: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1292:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1293: @*/
1294: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1295: {

1301:   MatCheckPreallocated(mat,1);
1303: #if defined(PETSC_USE_DEBUG)
1304:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1305:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1306: #endif
1307:   mat->insertmode = INSERT_VALUES;

1309:   if (mat->assembled) {
1310:     mat->was_assembled = PETSC_TRUE;
1311:     mat->assembled     = PETSC_FALSE;
1312:   }
1313:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1314:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1315:   (*mat->ops->setvaluesrow)(mat,row,v);
1316:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1317: #if defined(PETSC_HAVE_CUSP)
1318:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1319:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1320:   }
1321: #elif defined(PETSC_HAVE_VIENNACL)
1322:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1323:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1324:   }
1325: #elif defined(PETSC_HAVE_VECCUDA)
1326:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1327:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1328:   }
1329: #endif
1330:   return(0);
1331: }

1335: /*@
1336:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1337:      Using structured grid indexing

1339:    Not Collective

1341:    Input Parameters:
1342: +  mat - the matrix
1343: .  m - number of rows being entered
1344: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1345: .  n - number of columns being entered
1346: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1347: .  v - a logically two-dimensional array of values
1348: -  addv - either ADD_VALUES or INSERT_VALUES, where
1349:    ADD_VALUES adds values to any existing entries, and
1350:    INSERT_VALUES replaces existing entries with new values

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

1355:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1356:    options cannot be mixed without intervening calls to the assembly
1357:    routines.

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

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

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

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

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

1375:    In Fortran idxm and idxn should be declared as
1376: $     MatStencil idxm(4,m),idxn(4,n)
1377:    and the values inserted using
1378: $    idxm(MatStencil_i,1) = i
1379: $    idxm(MatStencil_j,1) = j
1380: $    idxm(MatStencil_k,1) = k
1381: $    idxm(MatStencil_c,1) = c
1382:    etc

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

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

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

1395:    Efficiency Alert:
1396:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1397:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1399:    Level: beginner

1401:    Concepts: matrices^putting entries in

1403: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1404:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1405: @*/
1406: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1407: {
1409:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1410:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1411:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1421:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1422:     jdxm = buf; jdxn = buf+m;
1423:   } else {
1424:     PetscMalloc2(m,&bufm,n,&bufn);
1425:     jdxm = bufm; jdxn = bufn;
1426:   }
1427:   for (i=0; i<m; i++) {
1428:     for (j=0; j<3-sdim; j++) dxm++;
1429:     tmp = *dxm++ - starts[0];
1430:     for (j=0; j<dim-1; j++) {
1431:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1432:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1433:     }
1434:     if (mat->stencil.noc) dxm++;
1435:     jdxm[i] = tmp;
1436:   }
1437:   for (i=0; i<n; i++) {
1438:     for (j=0; j<3-sdim; j++) dxn++;
1439:     tmp = *dxn++ - starts[0];
1440:     for (j=0; j<dim-1; j++) {
1441:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1442:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1443:     }
1444:     if (mat->stencil.noc) dxn++;
1445:     jdxn[i] = tmp;
1446:   }
1447:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1448:   PetscFree2(bufm,bufn);
1449:   return(0);
1450: }

1454: /*@
1455:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1456:      Using structured grid indexing

1458:    Not Collective

1460:    Input Parameters:
1461: +  mat - the matrix
1462: .  m - number of rows being entered
1463: .  idxm - grid coordinates for matrix rows being entered
1464: .  n - number of columns being entered
1465: .  idxn - grid coordinates for matrix columns being entered
1466: .  v - a logically two-dimensional array of values
1467: -  addv - either ADD_VALUES or INSERT_VALUES, where
1468:    ADD_VALUES adds values to any existing entries, and
1469:    INSERT_VALUES replaces existing entries with new values

1471:    Notes:
1472:    By default the values, v, are row-oriented and unsorted.
1473:    See MatSetOption() for other options.

1475:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1476:    options cannot be mixed without intervening calls to the assembly
1477:    routines.

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

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

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

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

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

1495:    In Fortran idxm and idxn should be declared as
1496: $     MatStencil idxm(4,m),idxn(4,n)
1497:    and the values inserted using
1498: $    idxm(MatStencil_i,1) = i
1499: $    idxm(MatStencil_j,1) = j
1500: $    idxm(MatStencil_k,1) = k
1501:    etc

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

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

1511:    Level: beginner

1513:    Concepts: matrices^putting entries in

1515: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1516:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1517:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1518: @*/
1519: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1520: {
1522:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1523:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1524:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1534:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1535:     jdxm = buf; jdxn = buf+m;
1536:   } else {
1537:     PetscMalloc2(m,&bufm,n,&bufn);
1538:     jdxm = bufm; jdxn = bufn;
1539:   }
1540:   for (i=0; i<m; i++) {
1541:     for (j=0; j<3-sdim; j++) dxm++;
1542:     tmp = *dxm++ - starts[0];
1543:     for (j=0; j<sdim-1; j++) {
1544:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1545:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1546:     }
1547:     dxm++;
1548:     jdxm[i] = tmp;
1549:   }
1550:   for (i=0; i<n; i++) {
1551:     for (j=0; j<3-sdim; j++) dxn++;
1552:     tmp = *dxn++ - starts[0];
1553:     for (j=0; j<sdim-1; j++) {
1554:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1555:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1556:     }
1557:     dxn++;
1558:     jdxn[i] = tmp;
1559:   }
1560:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1561:   PetscFree2(bufm,bufn);
1562: #if defined(PETSC_HAVE_CUSP)
1563:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1564:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1565:   }
1566: #elif defined(PETSC_HAVE_VIENNACL)
1567:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1568:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1569:   }
1570: #elif defined(PETSC_HAVE_VECCUDA)
1571:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1572:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1573:   }
1574: #endif
1575:   return(0);
1576: }

1580: /*@
1581:    MatSetStencil - Sets the grid information for setting values into a matrix via
1582:         MatSetValuesStencil()

1584:    Not Collective

1586:    Input Parameters:
1587: +  mat - the matrix
1588: .  dim - dimension of the grid 1, 2, or 3
1589: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1590: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1591: -  dof - number of degrees of freedom per node


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

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

1600:    Level: beginner

1602:    Concepts: matrices^putting entries in

1604: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1605:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1606: @*/
1607: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1608: {
1609:   PetscInt i;


1616:   mat->stencil.dim = dim + (dof > 1);
1617:   for (i=0; i<dim; i++) {
1618:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1619:     mat->stencil.starts[i] = starts[dim-i-1];
1620:   }
1621:   mat->stencil.dims[dim]   = dof;
1622:   mat->stencil.starts[dim] = 0;
1623:   mat->stencil.noc         = (PetscBool)(dof == 1);
1624:   return(0);
1625: }

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

1632:    Not Collective

1634:    Input Parameters:
1635: +  mat - the matrix
1636: .  v - a logically two-dimensional array of values
1637: .  m, idxm - the number of block rows and their global block indices
1638: .  n, idxn - the number of block columns and their global block indices
1639: -  addv - either ADD_VALUES or INSERT_VALUES, where
1640:    ADD_VALUES adds values to any existing entries, and
1641:    INSERT_VALUES replaces existing entries with new values

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

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

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

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

1659:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1660:    options cannot be mixed without intervening calls to the assembly
1661:    routines.

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

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

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

1677:    Example:
1678: $   Suppose m=n=2 and block size(bs) = 2 The array is
1679: $
1680: $   1  2  | 3  4
1681: $   5  6  | 7  8
1682: $   - - - | - - -
1683: $   9  10 | 11 12
1684: $   13 14 | 15 16
1685: $
1686: $   v[] should be passed in like
1687: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1688: $
1689: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1690: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

1692:    Level: intermediate

1694:    Concepts: matrices^putting entries in blocked

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

1705:   if (!m || !n) return(0); /* no values to insert */
1709:   MatCheckPreallocated(mat,1);
1710:   if (mat->insertmode == NOT_SET_VALUES) {
1711:     mat->insertmode = addv;
1712:   }
1713: #if defined(PETSC_USE_DEBUG)
1714:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1715:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1716:   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1717: #endif

1719:   if (mat->assembled) {
1720:     mat->was_assembled = PETSC_TRUE;
1721:     mat->assembled     = PETSC_FALSE;
1722:   }
1723:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1724:   if (mat->ops->setvaluesblocked) {
1725:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1726:   } else {
1727:     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1728:     PetscInt i,j,bs,cbs;
1729:     MatGetBlockSizes(mat,&bs,&cbs);
1730:     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1731:       iidxm = buf; iidxn = buf + m*bs;
1732:     } else {
1733:       PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1734:       iidxm = bufr; iidxn = bufc;
1735:     }
1736:     for (i=0; i<m; i++) {
1737:       for (j=0; j<bs; j++) {
1738:         iidxm[i*bs+j] = bs*idxm[i] + j;
1739:       }
1740:     }
1741:     for (i=0; i<n; i++) {
1742:       for (j=0; j<cbs; j++) {
1743:         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1744:       }
1745:     }
1746:     MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1747:     PetscFree2(bufr,bufc);
1748:   }
1749:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1750: #if defined(PETSC_HAVE_CUSP)
1751:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1752:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1753:   }
1754: #elif defined(PETSC_HAVE_VIENNACL)
1755:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1756:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1757:   }
1758: #elif defined(PETSC_HAVE_VECCUDA)
1759:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1760:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1761:   }
1762: #endif
1763:   return(0);
1764: }

1768: /*@
1769:    MatGetValues - Gets a block of values from a matrix.

1771:    Not Collective; currently only returns a local block

1773:    Input Parameters:
1774: +  mat - the matrix
1775: .  v - a logically two-dimensional array for storing the values
1776: .  m, idxm - the number of rows and their global indices
1777: -  n, idxn - the number of columns and their global indices

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

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

1787:    MatGetValues() requires that the matrix has been assembled
1788:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1789:    MatSetValues() and MatGetValues() CANNOT be made in succession
1790:    without intermediate matrix assembly.

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

1795:    Level: advanced

1797:    Concepts: matrices^accessing values

1799: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1800: @*/
1801: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1802: {

1808:   if (!m || !n) return(0);
1812:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1813:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1814:   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1815:   MatCheckPreallocated(mat,1);

1817:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1818:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1819:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1820:   return(0);
1821: }

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

1829:   Not Collective

1831:   Input Parameters:
1832: + mat - the matrix
1833: . nb - the number of blocks
1834: . bs - the number of rows (and columns) in each block
1835: . rows - a concatenation of the rows for each block
1836: - v - a concatenation of logically two-dimensional arrays of values

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

1841:   Level: advanced

1843:   Concepts: matrices^putting entries in

1845: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1846:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1847: @*/
1848: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1849: {

1857: #if defined(PETSC_USE_DEBUG)
1858:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1859: #endif

1861:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1862:   if (mat->ops->setvaluesbatch) {
1863:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1864:   } else {
1865:     PetscInt b;
1866:     for (b = 0; b < nb; ++b) {
1867:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1868:     }
1869:   }
1870:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1871:   return(0);
1872: }

1876: /*@
1877:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1878:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1879:    using a local (per-processor) numbering.

1881:    Not Collective

1883:    Input Parameters:
1884: +  x - the matrix
1885: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1886: - cmapping - column mapping

1888:    Level: intermediate

1890:    Concepts: matrices^local to global mapping
1891:    Concepts: local to global mapping^for matrices

1893: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1894: @*/
1895: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1896: {


1905:   if (x->ops->setlocaltoglobalmapping) {
1906:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1907:   } else {
1908:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1909:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1910:   }
1911:   return(0);
1912: }


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

1920:    Not Collective

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

1925:    Output Parameters:
1926: + rmapping - row mapping
1927: - cmapping - column mapping

1929:    Level: advanced

1931:    Concepts: matrices^local to global mapping
1932:    Concepts: local to global mapping^for matrices

1934: .seealso:  MatSetValuesLocal()
1935: @*/
1936: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1937: {
1943:   if (rmapping) *rmapping = A->rmap->mapping;
1944:   if (cmapping) *cmapping = A->cmap->mapping;
1945:   return(0);
1946: }

1950: /*@
1951:    MatGetLayouts - Gets the PetscLayout objects for rows and columns

1953:    Not Collective

1955:    Input Parameters:
1956: .  A - the matrix

1958:    Output Parameters:
1959: + rmap - row layout
1960: - cmap - column layout

1962:    Level: advanced

1964: .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
1965: @*/
1966: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1967: {
1973:   if (rmap) *rmap = A->rmap;
1974:   if (cmap) *cmap = A->cmap;
1975:   return(0);
1976: }

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

1984:    Not Collective

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

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

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

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

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

2008:    Level: intermediate

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

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

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

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

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

2079:    Not Collective

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

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

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

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

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

2104:    Level: intermediate

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

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

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

2132:   if (mat->assembled) {
2133:     mat->was_assembled = PETSC_TRUE;
2134:     mat->assembled     = PETSC_FALSE;
2135:   }
2136:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2137:   if (mat->ops->setvaluesblockedlocal) {
2138:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2139:   } else {
2140:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2141:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2142:       irowm = buf; icolm = buf + nrow;
2143:     } else {
2144:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2145:       irowm = bufr; icolm = bufc;
2146:     }
2147:     ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2148:     ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2149:     MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2150:     PetscFree2(bufr,bufc);
2151:   }
2152:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2153: #if defined(PETSC_HAVE_CUSP)
2154:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2155:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2156:   }
2157: #elif defined(PETSC_HAVE_VIENNACL)
2158:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2159:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2160:   }
2161: #elif defined(PETSC_HAVE_VECCUDA)
2162:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2163:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2164:   }
2165: #endif
2166:   return(0);
2167: }

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

2174:    Collective on Mat and Vec

2176:    Input Parameters:
2177: +  mat - the matrix
2178: -  x   - the vector to be multiplied

2180:    Output Parameters:
2181: .  y - the result

2183:    Notes:
2184:    The vectors x and y cannot be the same.  I.e., one cannot
2185:    call MatMult(A,y,y).

2187:    Level: developer

2189:    Concepts: matrix-vector product

2191: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2192: @*/
2193: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2194: {


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

2208:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2209:   (*mat->ops->multdiagonalblock)(mat,x,y);
2210:   PetscObjectStateIncrease((PetscObject)y);
2211:   return(0);
2212: }

2214: /* --------------------------------------------------------*/
2217: /*@
2218:    MatMult - Computes the matrix-vector product, y = Ax.

2220:    Neighbor-wise Collective on Mat and Vec

2222:    Input Parameters:
2223: +  mat - the matrix
2224: -  x   - the vector to be multiplied

2226:    Output Parameters:
2227: .  y - the result

2229:    Notes:
2230:    The vectors x and y cannot be the same.  I.e., one cannot
2231:    call MatMult(A,y,y).

2233:    Level: beginner

2235:    Concepts: matrix-vector product

2237: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2238: @*/
2239: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2240: {

2248:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2249:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2250:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2251: #if !defined(PETSC_HAVE_CONSTRAINTS)
2252:   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);
2253:   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);
2254:   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);
2255: #endif
2256:   VecLocked(y,3);
2257:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2258:   MatCheckPreallocated(mat,1);

2260:   VecLockPush(x);
2261:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2262:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2263:   (*mat->ops->mult)(mat,x,y);
2264:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2265:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2266:   VecLockPop(x);
2267:   return(0);
2268: }

2272: /*@
2273:    MatMultTranspose - Computes matrix transpose times a vector.

2275:    Neighbor-wise Collective on Mat and Vec

2277:    Input Parameters:
2278: +  mat - the matrix
2279: -  x   - the vector to be multilplied

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

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

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

2291:    Level: beginner

2293:    Concepts: matrix vector product^transpose

2295: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2296: @*/
2297: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2298: {


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

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

2330: /*@
2331:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2333:    Neighbor-wise Collective on Mat and Vec

2335:    Input Parameters:
2336: +  mat - the matrix
2337: -  x   - the vector to be multilplied

2339:    Output Parameters:
2340: .  y - the result

2342:    Notes:
2343:    The vectors x and y cannot be the same.  I.e., one cannot
2344:    call MatMultHermitianTranspose(A,y,y).

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

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

2350:    Level: beginner

2352:    Concepts: matrix vector product^transpose

2354: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2355: @*/
2356: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2357: {
2359:   Vec            w;


2367:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2368:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2369:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2370: #if !defined(PETSC_HAVE_CONSTRAINTS)
2371:   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);
2372:   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);
2373: #endif
2374:   MatCheckPreallocated(mat,1);

2376:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2377:   if (mat->ops->multhermitiantranspose) {
2378:     VecLockPush(x);
2379:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2380:     VecLockPop(x);
2381:   } else {
2382:     VecDuplicate(x,&w);
2383:     VecCopy(x,w);
2384:     VecConjugate(w);
2385:     MatMultTranspose(mat,w,y);
2386:     VecDestroy(&w);
2387:     VecConjugate(y);
2388:   }
2389:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2390:   PetscObjectStateIncrease((PetscObject)y);
2391:   return(0);
2392: }

2396: /*@
2397:     MatMultAdd -  Computes v3 = v2 + A * v1.

2399:     Neighbor-wise Collective on Mat and Vec

2401:     Input Parameters:
2402: +   mat - the matrix
2403: -   v1, v2 - the vectors

2405:     Output Parameters:
2406: .   v3 - the result

2408:     Notes:
2409:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2410:     call MatMultAdd(A,v1,v2,v1).

2412:     Level: beginner

2414:     Concepts: matrix vector product^addition

2416: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2417: @*/
2418: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2419: {


2429:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2430:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2431:   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);
2432:   /* 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);
2433:      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); */
2434:   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);
2435:   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);
2436:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2437:   MatCheckPreallocated(mat,1);

2439:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2440:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2441:   VecLockPush(v1);
2442:   (*mat->ops->multadd)(mat,v1,v2,v3);
2443:   VecLockPop(v1);
2444:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2445:   PetscObjectStateIncrease((PetscObject)v3);
2446:   return(0);
2447: }

2451: /*@
2452:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2454:    Neighbor-wise Collective on Mat and Vec

2456:    Input Parameters:
2457: +  mat - the matrix
2458: -  v1, v2 - the vectors

2460:    Output Parameters:
2461: .  v3 - the result

2463:    Notes:
2464:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2465:    call MatMultTransposeAdd(A,v1,v2,v1).

2467:    Level: beginner

2469:    Concepts: matrix vector product^transpose and addition

2471: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2472: @*/
2473: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2474: {


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

2493:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2494:   VecLockPush(v1);
2495:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2496:   VecLockPop(v1);
2497:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2498:   PetscObjectStateIncrease((PetscObject)v3);
2499:   return(0);
2500: }

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

2507:    Neighbor-wise Collective on Mat and Vec

2509:    Input Parameters:
2510: +  mat - the matrix
2511: -  v1, v2 - the vectors

2513:    Output Parameters:
2514: .  v3 - the result

2516:    Notes:
2517:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2518:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2520:    Level: beginner

2522:    Concepts: matrix vector product^transpose and addition

2524: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2525: @*/
2526: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2527: {


2537:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2538:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2539:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2540:   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);
2541:   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);
2542:   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);
2543:   MatCheckPreallocated(mat,1);

2545:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2546:   VecLockPush(v1);
2547:   if (mat->ops->multhermitiantransposeadd) {
2548:     (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2549:    } else {
2550:     Vec w,z;
2551:     VecDuplicate(v1,&w);
2552:     VecCopy(v1,w);
2553:     VecConjugate(w);
2554:     VecDuplicate(v3,&z);
2555:     MatMultTranspose(mat,w,z);
2556:     VecDestroy(&w);
2557:     VecConjugate(z);
2558:     VecWAXPY(v3,1.0,v2,z);
2559:     VecDestroy(&z);
2560:   }
2561:   VecLockPop(v1);
2562:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2563:   PetscObjectStateIncrease((PetscObject)v3);
2564:   return(0);
2565: }

2569: /*@
2570:    MatMultConstrained - The inner multiplication routine for a
2571:    constrained matrix P^T A P.

2573:    Neighbor-wise Collective on Mat and Vec

2575:    Input Parameters:
2576: +  mat - the matrix
2577: -  x   - the vector to be multilplied

2579:    Output Parameters:
2580: .  y - the result

2582:    Notes:
2583:    The vectors x and y cannot be the same.  I.e., one cannot
2584:    call MatMult(A,y,y).

2586:    Level: beginner

2588: .keywords: matrix, multiply, matrix-vector product, constraint
2589: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2590: @*/
2591: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2592: {

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

2606:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2607:   VecLockPush(x);
2608:   (*mat->ops->multconstrained)(mat,x,y);
2609:   VecLockPop(x);
2610:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2611:   PetscObjectStateIncrease((PetscObject)y);
2612:   return(0);
2613: }

2617: /*@
2618:    MatMultTransposeConstrained - The inner multiplication routine for a
2619:    constrained matrix P^T A^T P.

2621:    Neighbor-wise Collective on Mat and Vec

2623:    Input Parameters:
2624: +  mat - the matrix
2625: -  x   - the vector to be multilplied

2627:    Output Parameters:
2628: .  y - the result

2630:    Notes:
2631:    The vectors x and y cannot be the same.  I.e., one cannot
2632:    call MatMult(A,y,y).

2634:    Level: beginner

2636: .keywords: matrix, multiply, matrix-vector product, constraint
2637: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2638: @*/
2639: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2640: {

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

2653:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2654:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2655:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2656:   PetscObjectStateIncrease((PetscObject)y);
2657:   return(0);
2658: }

2662: /*@C
2663:    MatGetFactorType - gets the type of factorization it is

2665:    Note Collective
2666:    as the flag

2668:    Input Parameters:
2669: .  mat - the matrix

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

2674:     Level: intermediate

2676: .seealso:    MatFactorType, MatGetFactor()
2677: @*/
2678: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2679: {
2683:   *t = mat->factortype;
2684:   return(0);
2685: }

2687: /* ------------------------------------------------------------*/
2690: /*@C
2691:    MatGetInfo - Returns information about matrix storage (number of
2692:    nonzeros, memory, etc.).

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

2696:    Input Parameters:
2697: .  mat - the matrix

2699:    Output Parameters:
2700: +  flag - flag indicating the type of parameters to be returned
2701:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2702:    MAT_GLOBAL_SUM - sum over all processors)
2703: -  info - matrix information context

2705:    Notes:
2706:    The MatInfo context contains a variety of matrix data, including
2707:    number of nonzeros allocated and used, number of mallocs during
2708:    matrix assembly, etc.  Additional information for factored matrices
2709:    is provided (such as the fill ratio, number of mallocs during
2710:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2711:    when using the runtime options
2712: $       -info -mat_view ::ascii_info

2714:    Example for C/C++ Users:
2715:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2716:    data within the MatInfo context.  For example,
2717: .vb
2718:       MatInfo info;
2719:       Mat     A;
2720:       double  mal, nz_a, nz_u;

2722:       MatGetInfo(A,MAT_LOCAL,&info);
2723:       mal  = info.mallocs;
2724:       nz_a = info.nz_allocated;
2725: .ve

2727:    Example for Fortran Users:
2728:    Fortran users should declare info as a double precision
2729:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2730:    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2731:    a complete list of parameter names.
2732: .vb
2733:       double  precision info(MAT_INFO_SIZE)
2734:       double  precision mal, nz_a
2735:       Mat     A
2736:       integer ierr

2738:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2739:       mal = info(MAT_INFO_MALLOCS)
2740:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2741: .ve

2743:     Level: intermediate

2745:     Concepts: matrices^getting information on

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

2750: .seealso: MatStashGetInfo()

2752: @*/
2753: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2754: {

2761:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2762:   MatCheckPreallocated(mat,1);
2763:   (*mat->ops->getinfo)(mat,flag,info);
2764:   return(0);
2765: }

2767: /* ----------------------------------------------------------*/

2771: /*@C
2772:    MatLUFactor - Performs in-place LU factorization of matrix.

2774:    Collective on Mat

2776:    Input Parameters:
2777: +  mat - the matrix
2778: .  row - row permutation
2779: .  col - column permutation
2780: -  info - options for factorization, includes
2781: $          fill - expected fill as ratio of original fill.
2782: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2783: $                   Run with the option -info to determine an optimal value to use

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

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

2793:    Level: developer

2795:    Concepts: matrices^LU factorization

2797: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2798:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2803: @*/
2804: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2805: {
2807:   MatFactorInfo  tinfo;

2815:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2816:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2817:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2818:   MatCheckPreallocated(mat,1);
2819:   if (!info) {
2820:     MatFactorInfoInitialize(&tinfo);
2821:     info = &tinfo;
2822:   }

2824:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2825:   (*mat->ops->lufactor)(mat,row,col,info);
2826:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2827:   PetscObjectStateIncrease((PetscObject)mat);
2828:   return(0);
2829: }

2833: /*@C
2834:    MatILUFactor - Performs in-place ILU factorization of matrix.

2836:    Collective on Mat

2838:    Input Parameters:
2839: +  mat - the matrix
2840: .  row - row permutation
2841: .  col - column permutation
2842: -  info - structure containing
2843: $      levels - number of levels of fill.
2844: $      expected fill - as ratio of original fill.
2845: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2846:                 missing diagonal entries)

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

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

2856:    Level: developer

2858:    Concepts: matrices^ILU factorization

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

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

2865: @*/
2866: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2867: {

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

2882:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2883:   (*mat->ops->ilufactor)(mat,row,col,info);
2884:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2885:   PetscObjectStateIncrease((PetscObject)mat);
2886:   return(0);
2887: }

2891: /*@C
2892:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2893:    Call this routine before calling MatLUFactorNumeric().

2895:    Collective on Mat

2897:    Input Parameters:
2898: +  fact - the factor matrix obtained with MatGetFactor()
2899: .  mat - the matrix
2900: .  row, col - row and column permutations
2901: -  info - options for factorization, includes
2902: $          fill - expected fill as ratio of original fill.
2903: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2904: $                   Run with the option -info to determine an optimal value to use


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

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

2913:    Level: developer

2915:    Concepts: matrices^LU symbolic factorization

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

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

2922: @*/
2923: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2924: {

2934:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2935:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2936:   if (!(fact)->ops->lufactorsymbolic) {
2937:     const MatSolverPackage spackage;
2938:     MatFactorGetSolverPackage(fact,&spackage);
2939:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2940:   }
2941:   MatCheckPreallocated(mat,2);

2943:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2944:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2945:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2946:   PetscObjectStateIncrease((PetscObject)fact);
2947:   return(0);
2948: }

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

2956:    Collective on Mat

2958:    Input Parameters:
2959: +  fact - the factor matrix obtained with MatGetFactor()
2960: .  mat - the matrix
2961: -  info - options for factorization

2963:    Notes:
2964:    See MatLUFactor() for in-place factorization.  See
2965:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

2971:    Level: developer

2973:    Concepts: matrices^LU numeric factorization

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

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

2980: @*/
2981: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2982: {

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

2993:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2994:   MatCheckPreallocated(mat,2);
2995:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2996:   (fact->ops->lufactornumeric)(fact,mat,info);
2997:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2998:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
2999:   PetscObjectStateIncrease((PetscObject)fact);
3000:   return(0);
3001: }

3005: /*@C
3006:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3007:    symmetric matrix.

3009:    Collective on Mat

3011:    Input Parameters:
3012: +  mat - the matrix
3013: .  perm - row and column permutations
3014: -  f - expected fill as ratio of original fill

3016:    Notes:
3017:    See MatLUFactor() for the nonsymmetric case.  See also
3018:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

3024:    Level: developer

3026:    Concepts: matrices^Cholesky factorization

3028: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3029:           MatGetOrdering()

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

3034: @*/
3035: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3036: {

3044:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3045:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3046:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3047:   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3048:   MatCheckPreallocated(mat,1);

3050:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3051:   (*mat->ops->choleskyfactor)(mat,perm,info);
3052:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3053:   PetscObjectStateIncrease((PetscObject)mat);
3054:   return(0);
3055: }

3059: /*@C
3060:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3061:    of a symmetric matrix.

3063:    Collective on Mat

3065:    Input Parameters:
3066: +  fact - the factor matrix obtained with MatGetFactor()
3067: .  mat - the matrix
3068: .  perm - row and column permutations
3069: -  info - options for factorization, includes
3070: $          fill - expected fill as ratio of original fill.
3071: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3072: $                   Run with the option -info to determine an optimal value to use

3074:    Notes:
3075:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3076:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

3082:    Level: developer

3084:    Concepts: matrices^Cholesky symbolic factorization

3086: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3087:           MatGetOrdering()

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

3092: @*/
3093: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3094: {

3103:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3104:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3105:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3106:   if (!(fact)->ops->choleskyfactorsymbolic) {
3107:     const MatSolverPackage spackage;
3108:     MatFactorGetSolverPackage(fact,&spackage);
3109:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3110:   }
3111:   MatCheckPreallocated(mat,2);

3113:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3114:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3115:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3116:   PetscObjectStateIncrease((PetscObject)fact);
3117:   return(0);
3118: }

3122: /*@C
3123:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3124:    of a symmetric matrix. Call this routine after first calling
3125:    MatCholeskyFactorSymbolic().

3127:    Collective on Mat

3129:    Input Parameters:
3130: +  fact - the factor matrix obtained with MatGetFactor()
3131: .  mat - the initial matrix
3132: .  info - options for factorization
3133: -  fact - the symbolic factor of mat


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

3141:    Level: developer

3143:    Concepts: matrices^Cholesky numeric factorization

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

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

3150: @*/
3151: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3152: {

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

3165:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3166:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3167:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3168:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3169:   PetscObjectStateIncrease((PetscObject)fact);
3170:   return(0);
3171: }

3173: /* ----------------------------------------------------------------*/
3176: /*@
3177:    MatSolve - Solves A x = b, given a factored matrix.

3179:    Neighbor-wise Collective on Mat and Vec

3181:    Input Parameters:
3182: +  mat - the factored matrix
3183: -  b - the right-hand-side vector

3185:    Output Parameter:
3186: .  x - the result vector

3188:    Notes:
3189:    The vectors b and x cannot be the same.  I.e., one cannot
3190:    call MatSolve(A,x,x).

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

3197:    Level: developer

3199:    Concepts: matrices^triangular solves

3201: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3202: @*/
3203: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3204: {

3214:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3215:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3216:   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);
3217:   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);
3218:   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);
3219:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3220:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3221:   MatCheckPreallocated(mat,1);

3223:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3224:   if (mat->errortype) {
3225:     PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3226:     VecSetInf(x);
3227:   } else {
3228:     (*mat->ops->solve)(mat,b,x);
3229:   }
3230:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3231:   PetscObjectStateIncrease((PetscObject)x);
3232:   return(0);
3233: }

3237: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3238: {
3240:   Vec            b,x;
3241:   PetscInt       m,N,i;
3242:   PetscScalar    *bb,*xx;
3243:   PetscBool      flg;

3246:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3247:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3248:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3249:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3251:   MatDenseGetArray(B,&bb);
3252:   MatDenseGetArray(X,&xx);
3253:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3254:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3255:   MatCreateVecs(A,&x,&b);
3256:   for (i=0; i<N; i++) {
3257:     VecPlaceArray(b,bb + i*m);
3258:     VecPlaceArray(x,xx + i*m);
3259:     MatSolve(A,b,x);
3260:     VecResetArray(x);
3261:     VecResetArray(b);
3262:   }
3263:   VecDestroy(&b);
3264:   VecDestroy(&x);
3265:   MatDenseRestoreArray(B,&bb);
3266:   MatDenseRestoreArray(X,&xx);
3267:   return(0);
3268: }

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

3275:    Neighbor-wise Collective on Mat

3277:    Input Parameters:
3278: +  A - the factored matrix
3279: -  B - the right-hand-side matrix  (dense matrix)

3281:    Output Parameter:
3282: .  X - the result matrix (dense matrix)

3284:    Notes:
3285:    The matrices b and x cannot be the same.  I.e., one cannot
3286:    call MatMatSolve(A,x,x).

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

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

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

3299:    Level: developer

3301:    Concepts: matrices^triangular solves

3303: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3304: @*/
3305: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3306: {

3316:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3317:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3318:   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);
3319:   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);
3320:   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);
3321:   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3322:   if (!A->rmap->N && !A->cmap->N) return(0);
3323:   MatCheckPreallocated(A,1);

3325:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3326:   if (!A->ops->matsolve) {
3327:     PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3328:     MatMatSolve_Basic(A,B,X);
3329:   } else {
3330:     (*A->ops->matsolve)(A,B,X);
3331:   }
3332:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3333:   PetscObjectStateIncrease((PetscObject)X);
3334:   return(0);
3335: }


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

3344:    Neighbor-wise Collective on Mat and Vec

3346:    Input Parameters:
3347: +  mat - the factored matrix
3348: -  b - the right-hand-side vector

3350:    Output Parameter:
3351: .  x - the result vector

3353:    Notes:
3354:    MatSolve() should be used for most applications, as it performs
3355:    a forward solve followed by a backward solve.

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

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

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

3370:    Level: developer

3372:    Concepts: matrices^forward solves

3374: .seealso: MatSolve(), MatBackwardSolve()
3375: @*/
3376: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3377: {

3387:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3388:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3389:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3390:   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);
3391:   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);
3392:   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);
3393:   MatCheckPreallocated(mat,1);
3394:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3395:   (*mat->ops->forwardsolve)(mat,b,x);
3396:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3397:   PetscObjectStateIncrease((PetscObject)x);
3398:   return(0);
3399: }

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

3407:    Neighbor-wise Collective on Mat and Vec

3409:    Input Parameters:
3410: +  mat - the factored matrix
3411: -  b - the right-hand-side vector

3413:    Output Parameter:
3414: .  x - the result vector

3416:    Notes:
3417:    MatSolve() should be used for most applications, as it performs
3418:    a forward solve followed by a backward solve.

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

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

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

3433:    Level: developer

3435:    Concepts: matrices^backward solves

3437: .seealso: MatSolve(), MatForwardSolve()
3438: @*/
3439: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3440: {

3450:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3451:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3452:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3453:   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);
3454:   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);
3455:   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);
3456:   MatCheckPreallocated(mat,1);

3458:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3459:   (*mat->ops->backwardsolve)(mat,b,x);
3460:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3461:   PetscObjectStateIncrease((PetscObject)x);
3462:   return(0);
3463: }

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

3470:    Neighbor-wise Collective on Mat and Vec

3472:    Input Parameters:
3473: +  mat - the factored matrix
3474: .  b - the right-hand-side vector
3475: -  y - the vector to be added to

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

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

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

3488:    Level: developer

3490:    Concepts: matrices^triangular solves

3492: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3493: @*/
3494: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3495: {
3496:   PetscScalar    one = 1.0;
3497:   Vec            tmp;

3509:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3510:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3511:   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);
3512:   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);
3513:   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);
3514:   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);
3515:   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);
3516:   MatCheckPreallocated(mat,1);

3518:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3519:   if (mat->ops->solveadd) {
3520:     (*mat->ops->solveadd)(mat,b,y,x);
3521:   } else {
3522:     /* do the solve then the add manually */
3523:     if (x != y) {
3524:       MatSolve(mat,b,x);
3525:       VecAXPY(x,one,y);
3526:     } else {
3527:       VecDuplicate(x,&tmp);
3528:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3529:       VecCopy(x,tmp);
3530:       MatSolve(mat,b,x);
3531:       VecAXPY(x,one,tmp);
3532:       VecDestroy(&tmp);
3533:     }
3534:   }
3535:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3536:   PetscObjectStateIncrease((PetscObject)x);
3537:   return(0);
3538: }

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

3545:    Neighbor-wise Collective on Mat and Vec

3547:    Input Parameters:
3548: +  mat - the factored matrix
3549: -  b - the right-hand-side vector

3551:    Output Parameter:
3552: .  x - the result vector

3554:    Notes:
3555:    The vectors b and x cannot be the same.  I.e., one cannot
3556:    call MatSolveTranspose(A,x,x).

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

3562:    Level: developer

3564:    Concepts: matrices^triangular solves

3566: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3567: @*/
3568: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3569: {

3579:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3580:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3581:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3582:   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);
3583:   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);
3584:   MatCheckPreallocated(mat,1);
3585:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3586:   if (mat->errortype) {
3587:     PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3588:     VecSetInf(x);
3589:   } else {
3590:     (*mat->ops->solvetranspose)(mat,b,x);
3591:   }
3592:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3593:   PetscObjectStateIncrease((PetscObject)x);
3594:   return(0);
3595: }

3599: /*@
3600:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3601:                       factored matrix.

3603:    Neighbor-wise Collective on Mat and Vec

3605:    Input Parameters:
3606: +  mat - the factored matrix
3607: .  b - the right-hand-side vector
3608: -  y - the vector to be added to

3610:    Output Parameter:
3611: .  x - the result vector

3613:    Notes:
3614:    The vectors b and x cannot be the same.  I.e., one cannot
3615:    call MatSolveTransposeAdd(A,x,y,x).

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

3621:    Level: developer

3623:    Concepts: matrices^triangular solves

3625: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3626: @*/
3627: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3628: {
3629:   PetscScalar    one = 1.0;
3631:   Vec            tmp;

3642:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3643:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3644:   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);
3645:   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);
3646:   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);
3647:   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);
3648:   MatCheckPreallocated(mat,1);

3650:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3651:   if (mat->ops->solvetransposeadd) {
3652:     if (mat->errortype) {
3653:       PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3654:       VecSetInf(x);
3655:     } else {
3656:       (*mat->ops->solvetransposeadd)(mat,b,y,x);
3657:     }
3658:   } else {
3659:     /* do the solve then the add manually */
3660:     if (x != y) {
3661:       MatSolveTranspose(mat,b,x);
3662:       VecAXPY(x,one,y);
3663:     } else {
3664:       VecDuplicate(x,&tmp);
3665:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3666:       VecCopy(x,tmp);
3667:       MatSolveTranspose(mat,b,x);
3668:       VecAXPY(x,one,tmp);
3669:       VecDestroy(&tmp);
3670:     }
3671:   }
3672:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3673:   PetscObjectStateIncrease((PetscObject)x);
3674:   return(0);
3675: }
3676: /* ----------------------------------------------------------------*/

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

3683:    Neighbor-wise Collective on Mat and Vec

3685:    Input Parameters:
3686: +  mat - the matrix
3687: .  b - the right hand side
3688: .  omega - the relaxation factor
3689: .  flag - flag indicating the type of SOR (see below)
3690: .  shift -  diagonal shift
3691: .  its - the number of iterations
3692: -  lits - the number of local iterations

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

3697:    SOR Flags:
3698: .     SOR_FORWARD_SWEEP - forward SOR
3699: .     SOR_BACKWARD_SWEEP - backward SOR
3700: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3701: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3702: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3703: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3704: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3705:          upper/lower triangular part of matrix to
3706:          vector (with omega)
3707: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3709:    Notes:
3710:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3711:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3712:    on each processor.

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

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

3719:    Notes for Advanced Users:
3720:    The flags are implemented as bitwise inclusive or operations.
3721:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3722:    to specify a zero initial guess for SSOR.

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

3728:    Vectors x and b CANNOT be the same

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

3732:    Level: developer

3734:    Concepts: matrices^relaxation
3735:    Concepts: matrices^SOR
3736:    Concepts: matrices^Gauss-Seidel

3738: @*/
3739: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3740: {

3750:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3751:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3752:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3753:   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);
3754:   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);
3755:   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);
3756:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3757:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3758:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3760:   MatCheckPreallocated(mat,1);
3761:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3762:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3763:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3764:   PetscObjectStateIncrease((PetscObject)x);
3765:   return(0);
3766: }

3770: /*
3771:       Default matrix copy routine.
3772: */
3773: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3774: {
3775:   PetscErrorCode    ierr;
3776:   PetscInt          i,rstart = 0,rend = 0,nz;
3777:   const PetscInt    *cwork;
3778:   const PetscScalar *vwork;

3781:   if (B->assembled) {
3782:     MatZeroEntries(B);
3783:   }
3784:   MatGetOwnershipRange(A,&rstart,&rend);
3785:   for (i=rstart; i<rend; i++) {
3786:     MatGetRow(A,i,&nz,&cwork,&vwork);
3787:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3788:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3789:   }
3790:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3791:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3792:   PetscObjectStateIncrease((PetscObject)B);
3793:   return(0);
3794: }

3798: /*@
3799:    MatCopy - Copys a matrix to another matrix.

3801:    Collective on Mat

3803:    Input Parameters:
3804: +  A - the matrix
3805: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3807:    Output Parameter:
3808: .  B - where the copy is put

3810:    Notes:
3811:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3812:    same nonzero pattern or the routine will crash.

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

3818:    Level: intermediate

3820:    Concepts: matrices^copying

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

3824: @*/
3825: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3826: {
3828:   PetscInt       i;

3836:   MatCheckPreallocated(B,2);
3837:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3838:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3839:   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);
3840:   MatCheckPreallocated(A,1);

3842:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3843:   if (A->ops->copy) {
3844:     (*A->ops->copy)(A,B,str);
3845:   } else { /* generic conversion */
3846:     MatCopy_Basic(A,B,str);
3847:   }

3849:   B->stencil.dim = A->stencil.dim;
3850:   B->stencil.noc = A->stencil.noc;
3851:   for (i=0; i<=A->stencil.dim; i++) {
3852:     B->stencil.dims[i]   = A->stencil.dims[i];
3853:     B->stencil.starts[i] = A->stencil.starts[i];
3854:   }

3856:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3857:   PetscObjectStateIncrease((PetscObject)B);
3858:   return(0);
3859: }

3863: /*@C
3864:    MatConvert - Converts a matrix to another matrix, either of the same
3865:    or different type.

3867:    Collective on Mat

3869:    Input Parameters:
3870: +  mat - the matrix
3871: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3872:    same type as the original matrix.
3873: -  reuse - denotes if the destination matrix is to be created or reused.
3874:    Use MAT_INPLACE_MATRIX for inplace conversion, otherwise use
3875:    MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX.

3877:    Output Parameter:
3878: .  M - pointer to place new matrix

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

3885:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3886:    the MPI communicator of the generated matrix is always the same as the communicator
3887:    of the input matrix.

3889:    Level: intermediate

3891:    Concepts: matrices^converting between storage formats

3893: .seealso: MatCopy(), MatDuplicate()
3894: @*/
3895: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3896: {
3898:   PetscBool      sametype,issame,flg;
3899:   char           convname[256],mtype[256];
3900:   Mat            B;

3906:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3907:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3908:   MatCheckPreallocated(mat,1);
3909:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

3911:   PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3912:   if (flg) {
3913:     newtype = mtype;
3914:   }
3915:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3916:   PetscStrcmp(newtype,"same",&issame);
3917:   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");

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

3921:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3922:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3923:   } else {
3924:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3925:     const char     *prefix[3] = {"seq","mpi",""};
3926:     PetscInt       i;
3927:     /*
3928:        Order of precedence:
3929:        1) See if a specialized converter is known to the current matrix.
3930:        2) See if a specialized converter is known to the desired matrix class.
3931:        3) See if a good general converter is registered for the desired class
3932:           (as of 6/27/03 only MATMPIADJ falls into this category).
3933:        4) See if a good general converter is known for the current matrix.
3934:        5) Use a really basic converter.
3935:     */

3937:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3938:     for (i=0; i<3; i++) {
3939:       PetscStrcpy(convname,"MatConvert_");
3940:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3941:       PetscStrcat(convname,"_");
3942:       PetscStrcat(convname,prefix[i]);
3943:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3944:       PetscStrcat(convname,"_C");
3945:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3946:       if (conv) goto foundconv;
3947:     }

3949:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3950:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
3951:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3952:     MatSetType(B,newtype);
3953:     for (i=0; i<3; i++) {
3954:       PetscStrcpy(convname,"MatConvert_");
3955:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3956:       PetscStrcat(convname,"_");
3957:       PetscStrcat(convname,prefix[i]);
3958:       PetscStrcat(convname,newtype);
3959:       PetscStrcat(convname,"_C");
3960:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3961:       if (conv) {
3962:         MatDestroy(&B);
3963:         goto foundconv;
3964:       }
3965:     }

3967:     /* 3) See if a good general converter is registered for the desired class */
3968:     conv = B->ops->convertfrom;
3969:     MatDestroy(&B);
3970:     if (conv) goto foundconv;

3972:     /* 4) See if a good general converter is known for the current matrix */
3973:     if (mat->ops->convert) {
3974:       conv = mat->ops->convert;
3975:     }
3976:     if (conv) goto foundconv;

3978:     /* 5) Use a really basic converter. */
3979:     conv = MatConvert_Basic;

3981: foundconv:
3982:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3983:     (*conv)(mat,newtype,reuse,M);
3984:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3985:   }
3986:   PetscObjectStateIncrease((PetscObject)*M);

3988:   /* Copy Mat options */
3989:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3990:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3991:   return(0);
3992: }

3996: /*@C
3997:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3999:    Not Collective

4001:    Input Parameter:
4002: .  mat - the matrix, must be a factored matrix

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

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

4011:    Level: intermediate

4013: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4014: @*/
4015: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4016: {
4017:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

4022:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4023:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
4024:   if (!conv) {
4025:     *type = MATSOLVERPETSC;
4026:   } else {
4027:     (*conv)(mat,type);
4028:   }
4029:   return(0);
4030: }

4032: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4033: struct _MatSolverPackageForSpecifcType {
4034:   MatType                        mtype;
4035:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4036:   MatSolverPackageForSpecifcType next;
4037: };

4039: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4040: struct _MatSolverPackageHolder {
4041:   char                           *name;
4042:   MatSolverPackageForSpecifcType handlers;
4043:   MatSolverPackageHolder         next;
4044: };

4046: static MatSolverPackageHolder MatSolverPackageHolders = NULL;

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

4053:    Input Parameters:
4054: +    package - name of the package, for example petsc or superlu
4055: .    mtype - the matrix type that works with this package
4056: .    ftype - the type of factorization supported by the package
4057: -    getfactor - routine that will create the factored matrix ready to be used

4059:     Level: intermediate

4061: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4062: @*/
4063: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4064: {
4065:   PetscErrorCode                 ierr;
4066:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4067:   PetscBool                      flg;
4068:   MatSolverPackageForSpecifcType inext,iprev = NULL;

4071:   if (!next) {
4072:     PetscNew(&MatSolverPackageHolders);
4073:     PetscStrallocpy(package,&MatSolverPackageHolders->name);
4074:     PetscNew(&MatSolverPackageHolders->handlers);
4075:     PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4076:     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4077:     return(0);
4078:   }
4079:   while (next) {
4080:     PetscStrcasecmp(package,next->name,&flg);
4081:     if (flg) {
4082:       inext = next->handlers;
4083:       while (inext) {
4084:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4085:         if (flg) {
4086:           inext->getfactor[(int)ftype-1] = getfactor;
4087:           return(0);
4088:         }
4089:         iprev = inext;
4090:         inext = inext->next;
4091:       }
4092:       PetscNew(&iprev->next);
4093:       PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4094:       iprev->next->getfactor[(int)ftype-1] = getfactor;
4095:       return(0);
4096:     }
4097:     prev = next;
4098:     next = next->next;
4099:   }
4100:   PetscNew(&prev->next);
4101:   PetscStrallocpy(package,&prev->next->name);
4102:   PetscNew(&prev->next->handlers);
4103:   PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4104:   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4105:   return(0);
4106: }

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

4113:    Input Parameters:
4114: +    package - name of the package, for example petsc or superlu
4115: .    ftype - the type of factorization supported by the package
4116: -    mtype - the matrix type that works with this package

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

4123:     Level: intermediate

4125: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4126: @*/
4127: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4128: {
4129:   PetscErrorCode                 ierr;
4130:   MatSolverPackageHolder         next = MatSolverPackageHolders;
4131:   PetscBool                      flg;
4132:   MatSolverPackageForSpecifcType inext;

4135:   if (foundpackage) *foundpackage = PETSC_FALSE;
4136:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4137:   if (getfactor)    *getfactor    = NULL;

4139:   if (package) {
4140:     while (next) {
4141:       PetscStrcasecmp(package,next->name,&flg);
4142:       if (flg) {
4143:         if (foundpackage) *foundpackage = PETSC_TRUE;
4144:         inext = next->handlers;
4145:         while (inext) {
4146:           PetscStrcasecmp(mtype,inext->mtype,&flg);
4147:           if (flg) {
4148:             if (foundmtype) *foundmtype = PETSC_TRUE;
4149:             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4150:             return(0);
4151:           }
4152:           inext = inext->next;
4153:         }
4154:       }
4155:       next = next->next;
4156:     }
4157:   } else {
4158:     while (next) {
4159:       inext = next->handlers;
4160:       while (inext) {
4161:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4162:         if (flg && inext->getfactor[(int)ftype-1]) {
4163:           if (foundpackage) *foundpackage = PETSC_TRUE;
4164:           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4165:           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4166:           return(0);
4167:         }
4168:         inext = inext->next;
4169:       }
4170:       next = next->next;
4171:     }
4172:   }
4173:   return(0);
4174: }

4178: PetscErrorCode MatSolverPackageDestroy(void)
4179: {
4180:   PetscErrorCode                 ierr;
4181:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4182:   MatSolverPackageForSpecifcType inext,iprev;

4185:   while (next) {
4186:     PetscFree(next->name);
4187:     inext = next->handlers;
4188:     while (inext) {
4189:       PetscFree(inext->mtype);
4190:       iprev = inext;
4191:       inext = inext->next;
4192:       PetscFree(iprev);
4193:     }
4194:     prev = next;
4195:     next = next->next;
4196:     PetscFree(prev);
4197:   }
4198:   MatSolverPackageHolders = NULL;
4199:   return(0);
4200: }

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

4207:    Collective on Mat

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

4214:    Output Parameters:
4215: .  f - the factor matrix used with MatXXFactorSymbolic() calls

4217:    Notes:
4218:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4219:      such as pastix, superlu, mumps etc.

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

4223:    Level: intermediate

4225: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4226: @*/
4227: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4228: {
4229:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4230:   PetscBool      foundpackage,foundmtype;


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

4239:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4240:   if (!foundpackage) {
4241:     if (type) {
4242:       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4243:     } else {
4244:       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4245:     }
4246:   }
4247: 
4248:   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4249:   if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support factorization type %s for  matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);

4251:   (*conv)(mat,ftype,f);
4252:   return(0);
4253: }

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

4260:    Not Collective

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

4267:    Output Parameter:
4268: .    flg - PETSC_TRUE if the factorization is available

4270:    Notes:
4271:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4272:      such as pastix, superlu, mumps etc.

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

4276:    Level: intermediate

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


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

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

4299: #include <petscdmtypes.h>

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

4306:    Collective on Mat

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

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

4316:    Level: intermediate

4318:    Concepts: matrices^duplicating

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

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

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

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

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

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

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

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

4369:    Logically Collective on Mat and Vec

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

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

4378:    Level: intermediate

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

4383:    Concepts: matrices^accessing diagonals

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

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

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

4406: /*@C
4407:    MatGetRowMin - Gets the minimum value (of the real part) of each
4408:         row of the matrix

4410:    Logically Collective on Mat and Vec

4412:    Input Parameters:
4413: .  mat - the matrix

4415:    Output Parameter:
4416: +  v - the vector for storing the maximums
4417: -  idx - the indices of the column found for each row (optional)

4419:    Level: intermediate

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

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

4426:    Concepts: matrices^getting row maximums

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

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

4443:   (*mat->ops->getrowmin)(mat,v,idx);
4444:   PetscObjectStateIncrease((PetscObject)v);
4445:   return(0);
4446: }

4450: /*@C
4451:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4452:         row of the matrix

4454:    Logically Collective on Mat and Vec

4456:    Input Parameters:
4457: .  mat - the matrix

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

4463:    Level: intermediate

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

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

4470:    Concepts: matrices^getting row maximums

4472: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4473: @*/
4474: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4475: {

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

4487:   (*mat->ops->getrowminabs)(mat,v,idx);
4488:   PetscObjectStateIncrease((PetscObject)v);
4489:   return(0);
4490: }

4494: /*@C
4495:    MatGetRowMax - Gets the maximum value (of the real part) of each
4496:         row of the matrix

4498:    Logically Collective on Mat and Vec

4500:    Input Parameters:
4501: .  mat - the matrix

4503:    Output Parameter:
4504: +  v - the vector for storing the maximums
4505: -  idx - the indices of the column found for each row (optional)

4507:    Level: intermediate

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

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

4514:    Concepts: matrices^getting row maximums

4516: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4517: @*/
4518: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4519: {

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

4530:   (*mat->ops->getrowmax)(mat,v,idx);
4531:   PetscObjectStateIncrease((PetscObject)v);
4532:   return(0);
4533: }

4537: /*@C
4538:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4539:         row of the matrix

4541:    Logically Collective on Mat and Vec

4543:    Input Parameters:
4544: .  mat - the matrix

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

4550:    Level: intermediate

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

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

4557:    Concepts: matrices^getting row maximums

4559: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4560: @*/
4561: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4562: {

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

4574:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4575:   PetscObjectStateIncrease((PetscObject)v);
4576:   return(0);
4577: }

4581: /*@
4582:    MatGetRowSum - Gets the sum of each row of the matrix

4584:    Logically Collective on Mat and Vec

4586:    Input Parameters:
4587: .  mat - the matrix

4589:    Output Parameter:
4590: .  v - the vector for storing the sum of rows

4592:    Level: intermediate

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

4596:    Concepts: matrices^getting row sums

4598: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4599: @*/
4600: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4601: {
4602:   PetscInt       start = 0, end = 0, row;
4603:   PetscScalar    *array;

4610:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4611:   MatCheckPreallocated(mat,1);
4612:   MatGetOwnershipRange(mat, &start, &end);
4613:   VecGetArray(v, &array);
4614:   for (row = start; row < end; ++row) {
4615:     PetscInt          ncols, col;
4616:     const PetscInt    *cols;
4617:     const PetscScalar *vals;

4619:     array[row - start] = 0.0;

4621:     MatGetRow(mat, row, &ncols, &cols, &vals);
4622:     for (col = 0; col < ncols; col++) {
4623:       array[row - start] += vals[col];
4624:     }
4625:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4626:   }
4627:   VecRestoreArray(v, &array);
4628:   PetscObjectStateIncrease((PetscObject) v);
4629:   return(0);
4630: }

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

4637:    Collective on Mat

4639:    Input Parameter:
4640: +  mat - the matrix to transpose
4641: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4643:    Output Parameters:
4644: .  B - the transpose

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

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

4651:    Level: intermediate

4653:    Concepts: matrices^transposing

4655: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4656: @*/
4657: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4658: {

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

4669:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4670:   (*mat->ops->transpose)(mat,reuse,B);
4671:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4672:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4673:   return(0);
4674: }

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

4682:    Collective on Mat

4684:    Input Parameter:
4685: +  A - the matrix to test
4686: -  B - the matrix to test against, this can equal the first parameter

4688:    Output Parameters:
4689: .  flg - the result

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

4696:    Level: intermediate

4698:    Concepts: matrices^transposing, matrix^symmetry

4700: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4701: @*/
4702: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4703: {
4704:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4710:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4711:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4712:   *flg = PETSC_FALSE;
4713:   if (f && g) {
4714:     if (f == g) {
4715:       (*f)(A,B,tol,flg);
4716:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4717:   } else {
4718:     MatType mattype;
4719:     if (!f) {
4720:       MatGetType(A,&mattype);
4721:     } else {
4722:       MatGetType(B,&mattype);
4723:     }
4724:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4725:   }
4726:   return(0);
4727: }

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

4734:    Collective on Mat

4736:    Input Parameter:
4737: +  mat - the matrix to transpose and complex conjugate
4738: -  reuse - store the transpose matrix in the provided B

4740:    Output Parameters:
4741: .  B - the Hermitian

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

4746:    Level: intermediate

4748:    Concepts: matrices^transposing, complex conjugatex

4750: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4751: @*/
4752: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4753: {

4757:   MatTranspose(mat,reuse,B);
4758: #if defined(PETSC_USE_COMPLEX)
4759:   MatConjugate(*B);
4760: #endif
4761:   return(0);
4762: }

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

4769:    Collective on Mat

4771:    Input Parameter:
4772: +  A - the matrix to test
4773: -  B - the matrix to test against, this can equal the first parameter

4775:    Output Parameters:
4776: .  flg - the result

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

4783:    Level: intermediate

4785:    Concepts: matrices^transposing, matrix^symmetry

4787: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4788: @*/
4789: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4790: {
4791:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4797:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4798:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4799:   if (f && g) {
4800:     if (f==g) {
4801:       (*f)(A,B,tol,flg);
4802:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4803:   }
4804:   return(0);
4805: }

4809: /*@
4810:    MatPermute - Creates a new matrix with rows and columns permuted from the
4811:    original.

4813:    Collective on Mat

4815:    Input Parameters:
4816: +  mat - the matrix to permute
4817: .  row - row permutation, each processor supplies only the permutation for its rows
4818: -  col - column permutation, each processor supplies only the permutation for its columns

4820:    Output Parameters:
4821: .  B - the permuted matrix

4823:    Level: advanced

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

4829:    Concepts: matrices^permuting

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

4833: @*/
4834: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4835: {

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

4849:   (*mat->ops->permute)(mat,row,col,B);
4850:   PetscObjectStateIncrease((PetscObject)*B);
4851:   return(0);
4852: }

4856: /*@
4857:    MatEqual - Compares two matrices.

4859:    Collective on Mat

4861:    Input Parameters:
4862: +  A - the first matrix
4863: -  B - the second matrix

4865:    Output Parameter:
4866: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4868:    Level: intermediate

4870:    Concepts: matrices^equality between
4871: @*/
4872: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4873: {

4883:   MatCheckPreallocated(B,2);
4884:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4885:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4886:   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);
4887:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4888:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4889:   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);
4890:   MatCheckPreallocated(A,1);

4892:   (*A->ops->equal)(A,B,flg);
4893:   return(0);
4894: }

4898: /*@
4899:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4900:    matrices that are stored as vectors.  Either of the two scaling
4901:    matrices can be NULL.

4903:    Collective on Mat

4905:    Input Parameters:
4906: +  mat - the matrix to be scaled
4907: .  l - the left scaling vector (or NULL)
4908: -  r - the right scaling vector (or NULL)

4910:    Notes:
4911:    MatDiagonalScale() computes A = LAR, where
4912:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4913:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4915:    Level: intermediate

4917:    Concepts: matrices^diagonal scaling
4918:    Concepts: diagonal scaling of matrices

4920: .seealso: MatScale()
4921: @*/
4922: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4923: {

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

4936:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4937:   (*mat->ops->diagonalscale)(mat,l,r);
4938:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4939:   PetscObjectStateIncrease((PetscObject)mat);
4940: #if defined(PETSC_HAVE_CUSP)
4941:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4942:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4943:   }
4944: #elif defined(PETSC_HAVE_VIENNACL)
4945:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4946:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4947:   }
4948: #elif defined(PETSC_HAVE_VECCUDA)
4949:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4950:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4951:   }
4952: #endif
4953:   return(0);
4954: }

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

4961:     Logically Collective on Mat

4963:     Input Parameters:
4964: +   mat - the matrix to be scaled
4965: -   a  - the scaling value

4967:     Output Parameter:
4968: .   mat - the scaled matrix

4970:     Level: intermediate

4972:     Concepts: matrices^scaling all entries

4974: .seealso: MatDiagonalScale()
4975: @*/
4976: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4977: {

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

4989:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4990:   if (a != (PetscScalar)1.0) {
4991:     (*mat->ops->scale)(mat,a);
4992:     PetscObjectStateIncrease((PetscObject)mat);
4993:   }
4994:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4995: #if defined(PETSC_HAVE_CUSP)
4996:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4997:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4998:   }
4999: #elif defined(PETSC_HAVE_VIENNACL)
5000:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5001:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5002:   }
5003: #elif defined(PETSC_HAVE_VECCUDA)
5004:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5005:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5006:   }
5007: #endif
5008:   return(0);
5009: }

5013: /*@
5014:    MatNorm - Calculates various norms of a matrix.

5016:    Collective on Mat

5018:    Input Parameters:
5019: +  mat - the matrix
5020: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

5022:    Output Parameters:
5023: .  nrm - the resulting norm

5025:    Level: intermediate

5027:    Concepts: matrices^norm
5028:    Concepts: norm^of matrix
5029: @*/
5030: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5031: {


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

5044:   (*mat->ops->norm)(mat,type,nrm);
5045:   return(0);
5046: }

5048: /*
5049:      This variable is used to prevent counting of MatAssemblyBegin() that
5050:    are called from within a MatAssemblyEnd().
5051: */
5052: static PetscInt MatAssemblyEnd_InUse = 0;
5055: /*@
5056:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5057:    be called after completing all calls to MatSetValues().

5059:    Collective on Mat

5061:    Input Parameters:
5062: +  mat - the matrix
5063: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

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

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

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

5080:    Level: beginner

5082:    Concepts: matrices^assembling

5084: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5085: @*/
5086: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5087: {

5093:   MatCheckPreallocated(mat,1);
5094:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5095:   if (mat->assembled) {
5096:     mat->was_assembled = PETSC_TRUE;
5097:     mat->assembled     = PETSC_FALSE;
5098:   }
5099:   if (!MatAssemblyEnd_InUse) {
5100:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5101:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5102:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5103:   } else if (mat->ops->assemblybegin) {
5104:     (*mat->ops->assemblybegin)(mat,type);
5105:   }
5106:   return(0);
5107: }

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

5115:    Not Collective

5117:    Input Parameter:
5118: .  mat - the matrix

5120:    Output Parameter:
5121: .  assembled - PETSC_TRUE or PETSC_FALSE

5123:    Level: advanced

5125:    Concepts: matrices^assembled?

5127: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5128: @*/
5129: PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5130: {
5135:   *assembled = mat->assembled;
5136:   return(0);
5137: }

5141: /*@
5142:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5143:    be called after MatAssemblyBegin().

5145:    Collective on Mat

5147:    Input Parameters:
5148: +  mat - the matrix
5149: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5151:    Options Database Keys:
5152: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5153: .  -mat_view ::ascii_info_detail - Prints more detailed info
5154: .  -mat_view - Prints matrix in ASCII format
5155: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5156: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5157: .  -display <name> - Sets display name (default is host)
5158: .  -draw_pause <sec> - Sets number of seconds to pause after display
5159: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 11 Using MATLAB with PETSc )
5160: .  -viewer_socket_machine <machine> - Machine to use for socket
5161: .  -viewer_socket_port <port> - Port number to use for socket
5162: -  -mat_view binary:filename[:append] - Save matrix to file in binary format

5164:    Notes:
5165:    MatSetValues() generally caches the values.  The matrix is ready to
5166:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5167:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5168:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5169:    using the matrix.

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

5175:    Level: beginner

5177: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5178: @*/
5179: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5180: {
5181:   PetscErrorCode  ierr;
5182:   static PetscInt inassm = 0;
5183:   PetscBool       flg    = PETSC_FALSE;


5189:   inassm++;
5190:   MatAssemblyEnd_InUse++;
5191:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5192:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5193:     if (mat->ops->assemblyend) {
5194:       (*mat->ops->assemblyend)(mat,type);
5195:     }
5196:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5197:   } else if (mat->ops->assemblyend) {
5198:     (*mat->ops->assemblyend)(mat,type);
5199:   }

5201:   /* Flush assembly is not a true assembly */
5202:   if (type != MAT_FLUSH_ASSEMBLY) {
5203:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5204:   }
5205:   mat->insertmode = NOT_SET_VALUES;
5206:   MatAssemblyEnd_InUse--;
5207:   PetscObjectStateIncrease((PetscObject)mat);
5208:   if (!mat->symmetric_eternal) {
5209:     mat->symmetric_set              = PETSC_FALSE;
5210:     mat->hermitian_set              = PETSC_FALSE;
5211:     mat->structurally_symmetric_set = PETSC_FALSE;
5212:   }
5213: #if defined(PETSC_HAVE_CUSP)
5214:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5215:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5216:   }
5217: #elif defined(PETSC_HAVE_VIENNACL)
5218:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5219:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5220:   }
5221: #elif defined(PETSC_HAVE_VECCUDA)
5222:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5223:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5224:   }
5225: #endif
5226:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5227:     MatViewFromOptions(mat,NULL,"-mat_view");

5229:     if (mat->checksymmetryonassembly) {
5230:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5231:       if (flg) {
5232:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5233:       } else {
5234:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5235:       }
5236:     }
5237:     if (mat->nullsp && mat->checknullspaceonassembly) {
5238:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5239:     }
5240:   }
5241:   inassm--;
5242:   return(0);
5243: }

5247: /*@
5248:    MatSetOption - Sets a parameter option for a matrix. Some options
5249:    may be specific to certain storage formats.  Some options
5250:    determine how values will be inserted (or added). Sorted,
5251:    row-oriented input will generally assemble the fastest. The default
5252:    is row-oriented.

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

5256:    Input Parameters:
5257: +  mat - the matrix
5258: .  option - the option, one of those listed below (and possibly others),
5259: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5261:   Options Describing Matrix Structure:
5262: +    MAT_SPD - symmetric positive definite
5263: .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5264: .    MAT_HERMITIAN - transpose is the complex conjugation
5265: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5266: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5267:                             you set to be kept with all future use of the matrix
5268:                             including after MatAssemblyBegin/End() which could
5269:                             potentially change the symmetry structure, i.e. you
5270:                             KNOW the matrix will ALWAYS have the property you set.


5273:    Options For Use with MatSetValues():
5274:    Insert a logically dense subblock, which can be
5275: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

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

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

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

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

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

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

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

5329:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5330:    searches during matrix assembly. When this flag is set, the hash table
5331:    is created during the first Matrix Assembly. This hash table is
5332:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5333:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5334:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5335:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5353:    Level: intermediate

5355:    Concepts: matrices^setting options

5357: .seealso:  MatOption, Mat

5359: @*/
5360: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5361: {

5367:   if (op > 0) {
5370:   }

5372:   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);
5373:   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()");

5375:   switch (op) {
5376:   case MAT_NO_OFF_PROC_ENTRIES:
5377:     mat->nooffprocentries = flg;
5378:     return(0);
5379:     break;
5380:   case MAT_SUBSET_OFF_PROC_ENTRIES:
5381:     mat->subsetoffprocentries = flg;
5382:     return(0);
5383:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5384:     mat->nooffproczerorows = flg;
5385:     return(0);
5386:     break;
5387:   case MAT_SPD:
5388:     mat->spd_set = PETSC_TRUE;
5389:     mat->spd     = flg;
5390:     if (flg) {
5391:       mat->symmetric                  = PETSC_TRUE;
5392:       mat->structurally_symmetric     = PETSC_TRUE;
5393:       mat->symmetric_set              = PETSC_TRUE;
5394:       mat->structurally_symmetric_set = PETSC_TRUE;
5395:     }
5396:     break;
5397:   case MAT_SYMMETRIC:
5398:     mat->symmetric = flg;
5399:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5400:     mat->symmetric_set              = PETSC_TRUE;
5401:     mat->structurally_symmetric_set = flg;
5402:     break;
5403:   case MAT_HERMITIAN:
5404:     mat->hermitian = flg;
5405:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5406:     mat->hermitian_set              = PETSC_TRUE;
5407:     mat->structurally_symmetric_set = flg;
5408:     break;
5409:   case MAT_STRUCTURALLY_SYMMETRIC:
5410:     mat->structurally_symmetric     = flg;
5411:     mat->structurally_symmetric_set = PETSC_TRUE;
5412:     break;
5413:   case MAT_SYMMETRY_ETERNAL:
5414:     mat->symmetric_eternal = flg;
5415:     break;
5416:   default:
5417:     break;
5418:   }
5419:   if (mat->ops->setoption) {
5420:     (*mat->ops->setoption)(mat,op,flg);
5421:   }
5422:   return(0);
5423: }

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

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

5432:    Input Parameters:
5433: +  mat - the matrix
5434: -  option - the option, this only responds to certain options, check the code for which ones

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

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

5441:    Level: intermediate

5443:    Concepts: matrices^setting options

5445: .seealso:  MatOption, MatSetOption()

5447: @*/
5448: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5449: {

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

5457:   switch (op) {
5458:   case MAT_NO_OFF_PROC_ENTRIES:
5459:     *flg = mat->nooffprocentries;
5460:     break;
5461:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5462:     *flg = mat->nooffproczerorows;
5463:     break;
5464:   case MAT_SYMMETRIC:
5465:     *flg = mat->symmetric;
5466:     break;
5467:   case MAT_HERMITIAN:
5468:     *flg = mat->hermitian;
5469:     break;
5470:   case MAT_STRUCTURALLY_SYMMETRIC:
5471:     *flg = mat->structurally_symmetric;
5472:     break;
5473:   case MAT_SYMMETRY_ETERNAL:
5474:     *flg = mat->symmetric_eternal;
5475:     break;
5476:   default:
5477:     break;
5478:   }
5479:   return(0);
5480: }

5484: /*@
5485:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5486:    this routine retains the old nonzero structure.

5488:    Logically Collective on Mat

5490:    Input Parameters:
5491: .  mat - the matrix

5493:    Level: intermediate

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

5498:    Concepts: matrices^zeroing

5500: .seealso: MatZeroRows()
5501: @*/
5502: PetscErrorCode MatZeroEntries(Mat mat)
5503: {

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

5514:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5515:   (*mat->ops->zeroentries)(mat);
5516:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5517:   PetscObjectStateIncrease((PetscObject)mat);
5518: #if defined(PETSC_HAVE_CUSP)
5519:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5520:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5521:   }
5522: #elif defined(PETSC_HAVE_VIENNACL)
5523:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5524:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5525:   }
5526: #elif defined(PETSC_HAVE_VECCUDA)
5527:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5528:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5529:   }
5530: #endif
5531:   return(0);
5532: }

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

5540:    Collective on Mat

5542:    Input Parameters:
5543: +  mat - the matrix
5544: .  numRows - the number of rows to remove
5545: .  rows - the global row indices
5546: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5547: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5548: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5567:    Level: intermediate

5569:    Concepts: matrices^zeroing rows

5571: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5572: @*/
5573: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5574: {

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

5586:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5587:   MatViewFromOptions(mat,NULL,"-mat_view");
5588:   PetscObjectStateIncrease((PetscObject)mat);
5589: #if defined(PETSC_HAVE_CUSP)
5590:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5591:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5592:   }
5593: #elif defined(PETSC_HAVE_VIENNACL)
5594:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5595:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5596:   }
5597: #elif defined(PETSC_HAVE_VECCUDA)
5598:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5599:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5600:   }
5601: #endif
5602:   return(0);
5603: }

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

5611:    Collective on Mat

5613:    Input Parameters:
5614: +  mat - the matrix
5615: .  is - the rows to zero
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:    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.

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

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

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

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

5637:    Level: intermediate

5639:    Concepts: matrices^zeroing rows

5641: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5642: @*/
5643: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5644: {
5646:   PetscInt       numRows;
5647:   const PetscInt *rows;

5654:   ISGetLocalSize(is,&numRows);
5655:   ISGetIndices(is,&rows);
5656:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5657:   ISRestoreIndices(is,&rows);
5658:   return(0);
5659: }

5663: /*@C
5664:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5665:    of a set of rows of a matrix.

5667:    Collective on Mat

5669:    Input Parameters:
5670: +  mat - the matrix
5671: .  numRows - the number of rows to remove
5672: .  rows - the global row indices
5673: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5674: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5675: -  b - optional vector of right hand side, that will be adjusted by provided solution

5677:    Notes:
5678:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5679:    but does not release memory.  For the dense and block diagonal
5680:    formats this does not alter the nonzero structure.

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

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

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

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

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

5701:    Level: intermediate

5703:    Concepts: matrices^zeroing rows

5705: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5706: @*/
5707: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5708: {

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

5720:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5721:   MatViewFromOptions(mat,NULL,"-mat_view");
5722:   PetscObjectStateIncrease((PetscObject)mat);
5723: #if defined(PETSC_HAVE_CUSP)
5724:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5725:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5726:   }
5727: #elif defined(PETSC_HAVE_VIENNACL)
5728:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5729:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5730:   }
5731: #elif defined(PETSC_HAVE_VECCUDA)
5732:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5733:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5734:   }
5735: #endif
5736:   return(0);
5737: }

5741: /*@C
5742:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5743:    of a set of rows of a matrix.

5745:    Collective on Mat

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

5754:    Notes:
5755:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5756:    but does not release memory.  For the dense and block diagonal
5757:    formats this does not alter the nonzero structure.

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

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

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

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

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

5778:    Level: intermediate

5780:    Concepts: matrices^zeroing rows

5782: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5783: @*/
5784: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5785: {
5786:   PetscInt       numRows;
5787:   const PetscInt *rows;

5794:   ISGetLocalSize(is,&numRows);
5795:   ISGetIndices(is,&rows);
5796:   MatZeroRows(mat,numRows,rows,diag,x,b);
5797:   ISRestoreIndices(is,&rows);
5798:   return(0);
5799: }

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

5807:    Collective on Mat

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

5817:    Notes:
5818:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5819:    but does not release memory.  For the dense and block diagonal
5820:    formats this does not alter the nonzero structure.

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

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

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

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

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

5840:    In Fortran idxm and idxn should be declared as
5841: $     MatStencil idxm(4,m)
5842:    and the values inserted using
5843: $    idxm(MatStencil_i,1) = i
5844: $    idxm(MatStencil_j,1) = j
5845: $    idxm(MatStencil_k,1) = k
5846: $    idxm(MatStencil_c,1) = c
5847:    etc

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

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

5857:    Level: intermediate

5859:    Concepts: matrices^zeroing rows

5861: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5862: @*/
5863: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5864: {
5865:   PetscInt       dim     = mat->stencil.dim;
5866:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5867:   PetscInt       *dims   = mat->stencil.dims+1;
5868:   PetscInt       *starts = mat->stencil.starts;
5869:   PetscInt       *dxm    = (PetscInt*) rows;
5870:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5878:   PetscMalloc1(numRows, &jdxm);
5879:   for (i = 0; i < numRows; ++i) {
5880:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5881:     for (j = 0; j < 3-sdim; ++j) dxm++;
5882:     /* Local index in X dir */
5883:     tmp = *dxm++ - starts[0];
5884:     /* Loop over remaining dimensions */
5885:     for (j = 0; j < dim-1; ++j) {
5886:       /* If nonlocal, set index to be negative */
5887:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5888:       /* Update local index */
5889:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5890:     }
5891:     /* Skip component slot if necessary */
5892:     if (mat->stencil.noc) dxm++;
5893:     /* Local row number */
5894:     if (tmp >= 0) {
5895:       jdxm[numNewRows++] = tmp;
5896:     }
5897:   }
5898:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5899:   PetscFree(jdxm);
5900:   return(0);
5901: }

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

5909:    Collective on Mat

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

5919:    Notes:
5920:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5921:    but does not release memory.  For the dense and block diagonal
5922:    formats this does not alter the nonzero structure.

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

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

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

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

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

5942:    In Fortran idxm and idxn should be declared as
5943: $     MatStencil idxm(4,m)
5944:    and the values inserted using
5945: $    idxm(MatStencil_i,1) = i
5946: $    idxm(MatStencil_j,1) = j
5947: $    idxm(MatStencil_k,1) = k
5948: $    idxm(MatStencil_c,1) = c
5949:    etc

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

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

5959:    Level: intermediate

5961:    Concepts: matrices^zeroing rows

5963: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5964: @*/
5965: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5966: {
5967:   PetscInt       dim     = mat->stencil.dim;
5968:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5969:   PetscInt       *dims   = mat->stencil.dims+1;
5970:   PetscInt       *starts = mat->stencil.starts;
5971:   PetscInt       *dxm    = (PetscInt*) rows;
5972:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5980:   PetscMalloc1(numRows, &jdxm);
5981:   for (i = 0; i < numRows; ++i) {
5982:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5983:     for (j = 0; j < 3-sdim; ++j) dxm++;
5984:     /* Local index in X dir */
5985:     tmp = *dxm++ - starts[0];
5986:     /* Loop over remaining dimensions */
5987:     for (j = 0; j < dim-1; ++j) {
5988:       /* If nonlocal, set index to be negative */
5989:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5990:       /* Update local index */
5991:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5992:     }
5993:     /* Skip component slot if necessary */
5994:     if (mat->stencil.noc) dxm++;
5995:     /* Local row number */
5996:     if (tmp >= 0) {
5997:       jdxm[numNewRows++] = tmp;
5998:     }
5999:   }
6000:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
6001:   PetscFree(jdxm);
6002:   return(0);
6003: }

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

6011:    Collective on Mat

6013:    Input Parameters:
6014: +  mat - the matrix
6015: .  numRows - the number of rows to remove
6016: .  rows - the global row indices
6017: .  diag - value put in all diagonals of eliminated rows
6018: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6019: -  b - optional vector of right hand side, that will be adjusted by provided solution

6021:    Notes:
6022:    Before calling MatZeroRowsLocal(), the user must first set the
6023:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6025:    For the AIJ matrix formats this removes the old nonzero structure,
6026:    but does not release memory.  For the dense and block diagonal
6027:    formats this does not alter the nonzero structure.

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

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

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

6040:    Level: intermediate

6042:    Concepts: matrices^zeroing

6044: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6045: @*/
6046: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6047: {

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

6058:   if (mat->ops->zerorowslocal) {
6059:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6060:   } else {
6061:     IS             is, newis;
6062:     const PetscInt *newRows;

6064:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6065:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6066:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6067:     ISGetIndices(newis,&newRows);
6068:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6069:     ISRestoreIndices(newis,&newRows);
6070:     ISDestroy(&newis);
6071:     ISDestroy(&is);
6072:   }
6073:   PetscObjectStateIncrease((PetscObject)mat);
6074: #if defined(PETSC_HAVE_CUSP)
6075:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6076:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6077:   }
6078: #elif defined(PETSC_HAVE_VIENNACL)
6079:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6080:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6081:   }
6082: #elif defined(PETSC_HAVE_VECCUDA)
6083:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6084:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6085:   }
6086: #endif
6087:   return(0);
6088: }

6092: /*@C
6093:    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6094:    of a set of rows of a matrix; using local numbering of rows.

6096:    Collective on Mat

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

6105:    Notes:
6106:    Before calling MatZeroRowsLocalIS(), the user must first set the
6107:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6109:    For the AIJ matrix formats this removes the old nonzero structure,
6110:    but does not release memory.  For the dense and block diagonal
6111:    formats this does not alter the nonzero structure.

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

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

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

6124:    Level: intermediate

6126:    Concepts: matrices^zeroing

6128: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6129: @*/
6130: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6131: {
6133:   PetscInt       numRows;
6134:   const PetscInt *rows;

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

6144:   ISGetLocalSize(is,&numRows);
6145:   ISGetIndices(is,&rows);
6146:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6147:   ISRestoreIndices(is,&rows);
6148:   return(0);
6149: }

6153: /*@C
6154:    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6155:    of a set of rows and columns of a matrix; using local numbering of rows.

6157:    Collective on Mat

6159:    Input Parameters:
6160: +  mat - the matrix
6161: .  numRows - the number of rows to remove
6162: .  rows - the global row indices
6163: .  diag - value put in all diagonals of eliminated rows
6164: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6165: -  b - optional vector of right hand side, that will be adjusted by provided solution

6167:    Notes:
6168:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6169:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6175:    Level: intermediate

6177:    Concepts: matrices^zeroing

6179: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6180: @*/
6181: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6182: {
6184:   IS             is, newis;
6185:   const PetscInt *newRows;

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

6195:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6196:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6197:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6198:   ISGetIndices(newis,&newRows);
6199:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6200:   ISRestoreIndices(newis,&newRows);
6201:   ISDestroy(&newis);
6202:   ISDestroy(&is);
6203:   PetscObjectStateIncrease((PetscObject)mat);
6204: #if defined(PETSC_HAVE_CUSP)
6205:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6206:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6207:   }
6208: #elif defined(PETSC_HAVE_VIENNACL)
6209:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6210:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6211:   }
6212: #elif defined(PETSC_HAVE_VECCUDA)
6213:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6214:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6215:   }
6216: #endif
6217:   return(0);
6218: }

6222: /*@C
6223:    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6224:    of a set of rows and columns of a matrix; using local numbering of rows.

6226:    Collective on Mat

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

6235:    Notes:
6236:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6237:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6243:    Level: intermediate

6245:    Concepts: matrices^zeroing

6247: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6248: @*/
6249: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6250: {
6252:   PetscInt       numRows;
6253:   const PetscInt *rows;

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

6263:   ISGetLocalSize(is,&numRows);
6264:   ISGetIndices(is,&rows);
6265:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6266:   ISRestoreIndices(is,&rows);
6267:   return(0);
6268: }

6272: /*@
6273:    MatGetSize - Returns the numbers of rows and columns in a matrix.

6275:    Not Collective

6277:    Input Parameter:
6278: .  mat - the matrix

6280:    Output Parameters:
6281: +  m - the number of global rows
6282: -  n - the number of global columns

6284:    Note: both output parameters can be NULL on input.

6286:    Level: beginner

6288:    Concepts: matrices^size

6290: .seealso: MatGetLocalSize()
6291: @*/
6292: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6293: {
6296:   if (m) *m = mat->rmap->N;
6297:   if (n) *n = mat->cmap->N;
6298:   return(0);
6299: }

6303: /*@
6304:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6305:    stored locally.  This information may be implementation dependent, so
6306:    use with care.

6308:    Not Collective

6310:    Input Parameters:
6311: .  mat - the matrix

6313:    Output Parameters:
6314: +  m - the number of local rows
6315: -  n - the number of local columns

6317:    Note: both output parameters can be NULL on input.

6319:    Level: beginner

6321:    Concepts: matrices^local size

6323: .seealso: MatGetSize()
6324: @*/
6325: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6326: {
6331:   if (m) *m = mat->rmap->n;
6332:   if (n) *n = mat->cmap->n;
6333:   return(0);
6334: }

6338: /*@
6339:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6340:    this processor. (The columns of the "diagonal block")

6342:    Not Collective, unless matrix has not been allocated, then collective on Mat

6344:    Input Parameters:
6345: .  mat - the matrix

6347:    Output Parameters:
6348: +  m - the global index of the first local column
6349: -  n - one more than the global index of the last local column

6351:    Notes: both output parameters can be NULL on input.

6353:    Level: developer

6355:    Concepts: matrices^column ownership

6357: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

6359: @*/
6360: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6361: {
6367:   MatCheckPreallocated(mat,1);
6368:   if (m) *m = mat->cmap->rstart;
6369:   if (n) *n = mat->cmap->rend;
6370:   return(0);
6371: }

6375: /*@
6376:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6377:    this processor, assuming that the matrix is laid out with the first
6378:    n1 rows on the first processor, the next n2 rows on the second, etc.
6379:    For certain parallel layouts this range may not be well defined.

6381:    Not Collective

6383:    Input Parameters:
6384: .  mat - the matrix

6386:    Output Parameters:
6387: +  m - the global index of the first local row
6388: -  n - one more than the global index of the last local row

6390:    Note: Both output parameters can be NULL on input.
6391: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6392: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6393: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

6395:    Level: beginner

6397:    Concepts: matrices^row ownership

6399: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

6401: @*/
6402: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6403: {
6409:   MatCheckPreallocated(mat,1);
6410:   if (m) *m = mat->rmap->rstart;
6411:   if (n) *n = mat->rmap->rend;
6412:   return(0);
6413: }

6417: /*@C
6418:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6419:    each process

6421:    Not Collective, unless matrix has not been allocated, then collective on Mat

6423:    Input Parameters:
6424: .  mat - the matrix

6426:    Output Parameters:
6427: .  ranges - start of each processors portion plus one more than the total length at the end

6429:    Level: beginner

6431:    Concepts: matrices^row ownership

6433: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6435: @*/
6436: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6437: {

6443:   MatCheckPreallocated(mat,1);
6444:   PetscLayoutGetRanges(mat->rmap,ranges);
6445:   return(0);
6446: }

6450: /*@C
6451:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6452:    this processor. (The columns of the "diagonal blocks" for each process)

6454:    Not Collective, unless matrix has not been allocated, then collective on Mat

6456:    Input Parameters:
6457: .  mat - the matrix

6459:    Output Parameters:
6460: .  ranges - start of each processors portion plus one more then the total length at the end

6462:    Level: beginner

6464:    Concepts: matrices^column ownership

6466: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6468: @*/
6469: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6470: {

6476:   MatCheckPreallocated(mat,1);
6477:   PetscLayoutGetRanges(mat->cmap,ranges);
6478:   return(0);
6479: }

6483: /*@C
6484:    MatGetOwnershipIS - Get row and column ownership as index sets

6486:    Not Collective

6488:    Input Arguments:
6489: .  A - matrix of type Elemental

6491:    Output Arguments:
6492: +  rows - rows in which this process owns elements
6493: .  cols - columns in which this process owns elements

6495:    Level: intermediate

6497: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6498: @*/
6499: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6500: {
6501:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6504:   MatCheckPreallocated(A,1);
6505:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6506:   if (f) {
6507:     (*f)(A,rows,cols);
6508:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6509:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6510:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6511:   }
6512:   return(0);
6513: }

6517: /*@C
6518:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6519:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6520:    to complete the factorization.

6522:    Collective on Mat

6524:    Input Parameters:
6525: +  mat - the matrix
6526: .  row - row permutation
6527: .  column - column permutation
6528: -  info - structure containing
6529: $      levels - number of levels of fill.
6530: $      expected fill - as ratio of original fill.
6531: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6532:                 missing diagonal entries)

6534:    Output Parameters:
6535: .  fact - new matrix that has been symbolically factored

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

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

6543:    Level: developer

6545:   Concepts: matrices^symbolic LU factorization
6546:   Concepts: matrices^factorization
6547:   Concepts: LU^symbolic factorization

6549: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6550:           MatGetOrdering(), MatFactorInfo

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

6555: @*/
6556: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6557: {

6567:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6568:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6569:   if (!(fact)->ops->ilufactorsymbolic) {
6570:     const MatSolverPackage spackage;
6571:     MatFactorGetSolverPackage(fact,&spackage);
6572:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6573:   }
6574:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6575:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6576:   MatCheckPreallocated(mat,2);

6578:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6579:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6580:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6581:   return(0);
6582: }

6586: /*@C
6587:    MatICCFactorSymbolic - Performs symbolic incomplete
6588:    Cholesky factorization for a symmetric matrix.  Use
6589:    MatCholeskyFactorNumeric() to complete the factorization.

6591:    Collective on Mat

6593:    Input Parameters:
6594: +  mat - the matrix
6595: .  perm - row and column permutation
6596: -  info - structure containing
6597: $      levels - number of levels of fill.
6598: $      expected fill - as ratio of original fill.

6600:    Output Parameter:
6601: .  fact - the factored matrix

6603:    Notes:
6604:    Most users should employ the KSP interface for linear solvers
6605:    instead of working directly with matrix algebra routines such as this.
6606:    See, e.g., KSPCreate().

6608:    Level: developer

6610:   Concepts: matrices^symbolic incomplete Cholesky factorization
6611:   Concepts: matrices^factorization
6612:   Concepts: Cholsky^symbolic factorization

6614: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

6619: @*/
6620: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6621: {

6630:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6631:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6632:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6633:   if (!(fact)->ops->iccfactorsymbolic) {
6634:     const MatSolverPackage spackage;
6635:     MatFactorGetSolverPackage(fact,&spackage);
6636:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6637:   }
6638:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6639:   MatCheckPreallocated(mat,2);

6641:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6642:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6643:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6644:   return(0);
6645: }

6649: /*@C
6650:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6651:    points to an array of valid matrices, they may be reused to store the new
6652:    submatrices.

6654:    Collective on Mat

6656:    Input Parameters:
6657: +  mat - the matrix
6658: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6659: .  irow, icol - index sets of rows and columns to extract
6660: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6662:    Output Parameter:
6663: .  submat - the array of submatrices

6665:    Notes:
6666:    MatGetSubMatrices() can extract ONLY sequential submatrices
6667:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6668:    to extract a parallel submatrix.

6670:    Some matrix types place restrictions on the row and column
6671:    indices, such as that they be sorted or that they be equal to each other.

6673:    The index sets may not have duplicate entries.

6675:    When extracting submatrices from a parallel matrix, each processor can
6676:    form a different submatrix by setting the rows and columns of its
6677:    individual index sets according to the local submatrix desired.

6679:    When finished using the submatrices, the user should destroy
6680:    them with MatDestroyMatrices().

6682:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6683:    original matrix has not changed from that last call to MatGetSubMatrices().

6685:    This routine creates the matrices in submat; you should NOT create them before
6686:    calling it. It also allocates the array of matrix pointers submat.

6688:    For BAIJ matrices the index sets must respect the block structure, that is if they
6689:    request one row/column in a block, they must request all rows/columns that are in
6690:    that block. For example, if the block size is 2 you cannot request just row 0 and
6691:    column 0.

6693:    Fortran Note:
6694:    The Fortran interface is slightly different from that given below; it
6695:    requires one to pass in  as submat a Mat (integer) array of size at least m.

6697:    Level: advanced

6699:    Concepts: matrices^accessing submatrices
6700:    Concepts: submatrices

6702: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6703: @*/
6704: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6705: {
6707:   PetscInt       i;
6708:   PetscBool      eq;

6713:   if (n) {
6718:   }
6720:   if (n && scall == MAT_REUSE_MATRIX) {
6723:   }
6724:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6725:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6726:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6727:   MatCheckPreallocated(mat,1);

6729:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6730:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6731:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6732:   for (i=0; i<n; i++) {
6733:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6734:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6735:       ISEqual(irow[i],icol[i],&eq);
6736:       if (eq) {
6737:         if (mat->symmetric) {
6738:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6739:         } else if (mat->hermitian) {
6740:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6741:         } else if (mat->structurally_symmetric) {
6742:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6743:         }
6744:       }
6745:     }
6746:   }
6747:   return(0);
6748: }

6752: PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6753: {
6755:   PetscInt       i;
6756:   PetscBool      eq;

6761:   if (n) {
6766:   }
6768:   if (n && scall == MAT_REUSE_MATRIX) {
6771:   }
6772:   if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6773:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6774:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6775:   MatCheckPreallocated(mat,1);

6777:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6778:   (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6779:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6780:   for (i=0; i<n; i++) {
6781:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6782:       ISEqual(irow[i],icol[i],&eq);
6783:       if (eq) {
6784:         if (mat->symmetric) {
6785:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6786:         } else if (mat->hermitian) {
6787:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6788:         } else if (mat->structurally_symmetric) {
6789:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6790:         }
6791:       }
6792:     }
6793:   }
6794:   return(0);
6795: }

6799: /*@C
6800:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().

6802:    Collective on Mat

6804:    Input Parameters:
6805: +  n - the number of local matrices
6806: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6807:                        sequence of MatGetSubMatrices())

6809:    Level: advanced

6811:     Notes: Frees not only the matrices, but also the array that contains the matrices
6812:            In Fortran will not free the array.

6814: .seealso: MatGetSubMatrices()
6815: @*/
6816: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6817: {
6819:   PetscInt       i;

6822:   if (!*mat) return(0);
6823:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6825:   for (i=0; i<n; i++) {
6826:     MatDestroy(&(*mat)[i]);
6827:   }
6828:   /* memory is allocated even if n = 0 */
6829:   PetscFree(*mat);
6830:   *mat = NULL;
6831:   return(0);
6832: }

6836: /*@C
6837:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.

6839:    Collective on Mat

6841:    Input Parameters:
6842: .  mat - the matrix

6844:    Output Parameter:
6845: .  matstruct - the sequential matrix with the nonzero structure of mat

6847:   Level: intermediate

6849: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6850: @*/
6851: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6852: {


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

6863:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6864:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6865:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6866:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6867:   return(0);
6868: }

6872: /*@C
6873:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6875:    Collective on Mat

6877:    Input Parameters:
6878: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6879:                        sequence of MatGetSequentialNonzeroStructure())

6881:    Level: advanced

6883:     Notes: Frees not only the matrices, but also the array that contains the matrices

6885: .seealso: MatGetSeqNonzeroStructure()
6886: @*/
6887: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6888: {

6893:   MatDestroy(mat);
6894:   return(0);
6895: }

6899: /*@
6900:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6901:    replaces the index sets by larger ones that represent submatrices with
6902:    additional overlap.

6904:    Collective on Mat

6906:    Input Parameters:
6907: +  mat - the matrix
6908: .  n   - the number of index sets
6909: .  is  - the array of index sets (these index sets will changed during the call)
6910: -  ov  - the additional overlap requested

6912:    Options Database:
6913: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

6915:    Level: developer

6917:    Concepts: overlap
6918:    Concepts: ASM^computing overlap

6920: .seealso: MatGetSubMatrices()
6921: @*/
6922: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6923: {

6929:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6930:   if (n) {
6933:   }
6934:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6935:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6936:   MatCheckPreallocated(mat,1);

6938:   if (!ov) return(0);
6939:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6940:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6941:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6942:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6943:   return(0);
6944: }


6947: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);

6951: /*@
6952:    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6953:    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6954:    additional overlap.

6956:    Collective on Mat

6958:    Input Parameters:
6959: +  mat - the matrix
6960: .  n   - the number of index sets
6961: .  is  - the array of index sets (these index sets will changed during the call)
6962: -  ov  - the additional overlap requested

6964:    Options Database:
6965: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

6967:    Level: developer

6969:    Concepts: overlap
6970:    Concepts: ASM^computing overlap

6972: .seealso: MatGetSubMatrices()
6973: @*/
6974: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6975: {
6976:   PetscInt       i;

6982:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6983:   if (n) {
6986:   }
6987:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6988:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6989:   MatCheckPreallocated(mat,1);
6990:   if (!ov) return(0);
6991:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6992:   for(i=0; i<n; i++){
6993:          MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
6994:   }
6995:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6996:   return(0);
6997: }




7004: /*@
7005:    MatGetBlockSize - Returns the matrix block size.

7007:    Not Collective

7009:    Input Parameter:
7010: .  mat - the matrix

7012:    Output Parameter:
7013: .  bs - block size

7015:    Notes:
7016:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

7018:    If the block size has not been set yet this routine returns 1.

7020:    Level: intermediate

7022:    Concepts: matrices^block size

7024: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7025: @*/
7026: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7027: {
7031:   *bs = PetscAbs(mat->rmap->bs);
7032:   return(0);
7033: }

7037: /*@
7038:    MatGetBlockSizes - Returns the matrix block row and column sizes.

7040:    Not Collective

7042:    Input Parameter:
7043: .  mat - the matrix

7045:    Output Parameter:
7046: .  rbs - row block size
7047: .  cbs - coumn block size

7049:    Notes:
7050:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7051:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

7053:    If a block size has not been set yet this routine returns 1.

7055:    Level: intermediate

7057:    Concepts: matrices^block size

7059: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7060: @*/
7061: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7062: {
7067:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7068:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7069:   return(0);
7070: }

7074: /*@
7075:    MatSetBlockSize - Sets the matrix block size.

7077:    Logically Collective on Mat

7079:    Input Parameters:
7080: +  mat - the matrix
7081: -  bs - block size

7083:    Notes:
7084:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

7086:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

7088:    Level: intermediate

7090:    Concepts: matrices^block size

7092: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7093: @*/
7094: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7095: {

7101:   PetscLayoutSetBlockSize(mat->rmap,bs);
7102:   PetscLayoutSetBlockSize(mat->cmap,bs);
7103:   return(0);
7104: }

7108: /*@
7109:    MatSetBlockSizes - Sets the matrix block row and column sizes.

7111:    Logically Collective on Mat

7113:    Input Parameters:
7114: +  mat - the matrix
7115: -  rbs - row block size
7116: -  cbs - column block size

7118:    Notes:
7119:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7120:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

7122:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

7124:     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().

7126:    Level: intermediate

7128:    Concepts: matrices^block size

7130: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7131: @*/
7132: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7133: {

7140:   PetscLayoutSetBlockSize(mat->rmap,rbs);
7141:   PetscLayoutSetBlockSize(mat->cmap,cbs);
7142:   return(0);
7143: }

7147: /*@
7148:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

7150:    Logically Collective on Mat

7152:    Input Parameters:
7153: +  mat - the matrix
7154: .  fromRow - matrix from which to copy row block size
7155: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

7157:    Level: developer

7159:    Concepts: matrices^block size

7161: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7162: @*/
7163: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7164: {

7171:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7172:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7173:   return(0);
7174: }

7178: /*@
7179:    MatResidual - Default routine to calculate the residual.

7181:    Collective on Mat and Vec

7183:    Input Parameters:
7184: +  mat - the matrix
7185: .  b   - the right-hand-side
7186: -  x   - the approximate solution

7188:    Output Parameter:
7189: .  r - location to store the residual

7191:    Level: developer

7193: .keywords: MG, default, multigrid, residual

7195: .seealso: PCMGSetResidual()
7196: @*/
7197: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7198: {

7207:   MatCheckPreallocated(mat,1);
7208:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7209:   if (!mat->ops->residual) {
7210:     MatMult(mat,x,r);
7211:     VecAYPX(r,-1.0,b);
7212:   } else {
7213:     (*mat->ops->residual)(mat,b,x,r);
7214:   }
7215:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7216:   return(0);
7217: }

7221: /*@C
7222:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.

7224:    Collective on Mat

7226:     Input Parameters:
7227: +   mat - the matrix
7228: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7229: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7230: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7231:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7232:                  always used.

7234:     Output Parameters:
7235: +   n - number of rows in the (possibly compressed) matrix
7236: .   ia - the row pointers [of length n+1]
7237: .   ja - the column indices
7238: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7239:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

7241:     Level: developer

7243:     Notes: You CANNOT change any of the ia[] or ja[] values.

7245:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

7247:     Fortran Node

7249:            In Fortran use
7250: $           PetscInt ia(1), ja(1)
7251: $           PetscOffset iia, jja
7252: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7253: $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7254: $
7255: $          or
7256: $
7257: $           PetscInt, pointer :: ia(:),ja(:)
7258: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7259: $      Acess the ith and jth entries via ia(i) and ja(j)



7263: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7264: @*/
7265: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7266: {

7276:   MatCheckPreallocated(mat,1);
7277:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7278:   else {
7279:     *done = PETSC_TRUE;
7280:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7281:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7282:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7283:   }
7284:   return(0);
7285: }

7289: /*@C
7290:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.

7292:     Collective on Mat

7294:     Input Parameters:
7295: +   mat - the matrix
7296: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7297: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7298:                 symmetrized
7299: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7300:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7301:                  always used.
7302: .   n - number of columns in the (possibly compressed) matrix
7303: .   ia - the column pointers
7304: -   ja - the row indices

7306:     Output Parameters:
7307: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

7309:     Note:
7310:     This routine zeros out n, ia, and ja. This is to prevent accidental
7311:     us of the array after it has been restored. If you pass NULL, it will
7312:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

7314:     Level: developer

7316: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7317: @*/
7318: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7319: {

7329:   MatCheckPreallocated(mat,1);
7330:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7331:   else {
7332:     *done = PETSC_TRUE;
7333:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7334:   }
7335:   return(0);
7336: }

7340: /*@C
7341:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7342:     MatGetRowIJ().

7344:     Collective on Mat

7346:     Input Parameters:
7347: +   mat - the matrix
7348: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7349: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7350:                 symmetrized
7351: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7352:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7353:                  always used.
7354: .   n - size of (possibly compressed) matrix
7355: .   ia - the row pointers
7356: -   ja - the column indices

7358:     Output Parameters:
7359: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7361:     Note:
7362:     This routine zeros out n, ia, and ja. This is to prevent accidental
7363:     us of the array after it has been restored. If you pass NULL, it will
7364:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

7366:     Level: developer

7368: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7369: @*/
7370: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7371: {

7380:   MatCheckPreallocated(mat,1);

7382:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7383:   else {
7384:     *done = PETSC_TRUE;
7385:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7386:     if (n)  *n = 0;
7387:     if (ia) *ia = NULL;
7388:     if (ja) *ja = NULL;
7389:   }
7390:   return(0);
7391: }

7395: /*@C
7396:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7397:     MatGetColumnIJ().

7399:     Collective on Mat

7401:     Input Parameters:
7402: +   mat - the matrix
7403: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7404: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7405:                 symmetrized
7406: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7407:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7408:                  always used.

7410:     Output Parameters:
7411: +   n - size of (possibly compressed) matrix
7412: .   ia - the column pointers
7413: .   ja - the row indices
7414: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7416:     Level: developer

7418: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7419: @*/
7420: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7421: {

7430:   MatCheckPreallocated(mat,1);

7432:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7433:   else {
7434:     *done = PETSC_TRUE;
7435:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7436:     if (n)  *n = 0;
7437:     if (ia) *ia = NULL;
7438:     if (ja) *ja = NULL;
7439:   }
7440:   return(0);
7441: }

7445: /*@C
7446:     MatColoringPatch -Used inside matrix coloring routines that
7447:     use MatGetRowIJ() and/or MatGetColumnIJ().

7449:     Collective on Mat

7451:     Input Parameters:
7452: +   mat - the matrix
7453: .   ncolors - max color value
7454: .   n   - number of entries in colorarray
7455: -   colorarray - array indicating color for each column

7457:     Output Parameters:
7458: .   iscoloring - coloring generated using colorarray information

7460:     Level: developer

7462: .seealso: MatGetRowIJ(), MatGetColumnIJ()

7464: @*/
7465: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7466: {

7474:   MatCheckPreallocated(mat,1);

7476:   if (!mat->ops->coloringpatch) {
7477:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7478:   } else {
7479:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7480:   }
7481:   return(0);
7482: }


7487: /*@
7488:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.

7490:    Logically Collective on Mat

7492:    Input Parameter:
7493: .  mat - the factored matrix to be reset

7495:    Notes:
7496:    This routine should be used only with factored matrices formed by in-place
7497:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7498:    format).  This option can save memory, for example, when solving nonlinear
7499:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7500:    ILU(0) preconditioner.

7502:    Note that one can specify in-place ILU(0) factorization by calling
7503: .vb
7504:      PCType(pc,PCILU);
7505:      PCFactorSeUseInPlace(pc);
7506: .ve
7507:    or by using the options -pc_type ilu -pc_factor_in_place

7509:    In-place factorization ILU(0) can also be used as a local
7510:    solver for the blocks within the block Jacobi or additive Schwarz
7511:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7512:    for details on setting local solver options.

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

7518:    Level: developer

7520: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()

7522:    Concepts: matrices^unfactored

7524: @*/
7525: PetscErrorCode MatSetUnfactored(Mat mat)
7526: {

7532:   MatCheckPreallocated(mat,1);
7533:   mat->factortype = MAT_FACTOR_NONE;
7534:   if (!mat->ops->setunfactored) return(0);
7535:   (*mat->ops->setunfactored)(mat);
7536:   return(0);
7537: }

7539: /*MC
7540:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7542:     Synopsis:
7543:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7545:     Not collective

7547:     Input Parameter:
7548: .   x - matrix

7550:     Output Parameters:
7551: +   xx_v - the Fortran90 pointer to the array
7552: -   ierr - error code

7554:     Example of Usage:
7555: .vb
7556:       PetscScalar, pointer xx_v(:,:)
7557:       ....
7558:       call MatDenseGetArrayF90(x,xx_v,ierr)
7559:       a = xx_v(3)
7560:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7561: .ve

7563:     Level: advanced

7565: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()

7567:     Concepts: matrices^accessing array

7569: M*/

7571: /*MC
7572:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7573:     accessed with MatDenseGetArrayF90().

7575:     Synopsis:
7576:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7578:     Not collective

7580:     Input Parameters:
7581: +   x - matrix
7582: -   xx_v - the Fortran90 pointer to the array

7584:     Output Parameter:
7585: .   ierr - error code

7587:     Example of Usage:
7588: .vb
7589:        PetscScalar, pointer xx_v(:,:)
7590:        ....
7591:        call MatDenseGetArrayF90(x,xx_v,ierr)
7592:        a = xx_v(3)
7593:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7594: .ve

7596:     Level: advanced

7598: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()

7600: M*/


7603: /*MC
7604:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7606:     Synopsis:
7607:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7609:     Not collective

7611:     Input Parameter:
7612: .   x - matrix

7614:     Output Parameters:
7615: +   xx_v - the Fortran90 pointer to the array
7616: -   ierr - error code

7618:     Example of Usage:
7619: .vb
7620:       PetscScalar, pointer xx_v(:)
7621:       ....
7622:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7623:       a = xx_v(3)
7624:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7625: .ve

7627:     Level: advanced

7629: .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()

7631:     Concepts: matrices^accessing array

7633: M*/

7635: /*MC
7636:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7637:     accessed with MatSeqAIJGetArrayF90().

7639:     Synopsis:
7640:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7642:     Not collective

7644:     Input Parameters:
7645: +   x - matrix
7646: -   xx_v - the Fortran90 pointer to the array

7648:     Output Parameter:
7649: .   ierr - error code

7651:     Example of Usage:
7652: .vb
7653:        PetscScalar, pointer xx_v(:)
7654:        ....
7655:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7656:        a = xx_v(3)
7657:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7658: .ve

7660:     Level: advanced

7662: .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()

7664: M*/


7669: /*@
7670:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7671:                       as the original matrix.

7673:     Collective on Mat

7675:     Input Parameters:
7676: +   mat - the original matrix
7677: .   isrow - parallel IS containing the rows this processor should obtain
7678: .   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.
7679: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7681:     Output Parameter:
7682: .   newmat - the new submatrix, of the same type as the old

7684:     Level: advanced

7686:     Notes:
7687:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7689:     Some matrix types place restrictions on the row and column indices, such
7690:     as that they be sorted or that they be equal to each other.

7692:     The index sets may not have duplicate entries.

7694:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7695:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7696:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7697:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7698:    you are finished using it.

7700:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7701:     the input matrix.

7703:     If iscol is NULL then all columns are obtained (not supported in Fortran).

7705:    Example usage:
7706:    Consider the following 8x8 matrix with 34 non-zero values, that is
7707:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7708:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7709:    as follows:

7711: .vb
7712:             1  2  0  |  0  3  0  |  0  4
7713:     Proc0   0  5  6  |  7  0  0  |  8  0
7714:             9  0 10  | 11  0  0  | 12  0
7715:     -------------------------------------
7716:            13  0 14  | 15 16 17  |  0  0
7717:     Proc1   0 18  0  | 19 20 21  |  0  0
7718:             0  0  0  | 22 23  0  | 24  0
7719:     -------------------------------------
7720:     Proc2  25 26 27  |  0  0 28  | 29  0
7721:            30  0  0  | 31 32 33  |  0 34
7722: .ve

7724:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7726: .vb
7727:             2  0  |  0  3  0  |  0
7728:     Proc0   5  6  |  7  0  0  |  8
7729:     -------------------------------
7730:     Proc1  18  0  | 19 20 21  |  0
7731:     -------------------------------
7732:     Proc2  26 27  |  0  0 28  | 29
7733:             0  0  | 31 32 33  |  0
7734: .ve


7737:     Concepts: matrices^submatrices

7739: .seealso: MatGetSubMatrices()
7740: @*/
7741: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7742: {
7744:   PetscMPIInt    size;
7745:   Mat            *local;
7746:   IS             iscoltmp;

7755:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7756:   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");

7758:   MatCheckPreallocated(mat,1);
7759:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7761:   if (!iscol || isrow == iscol) {
7762:     PetscBool   stride;
7763:     PetscMPIInt grabentirematrix = 0,grab;
7764:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7765:     if (stride) {
7766:       PetscInt first,step,n,rstart,rend;
7767:       ISStrideGetInfo(isrow,&first,&step);
7768:       if (step == 1) {
7769:         MatGetOwnershipRange(mat,&rstart,&rend);
7770:         if (rstart == first) {
7771:           ISGetLocalSize(isrow,&n);
7772:           if (n == rend-rstart) {
7773:             grabentirematrix = 1;
7774:           }
7775:         }
7776:       }
7777:     }
7778:     MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7779:     if (grab) {
7780:       PetscInfo(mat,"Getting entire matrix as submatrix\n");
7781:       if (cll == MAT_INITIAL_MATRIX) {
7782:         *newmat = mat;
7783:         PetscObjectReference((PetscObject)mat);
7784:       }
7785:       return(0);
7786:     }
7787:   }

7789:   if (!iscol) {
7790:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7791:   } else {
7792:     iscoltmp = iscol;
7793:   }

7795:   /* if original matrix is on just one processor then use submatrix generated */
7796:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7797:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7798:     if (!iscol) {ISDestroy(&iscoltmp);}
7799:     return(0);
7800:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7801:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7802:     *newmat = *local;
7803:     PetscFree(local);
7804:     if (!iscol) {ISDestroy(&iscoltmp);}
7805:     return(0);
7806:   } else if (!mat->ops->getsubmatrix) {
7807:     /* Create a new matrix type that implements the operation using the full matrix */
7808:     PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7809:     switch (cll) {
7810:     case MAT_INITIAL_MATRIX:
7811:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7812:       break;
7813:     case MAT_REUSE_MATRIX:
7814:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7815:       break;
7816:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7817:     }
7818:     PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7819:     if (!iscol) {ISDestroy(&iscoltmp);}
7820:     return(0);
7821:   }

7823:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7824:   PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7825:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7826:   PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7827:   if (!iscol) {ISDestroy(&iscoltmp);}
7828:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7829:   return(0);
7830: }

7834: /*@
7835:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7836:    used during the assembly process to store values that belong to
7837:    other processors.

7839:    Not Collective

7841:    Input Parameters:
7842: +  mat   - the matrix
7843: .  size  - the initial size of the stash.
7844: -  bsize - the initial size of the block-stash(if used).

7846:    Options Database Keys:
7847: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7848: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7850:    Level: intermediate

7852:    Notes:
7853:      The block-stash is used for values set with MatSetValuesBlocked() while
7854:      the stash is used for values set with MatSetValues()

7856:      Run with the option -info and look for output of the form
7857:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7858:      to determine the appropriate value, MM, to use for size and
7859:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7860:      to determine the value, BMM to use for bsize

7862:    Concepts: stash^setting matrix size
7863:    Concepts: matrices^stash

7865: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7867: @*/
7868: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7869: {

7875:   MatStashSetInitialSize_Private(&mat->stash,size);
7876:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7877:   return(0);
7878: }

7882: /*@
7883:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7884:      the matrix

7886:    Neighbor-wise Collective on Mat

7888:    Input Parameters:
7889: +  mat   - the matrix
7890: .  x,y - the vectors
7891: -  w - where the result is stored

7893:    Level: intermediate

7895:    Notes:
7896:     w may be the same vector as y.

7898:     This allows one to use either the restriction or interpolation (its transpose)
7899:     matrix to do the interpolation

7901:     Concepts: interpolation

7903: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7905: @*/
7906: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7907: {
7909:   PetscInt       M,N,Ny;

7917:   MatCheckPreallocated(A,1);
7918:   MatGetSize(A,&M,&N);
7919:   VecGetSize(y,&Ny);
7920:   if (M == Ny) {
7921:     MatMultAdd(A,x,y,w);
7922:   } else {
7923:     MatMultTransposeAdd(A,x,y,w);
7924:   }
7925:   return(0);
7926: }

7930: /*@
7931:    MatInterpolate - y = A*x or A'*x depending on the shape of
7932:      the matrix

7934:    Neighbor-wise Collective on Mat

7936:    Input Parameters:
7937: +  mat   - the matrix
7938: -  x,y - the vectors

7940:    Level: intermediate

7942:    Notes:
7943:     This allows one to use either the restriction or interpolation (its transpose)
7944:     matrix to do the interpolation

7946:    Concepts: matrices^interpolation

7948: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7950: @*/
7951: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7952: {
7954:   PetscInt       M,N,Ny;

7961:   MatCheckPreallocated(A,1);
7962:   MatGetSize(A,&M,&N);
7963:   VecGetSize(y,&Ny);
7964:   if (M == Ny) {
7965:     MatMult(A,x,y);
7966:   } else {
7967:     MatMultTranspose(A,x,y);
7968:   }
7969:   return(0);
7970: }

7974: /*@
7975:    MatRestrict - y = A*x or A'*x

7977:    Neighbor-wise Collective on Mat

7979:    Input Parameters:
7980: +  mat   - the matrix
7981: -  x,y - the vectors

7983:    Level: intermediate

7985:    Notes:
7986:     This allows one to use either the restriction or interpolation (its transpose)
7987:     matrix to do the restriction

7989:    Concepts: matrices^restriction

7991: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()

7993: @*/
7994: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7995: {
7997:   PetscInt       M,N,Ny;

8004:   MatCheckPreallocated(A,1);

8006:   MatGetSize(A,&M,&N);
8007:   VecGetSize(y,&Ny);
8008:   if (M == Ny) {
8009:     MatMult(A,x,y);
8010:   } else {
8011:     MatMultTranspose(A,x,y);
8012:   }
8013:   return(0);
8014: }

8018: /*@
8019:    MatGetNullSpace - retrieves the null space to a matrix.

8021:    Logically Collective on Mat and MatNullSpace

8023:    Input Parameters:
8024: +  mat - the matrix
8025: -  nullsp - the null space object

8027:    Level: developer

8029:    Concepts: null space^attaching to matrix

8031: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8032: @*/
8033: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8034: {
8039:   *nullsp = mat->nullsp;
8040:   return(0);
8041: }

8045: /*@
8046:    MatSetNullSpace - attaches a null space to a matrix.

8048:    Logically Collective on Mat and MatNullSpace

8050:    Input Parameters:
8051: +  mat - the matrix
8052: -  nullsp - the null space object

8054:    Level: advanced

8056:    Notes:
8057:       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached

8059:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8060:       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.

8062:       You can remove the null space by calling this routine with an nullsp of NULL


8065:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8066:    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8067:    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8068:    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8069:    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).

8071:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

8073:    Concepts: null space^attaching to matrix

8075: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8076: @*/
8077: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8078: {

8085:   MatCheckPreallocated(mat,1);
8086:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8087:   MatNullSpaceDestroy(&mat->nullsp);
8088:   mat->nullsp = nullsp;
8089:   return(0);
8090: }

8094: /*@
8095:    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.

8097:    Logically Collective on Mat and MatNullSpace

8099:    Input Parameters:
8100: +  mat - the matrix
8101: -  nullsp - the null space object

8103:    Level: developer

8105:    Concepts: null space^attaching to matrix

8107: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8108: @*/
8109: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8110: {
8115:   *nullsp = mat->transnullsp;
8116:   return(0);
8117: }

8121: /*@
8122:    MatSetTransposeNullSpace - attaches a null space to a matrix.

8124:    Logically Collective on Mat and MatNullSpace

8126:    Input Parameters:
8127: +  mat - the matrix
8128: -  nullsp - the null space object

8130:    Level: advanced

8132:    Notes:
8133:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) this allows the linear system to be solved in a least squares sense.
8134:       You must also call MatSetNullSpace()


8137:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8138:    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8139:    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8140:    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8141:    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).

8143:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

8145:    Concepts: null space^attaching to matrix

8147: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8148: @*/
8149: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8150: {

8157:   MatCheckPreallocated(mat,1);
8158:   PetscObjectReference((PetscObject)nullsp);
8159:   MatNullSpaceDestroy(&mat->transnullsp);
8160:   mat->transnullsp = nullsp;
8161:   return(0);
8162: }

8166: /*@
8167:    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8168:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

8170:    Logically Collective on Mat and MatNullSpace

8172:    Input Parameters:
8173: +  mat - the matrix
8174: -  nullsp - the null space object

8176:    Level: advanced

8178:    Notes:
8179:       Overwrites any previous near null space that may have been attached

8181:       You can remove the null space by calling this routine with an nullsp of NULL

8183:    Concepts: null space^attaching to matrix

8185: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8186: @*/
8187: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8188: {

8195:   MatCheckPreallocated(mat,1);
8196:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8197:   MatNullSpaceDestroy(&mat->nearnullsp);
8198:   mat->nearnullsp = nullsp;
8199:   return(0);
8200: }

8204: /*@
8205:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

8207:    Not Collective

8209:    Input Parameters:
8210: .  mat - the matrix

8212:    Output Parameters:
8213: .  nullsp - the null space object, NULL if not set

8215:    Level: developer

8217:    Concepts: null space^attaching to matrix

8219: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8220: @*/
8221: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8222: {
8227:   MatCheckPreallocated(mat,1);
8228:   *nullsp = mat->nearnullsp;
8229:   return(0);
8230: }

8234: /*@C
8235:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

8237:    Collective on Mat

8239:    Input Parameters:
8240: +  mat - the matrix
8241: .  row - row/column permutation
8242: .  fill - expected fill factor >= 1.0
8243: -  level - level of fill, for ICC(k)

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

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

8253:    Level: developer

8255:    Concepts: matrices^incomplete Cholesky factorization
8256:    Concepts: Cholesky factorization

8258: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

8263: @*/
8264: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8265: {

8273:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8274:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8275:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8276:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8277:   MatCheckPreallocated(mat,1);
8278:   (*mat->ops->iccfactor)(mat,row,info);
8279:   PetscObjectStateIncrease((PetscObject)mat);
8280:   return(0);
8281: }

8285: /*@
8286:    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.

8288:    Not Collective

8290:    Input Parameters:
8291: +  mat - the matrix
8292: .  nl - leading dimension of v
8293: -  v - the values compute with ADIFOR

8295:    Level: developer

8297:    Notes:
8298:      Must call MatSetColoring() before using this routine. Also this matrix must already
8299:      have its nonzero pattern determined.

8301: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8302:           MatSetValues(), MatSetColoring()
8303: @*/
8304: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8305: {


8313:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8314:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
8315:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8316:   (*mat->ops->setvaluesadifor)(mat,nl,v);
8317:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
8318:   PetscObjectStateIncrease((PetscObject)mat);
8319:   return(0);
8320: }

8324: /*@
8325:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8326:          ghosted ones.

8328:    Not Collective

8330:    Input Parameters:
8331: +  mat - the matrix
8332: -  diag = the diagonal values, including ghost ones

8334:    Level: developer

8336:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

8338: .seealso: MatDiagonalScale()
8339: @*/
8340: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8341: {
8343:   PetscMPIInt    size;


8350:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8351:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8352:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8353:   if (size == 1) {
8354:     PetscInt n,m;
8355:     VecGetSize(diag,&n);
8356:     MatGetSize(mat,0,&m);
8357:     if (m == n) {
8358:       MatDiagonalScale(mat,0,diag);
8359:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8360:   } else {
8361:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8362:   }
8363:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8364:   PetscObjectStateIncrease((PetscObject)mat);
8365:   return(0);
8366: }

8370: /*@
8371:    MatGetInertia - Gets the inertia from a factored matrix

8373:    Collective on Mat

8375:    Input Parameter:
8376: .  mat - the matrix

8378:    Output Parameters:
8379: +   nneg - number of negative eigenvalues
8380: .   nzero - number of zero eigenvalues
8381: -   npos - number of positive eigenvalues

8383:    Level: advanced

8385:    Notes: Matrix must have been factored by MatCholeskyFactor()


8388: @*/
8389: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8390: {

8396:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8397:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8398:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8399:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8400:   return(0);
8401: }

8403: /* ----------------------------------------------------------------*/
8406: /*@C
8407:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

8409:    Neighbor-wise Collective on Mat and Vecs

8411:    Input Parameters:
8412: +  mat - the factored matrix
8413: -  b - the right-hand-side vectors

8415:    Output Parameter:
8416: .  x - the result vectors

8418:    Notes:
8419:    The vectors b and x cannot be the same.  I.e., one cannot
8420:    call MatSolves(A,x,x).

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

8427:    Level: developer

8429:    Concepts: matrices^triangular solves

8431: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8432: @*/
8433: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8434: {

8440:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8441:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8442:   if (!mat->rmap->N && !mat->cmap->N) return(0);

8444:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8445:   MatCheckPreallocated(mat,1);
8446:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8447:   (*mat->ops->solves)(mat,b,x);
8448:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8449:   return(0);
8450: }

8454: /*@
8455:    MatIsSymmetric - Test whether a matrix is symmetric

8457:    Collective on Mat

8459:    Input Parameter:
8460: +  A - the matrix to test
8461: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

8463:    Output Parameters:
8464: .  flg - the result

8466:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

8468:    Level: intermediate

8470:    Concepts: matrix^symmetry

8472: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8473: @*/
8474: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8475: {


8482:   if (!A->symmetric_set) {
8483:     if (!A->ops->issymmetric) {
8484:       MatType mattype;
8485:       MatGetType(A,&mattype);
8486:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8487:     }
8488:     (*A->ops->issymmetric)(A,tol,flg);
8489:     if (!tol) {
8490:       A->symmetric_set = PETSC_TRUE;
8491:       A->symmetric     = *flg;
8492:       if (A->symmetric) {
8493:         A->structurally_symmetric_set = PETSC_TRUE;
8494:         A->structurally_symmetric     = PETSC_TRUE;
8495:       }
8496:     }
8497:   } else if (A->symmetric) {
8498:     *flg = PETSC_TRUE;
8499:   } else if (!tol) {
8500:     *flg = PETSC_FALSE;
8501:   } else {
8502:     if (!A->ops->issymmetric) {
8503:       MatType mattype;
8504:       MatGetType(A,&mattype);
8505:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8506:     }
8507:     (*A->ops->issymmetric)(A,tol,flg);
8508:   }
8509:   return(0);
8510: }

8514: /*@
8515:    MatIsHermitian - Test whether a matrix is Hermitian

8517:    Collective on Mat

8519:    Input Parameter:
8520: +  A - the matrix to test
8521: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

8523:    Output Parameters:
8524: .  flg - the result

8526:    Level: intermediate

8528:    Concepts: matrix^symmetry

8530: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8531:           MatIsSymmetricKnown(), MatIsSymmetric()
8532: @*/
8533: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8534: {


8541:   if (!A->hermitian_set) {
8542:     if (!A->ops->ishermitian) {
8543:       MatType mattype;
8544:       MatGetType(A,&mattype);
8545:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8546:     }
8547:     (*A->ops->ishermitian)(A,tol,flg);
8548:     if (!tol) {
8549:       A->hermitian_set = PETSC_TRUE;
8550:       A->hermitian     = *flg;
8551:       if (A->hermitian) {
8552:         A->structurally_symmetric_set = PETSC_TRUE;
8553:         A->structurally_symmetric     = PETSC_TRUE;
8554:       }
8555:     }
8556:   } else if (A->hermitian) {
8557:     *flg = PETSC_TRUE;
8558:   } else if (!tol) {
8559:     *flg = PETSC_FALSE;
8560:   } else {
8561:     if (!A->ops->ishermitian) {
8562:       MatType mattype;
8563:       MatGetType(A,&mattype);
8564:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8565:     }
8566:     (*A->ops->ishermitian)(A,tol,flg);
8567:   }
8568:   return(0);
8569: }

8573: /*@
8574:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

8576:    Not Collective

8578:    Input Parameter:
8579: .  A - the matrix to check

8581:    Output Parameters:
8582: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8583: -  flg - the result

8585:    Level: advanced

8587:    Concepts: matrix^symmetry

8589:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8590:          if you want it explicitly checked

8592: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8593: @*/
8594: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8595: {
8600:   if (A->symmetric_set) {
8601:     *set = PETSC_TRUE;
8602:     *flg = A->symmetric;
8603:   } else {
8604:     *set = PETSC_FALSE;
8605:   }
8606:   return(0);
8607: }

8611: /*@
8612:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8614:    Not Collective

8616:    Input Parameter:
8617: .  A - the matrix to check

8619:    Output Parameters:
8620: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8621: -  flg - the result

8623:    Level: advanced

8625:    Concepts: matrix^symmetry

8627:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8628:          if you want it explicitly checked

8630: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8631: @*/
8632: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8633: {
8638:   if (A->hermitian_set) {
8639:     *set = PETSC_TRUE;
8640:     *flg = A->hermitian;
8641:   } else {
8642:     *set = PETSC_FALSE;
8643:   }
8644:   return(0);
8645: }

8649: /*@
8650:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8652:    Collective on Mat

8654:    Input Parameter:
8655: .  A - the matrix to test

8657:    Output Parameters:
8658: .  flg - the result

8660:    Level: intermediate

8662:    Concepts: matrix^symmetry

8664: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8665: @*/
8666: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8667: {

8673:   if (!A->structurally_symmetric_set) {
8674:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8675:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);

8677:     A->structurally_symmetric_set = PETSC_TRUE;
8678:   }
8679:   *flg = A->structurally_symmetric;
8680:   return(0);
8681: }

8685: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8686: /*@
8687:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8688:        to be communicated to other processors during the MatAssemblyBegin/End() process

8690:     Not collective

8692:    Input Parameter:
8693: .   vec - the vector

8695:    Output Parameters:
8696: +   nstash   - the size of the stash
8697: .   reallocs - the number of additional mallocs incurred.
8698: .   bnstash   - the size of the block stash
8699: -   breallocs - the number of additional mallocs incurred.in the block stash

8701:    Level: advanced

8703: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()

8705: @*/
8706: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8707: {

8711:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8712:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8713:   return(0);
8714: }

8718: /*@C
8719:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8720:      parallel layout

8722:    Collective on Mat

8724:    Input Parameter:
8725: .  mat - the matrix

8727:    Output Parameter:
8728: +   right - (optional) vector that the matrix can be multiplied against
8729: -   left - (optional) vector that the matrix vector product can be stored in

8731:    Notes:
8732:     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().

8734:   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed

8736:   Level: advanced

8738: .seealso: MatCreate(), VecDestroy()
8739: @*/
8740: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8741: {

8747:   if (mat->ops->getvecs) {
8748:     (*mat->ops->getvecs)(mat,right,left);
8749:   } else {
8750:     PetscInt rbs,cbs;
8751:     MatGetBlockSizes(mat,&rbs,&cbs);
8752:     if (right) {
8753:       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8754:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8755:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8756:       VecSetBlockSize(*right,cbs);
8757:       VecSetType(*right,VECSTANDARD);
8758:       PetscLayoutReference(mat->cmap,&(*right)->map);
8759:     }
8760:     if (left) {
8761:       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8762:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8763:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8764:       VecSetBlockSize(*left,rbs);
8765:       VecSetType(*left,VECSTANDARD);
8766:       PetscLayoutReference(mat->rmap,&(*left)->map);
8767:     }
8768:   }
8769:   return(0);
8770: }

8774: /*@C
8775:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8776:      with default values.

8778:    Not Collective

8780:    Input Parameters:
8781: .    info - the MatFactorInfo data structure


8784:    Notes: The solvers are generally used through the KSP and PC objects, for example
8785:           PCLU, PCILU, PCCHOLESKY, PCICC

8787:    Level: developer

8789: .seealso: MatFactorInfo

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

8794: @*/

8796: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8797: {

8801:   PetscMemzero(info,sizeof(MatFactorInfo));
8802:   return(0);
8803: }

8807: /*@
8808:    MatFactorSetSchurIS - Set indices corresponding to the Schur complement

8810:    Collective on Mat

8812:    Input Parameters:
8813: +  mat - the factored matrix
8814: -  is - the index set defining the Schur indices (0-based)

8816:    Notes:

8818:    Level: developer

8820:    Concepts:

8822: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()

8824: @*/
8825: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8826: {
8827:   PetscErrorCode ierr,(*f)(Mat,IS);

8835:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8836:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8837:   if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverPackage does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
8838:   (*f)(mat,is);
8839:   return(0);
8840: }

8844: /*@
8845:   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step

8847:    Logically Collective on Mat

8849:    Input Parameters:
8850: +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8851: .  *S - location where to return the Schur complement (MATDENSE)

8853:    Notes:
8854:    The routine provides a copy of the Schur data stored within solver's data strutures. The caller must destroy the object when it is no longer needed.
8855:    If MatFactorInvertSchurComplement has been called, the routine gets back the inverse

8857:    Level: advanced

8859:    References:

8861: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement()
8862: @*/
8863: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S)
8864: {

8869:   PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));
8870:   return(0);
8871: }

8875: /*@
8876:   MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data

8878:    Logically Collective on Mat

8880:    Input Parameters:
8881: +  F - the factored matrix obtained by calling MatGetFactor()
8882: .  *S - location where to return the Schur complement (in MATDENSE format)

8884:    Notes:
8885:    Schur complement mode is currently implemented for sequential matrices.
8886:    The routine returns a dense matrix pointing to the raw data of the Schur Complement stored within the data strutures of the solver; e.g. if MatFactorInvertSchurComplement has been called, the returned matrix is actually the inverse of the Schur complement.
8887:    The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.

8889:    Level: advanced

8891:    References:

8893: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8894: @*/
8895: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S)
8896: {

8901:   PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));
8902:   return(0);
8903: }

8907: /*@
8908:   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement

8910:    Logically Collective on Mat

8912:    Input Parameters:
8913: +  F - the factored matrix obtained by calling MatGetFactor()
8914: .  *S - location where the Schur complement is stored

8916:    Notes:

8918:    Level: advanced

8920:    References:

8922: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8923: @*/
8924: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S)
8925: {

8931:   MatDestroy(S);
8932:   return(0);
8933: }

8937: /*@
8938:   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step

8940:    Logically Collective on Mat

8942:    Input Parameters:
8943: +  F - the factored matrix obtained by calling MatGetFactor()
8944: .  rhs - location where the right hand side of the Schur complement system is stored
8945: -  sol - location where the solution of the Schur complement system has to be returned

8947:    Notes:
8948:    The sizes of the vectors should match the size of the Schur complement

8950:    Level: advanced

8952:    References:

8954: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8955: @*/
8956: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8957: {

8966:   PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));
8967:   return(0);
8968: }

8972: /*@
8973:   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step

8975:    Logically Collective on Mat

8977:    Input Parameters:
8978: +  F - the factored matrix obtained by calling MatGetFactor()
8979: .  rhs - location where the right hand side of the Schur complement system is stored
8980: -  sol - location where the solution of the Schur complement system has to be returned

8982:    Notes:
8983:    The sizes of the vectors should match the size of the Schur complement

8985:    Level: advanced

8987:    References:

8989: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8990: @*/
8991: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8992: {

9001:   PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));
9002:   return(0);
9003: }

9007: /*@
9008:   MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step

9010:    Logically Collective on Mat

9012:    Input Parameters:
9013: +  F - the factored matrix obtained by calling MatGetFactor()

9015:    Notes:

9017:    Level: advanced

9019:    References:

9021: .seealso: MatGetFactor(), MatFactorSetSchurIS()
9022: @*/
9023: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9024: {

9029:   PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));
9030:   return(0);
9031: }


9036: /*@
9037:    MatPtAP - Creates the matrix product C = P^T * A * P

9039:    Neighbor-wise Collective on Mat

9041:    Input Parameters:
9042: +  A - the matrix
9043: .  P - the projection matrix
9044: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9045: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9046:           if the result is a dense matrix this is irrelevent

9048:    Output Parameters:
9049: .  C - the product matrix

9051:    Notes:
9052:    C will be created and must be destroyed by the user with MatDestroy().

9054:    This routine is currently only implemented for pairs of AIJ matrices and classes
9055:    which inherit from AIJ.

9057:    Level: intermediate

9059: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9060: @*/
9061: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9062: {
9064:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9065:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9066:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9067:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

9070:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
9071:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

9075:   MatCheckPreallocated(A,1);
9076:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9077:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9080:   MatCheckPreallocated(P,2);
9081:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9082:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9084:   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);
9085:   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);
9086:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9087:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9089:   if (scall == MAT_REUSE_MATRIX) {
9092:     if (viatranspose || viamatmatmatmult) {
9093:       Mat Pt;
9094:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9095:       if (viamatmatmatmult) {
9096:         MatMatMatMult(Pt,A,P,scall,fill,C);
9097:       } else {
9098:         Mat AP;
9099:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9100:         MatMatMult(Pt,AP,scall,fill,C);
9101:         MatDestroy(&AP);
9102:       }
9103:       MatDestroy(&Pt);
9104:     } else {
9105:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9106:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9107:       (*(*C)->ops->ptapnumeric)(A,P,*C);
9108:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9109:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9110:     }
9111:     return(0);
9112:   }

9114:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9115:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9117:   fA = A->ops->ptap;
9118:   fP = P->ops->ptap;
9119:   if (fP == fA) {
9120:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9121:     ptap = fA;
9122:   } else {
9123:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9124:     char ptapname[256];
9125:     PetscStrcpy(ptapname,"MatPtAP_");
9126:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
9127:     PetscStrcat(ptapname,"_");
9128:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
9129:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9130:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9131:     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);
9132:   }

9134:   if (viatranspose || viamatmatmatmult) {
9135:     Mat Pt;
9136:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9137:     if (viamatmatmatmult) {
9138:       MatMatMatMult(Pt,A,P,scall,fill,C);
9139:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
9140:     } else {
9141:       Mat AP;
9142:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9143:       MatMatMult(Pt,AP,scall,fill,C);
9144:       MatDestroy(&AP);
9145:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
9146:     }
9147:     MatDestroy(&Pt);
9148:   } else {
9149:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9150:     (*ptap)(A,P,scall,fill,C);
9151:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9152:   }
9153:   return(0);
9154: }

9158: /*@
9159:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

9161:    Neighbor-wise Collective on Mat

9163:    Input Parameters:
9164: +  A - the matrix
9165: -  P - the projection matrix

9167:    Output Parameters:
9168: .  C - the product matrix

9170:    Notes:
9171:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9172:    the user using MatDeatroy().

9174:    This routine is currently only implemented for pairs of AIJ matrices and classes
9175:    which inherit from AIJ.  C will be of type MATAIJ.

9177:    Level: intermediate

9179: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9180: @*/
9181: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9182: {

9188:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9189:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9192:   MatCheckPreallocated(P,2);
9193:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9194:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9197:   MatCheckPreallocated(C,3);
9198:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9199:   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);
9200:   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);
9201:   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);
9202:   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);
9203:   MatCheckPreallocated(A,1);

9205:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9206:   (*C->ops->ptapnumeric)(A,P,C);
9207:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9208:   return(0);
9209: }

9213: /*@
9214:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

9216:    Neighbor-wise Collective on Mat

9218:    Input Parameters:
9219: +  A - the matrix
9220: -  P - the projection matrix

9222:    Output Parameters:
9223: .  C - the (i,j) structure of the product matrix

9225:    Notes:
9226:    C will be created and must be destroyed by the user with MatDestroy().

9228:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9229:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9230:    this (i,j) structure by calling MatPtAPNumeric().

9232:    Level: intermediate

9234: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9235: @*/
9236: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9237: {

9243:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9244:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9245:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9248:   MatCheckPreallocated(P,2);
9249:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9250:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9253:   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);
9254:   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);
9255:   MatCheckPreallocated(A,1);
9256:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9257:   (*A->ops->ptapsymbolic)(A,P,fill,C);
9258:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

9260:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
9261:   return(0);
9262: }

9266: /*@
9267:    MatRARt - Creates the matrix product C = R * A * R^T

9269:    Neighbor-wise Collective on Mat

9271:    Input Parameters:
9272: +  A - the matrix
9273: .  R - the projection matrix
9274: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9275: -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9276:           if the result is a dense matrix this is irrelevent

9278:    Output Parameters:
9279: .  C - the product matrix

9281:    Notes:
9282:    C will be created and must be destroyed by the user with MatDestroy().

9284:    This routine is currently only implemented for pairs of AIJ matrices and classes
9285:    which inherit from AIJ.

9287:    Level: intermediate

9289: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9290: @*/
9291: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9292: {

9298:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9299:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9302:   MatCheckPreallocated(R,2);
9303:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9304:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9306:   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);

9308:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9309:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9310:   MatCheckPreallocated(A,1);

9312:   if (!A->ops->rart) {
9313:     MatType mattype;
9314:     MatGetType(A,&mattype);
9315:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
9316:   }
9317:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
9318:   (*A->ops->rart)(A,R,scall,fill,C);
9319:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
9320:   return(0);
9321: }

9325: /*@
9326:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

9328:    Neighbor-wise Collective on Mat

9330:    Input Parameters:
9331: +  A - the matrix
9332: -  R - the projection matrix

9334:    Output Parameters:
9335: .  C - the product matrix

9337:    Notes:
9338:    C must have been created by calling MatRARtSymbolic and must be destroyed by
9339:    the user using MatDestroy().

9341:    This routine is currently only implemented for pairs of AIJ matrices and classes
9342:    which inherit from AIJ.  C will be of type MATAIJ.

9344:    Level: intermediate

9346: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9347: @*/
9348: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9349: {

9355:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9356:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9359:   MatCheckPreallocated(R,2);
9360:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9361:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9364:   MatCheckPreallocated(C,3);
9365:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9366:   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);
9367:   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);
9368:   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);
9369:   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);
9370:   MatCheckPreallocated(A,1);

9372:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
9373:   (*A->ops->rartnumeric)(A,R,C);
9374:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
9375:   return(0);
9376: }

9380: /*@
9381:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

9383:    Neighbor-wise Collective on Mat

9385:    Input Parameters:
9386: +  A - the matrix
9387: -  R - the projection matrix

9389:    Output Parameters:
9390: .  C - the (i,j) structure of the product matrix

9392:    Notes:
9393:    C will be created and must be destroyed by the user with MatDestroy().

9395:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9396:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9397:    this (i,j) structure by calling MatRARtNumeric().

9399:    Level: intermediate

9401: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9402: @*/
9403: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9404: {

9410:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9411:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9412:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9415:   MatCheckPreallocated(R,2);
9416:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9417:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9420:   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);
9421:   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);
9422:   MatCheckPreallocated(A,1);
9423:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9424:   (*A->ops->rartsymbolic)(A,R,fill,C);
9425:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

9427:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9428:   return(0);
9429: }

9433: /*@
9434:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

9436:    Neighbor-wise Collective on Mat

9438:    Input Parameters:
9439: +  A - the left matrix
9440: .  B - the right matrix
9441: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9442: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9443:           if the result is a dense matrix this is irrelevent

9445:    Output Parameters:
9446: .  C - the product matrix

9448:    Notes:
9449:    Unless scall is MAT_REUSE_MATRIX C will be created.

9451:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9453:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9454:    actually needed.

9456:    If you have many matrices with the same non-zero structure to multiply, you
9457:    should either
9458: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9459: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9460:    In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine
9461:    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.

9463:    Level: intermediate

9465: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9466: @*/
9467: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9468: {
9470:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9471:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9472:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9477:   MatCheckPreallocated(A,1);
9478:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9479:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9482:   MatCheckPreallocated(B,2);
9483:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9484:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9486:   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);
9487:   if (scall == MAT_REUSE_MATRIX) {
9490:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9491:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9492:     (*(*C)->ops->matmultnumeric)(A,B,*C);
9493:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9494:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9495:     return(0);
9496:   }
9497:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9498:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9500:   fA = A->ops->matmult;
9501:   fB = B->ops->matmult;
9502:   if (fB == fA) {
9503:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9504:     mult = fB;
9505:   } else {
9506:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9507:     char multname[256];
9508:     PetscStrcpy(multname,"MatMatMult_");
9509:     PetscStrcat(multname,((PetscObject)A)->type_name);
9510:     PetscStrcat(multname,"_");
9511:     PetscStrcat(multname,((PetscObject)B)->type_name);
9512:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9513:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9514:     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);
9515:   }
9516:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9517:   (*mult)(A,B,scall,fill,C);
9518:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9519:   return(0);
9520: }

9524: /*@
9525:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9526:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

9528:    Neighbor-wise Collective on Mat

9530:    Input Parameters:
9531: +  A - the left matrix
9532: .  B - the right matrix
9533: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9534:       if C is a dense matrix this is irrelevent

9536:    Output Parameters:
9537: .  C - the product matrix

9539:    Notes:
9540:    Unless scall is MAT_REUSE_MATRIX C will be created.

9542:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9543:    actually needed.

9545:    This routine is currently implemented for
9546:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9547:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9548:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9550:    Level: intermediate

9552:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9553:      We should incorporate them into PETSc.

9555: .seealso: MatMatMult(), MatMatMultNumeric()
9556: @*/
9557: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9558: {
9560:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9561:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9562:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

9567:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9568:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9572:   MatCheckPreallocated(B,2);
9573:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9574:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9577:   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);
9578:   if (fill == PETSC_DEFAULT) fill = 2.0;
9579:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9580:   MatCheckPreallocated(A,1);

9582:   Asymbolic = A->ops->matmultsymbolic;
9583:   Bsymbolic = B->ops->matmultsymbolic;
9584:   if (Asymbolic == Bsymbolic) {
9585:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9586:     symbolic = Bsymbolic;
9587:   } else { /* dispatch based on the type of A and B */
9588:     char symbolicname[256];
9589:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9590:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9591:     PetscStrcat(symbolicname,"_");
9592:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9593:     PetscStrcat(symbolicname,"_C");
9594:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9595:     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);
9596:   }
9597:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9598:   (*symbolic)(A,B,fill,C);
9599:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9600:   return(0);
9601: }

9605: /*@
9606:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9607:    Call this routine after first calling MatMatMultSymbolic().

9609:    Neighbor-wise Collective on Mat

9611:    Input Parameters:
9612: +  A - the left matrix
9613: -  B - the right matrix

9615:    Output Parameters:
9616: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

9618:    Notes:
9619:    C must have been created with MatMatMultSymbolic().

9621:    This routine is currently implemented for
9622:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9623:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9624:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9626:    Level: intermediate

9628: .seealso: MatMatMult(), MatMatMultSymbolic()
9629: @*/
9630: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9631: {

9635:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9636:   return(0);
9637: }

9641: /*@
9642:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

9644:    Neighbor-wise Collective on Mat

9646:    Input Parameters:
9647: +  A - the left matrix
9648: .  B - the right matrix
9649: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9650: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9652:    Output Parameters:
9653: .  C - the product matrix

9655:    Notes:
9656:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

9658:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9660:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9661:    actually needed.

9663:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

9665:    Level: intermediate

9667: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9668: @*/
9669: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9670: {
9672:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9673:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

9678:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9679:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9682:   MatCheckPreallocated(B,2);
9683:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9684:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9686:   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);
9687:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9688:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9689:   MatCheckPreallocated(A,1);

9691:   fA = A->ops->mattransposemult;
9692:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9693:   fB = B->ops->mattransposemult;
9694:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9695:   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);

9697:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9698:   if (scall == MAT_INITIAL_MATRIX) {
9699:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9700:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9701:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9702:   }
9703:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9704:   (*A->ops->mattransposemultnumeric)(A,B,*C);
9705:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9706:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9707:   return(0);
9708: }

9712: /*@
9713:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

9715:    Neighbor-wise Collective on Mat

9717:    Input Parameters:
9718: +  A - the left matrix
9719: .  B - the right matrix
9720: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9721: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9723:    Output Parameters:
9724: .  C - the product matrix

9726:    Notes:
9727:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

9729:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9731:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9732:    actually needed.

9734:    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9735:    which inherit from SeqAIJ.  C will be of same type as the input matrices.

9737:    Level: intermediate

9739: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9740: @*/
9741: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9742: {
9744:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9745:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9746:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

9751:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9752:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9755:   MatCheckPreallocated(B,2);
9756:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9757:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9759:   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);
9760:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9761:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9762:   MatCheckPreallocated(A,1);

9764:   fA = A->ops->transposematmult;
9765:   fB = B->ops->transposematmult;
9766:   if (fB==fA) {
9767:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9768:     transposematmult = fA;
9769:   } else {
9770:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9771:     char multname[256];
9772:     PetscStrcpy(multname,"MatTransposeMatMult_");
9773:     PetscStrcat(multname,((PetscObject)A)->type_name);
9774:     PetscStrcat(multname,"_");
9775:     PetscStrcat(multname,((PetscObject)B)->type_name);
9776:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9777:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9778:     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);
9779:   }
9780:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9781:   (*transposematmult)(A,B,scall,fill,C);
9782:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9783:   return(0);
9784: }

9788: /*@
9789:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

9791:    Neighbor-wise Collective on Mat

9793:    Input Parameters:
9794: +  A - the left matrix
9795: .  B - the middle matrix
9796: .  C - the right matrix
9797: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9798: -  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
9799:           if the result is a dense matrix this is irrelevent

9801:    Output Parameters:
9802: .  D - the product matrix

9804:    Notes:
9805:    Unless scall is MAT_REUSE_MATRIX D will be created.

9807:    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call

9809:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9810:    actually needed.

9812:    If you have many matrices with the same non-zero structure to multiply, you
9813:    should use MAT_REUSE_MATRIX in all calls but the first or

9815:    Level: intermediate

9817: .seealso: MatMatMult, MatPtAP()
9818: @*/
9819: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9820: {
9822:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9823:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9824:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9825:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9830:   MatCheckPreallocated(A,1);
9831:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9832:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9835:   MatCheckPreallocated(B,2);
9836:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9837:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9840:   MatCheckPreallocated(C,3);
9841:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9842:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9843:   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);
9844:   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);
9845:   if (scall == MAT_REUSE_MATRIX) {
9848:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9849:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9850:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9851:     return(0);
9852:   }
9853:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9854:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9856:   fA = A->ops->matmatmult;
9857:   fB = B->ops->matmatmult;
9858:   fC = C->ops->matmatmult;
9859:   if (fA == fB && fA == fC) {
9860:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9861:     mult = fA;
9862:   } else {
9863:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9864:     char multname[256];
9865:     PetscStrcpy(multname,"MatMatMatMult_");
9866:     PetscStrcat(multname,((PetscObject)A)->type_name);
9867:     PetscStrcat(multname,"_");
9868:     PetscStrcat(multname,((PetscObject)B)->type_name);
9869:     PetscStrcat(multname,"_");
9870:     PetscStrcat(multname,((PetscObject)C)->type_name);
9871:     PetscStrcat(multname,"_C");
9872:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9873:     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);
9874:   }
9875:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9876:   (*mult)(A,B,C,scall,fill,D);
9877:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9878:   return(0);
9879: }

9883: /*@
9884:    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

9886:    Collective on Mat

9888:    Input Parameters:
9889: +  mat - the matrix
9890: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9891: .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9892: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9894:    Output Parameter:
9895: .  matredundant - redundant matrix

9897:    Notes:
9898:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9899:    original matrix has not changed from that last call to MatCreateRedundantMatrix().

9901:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9902:    calling it.

9904:    Level: advanced

9906:    Concepts: subcommunicator
9907:    Concepts: duplicate matrix

9909: .seealso: MatDestroy()
9910: @*/
9911: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9912: {
9914:   MPI_Comm       comm;
9915:   PetscMPIInt    size;
9916:   PetscInt       mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9917:   Mat_Redundant  *redund=NULL;
9918:   PetscSubcomm   psubcomm=NULL;
9919:   MPI_Comm       subcomm_in=subcomm;
9920:   Mat            *matseq;
9921:   IS             isrow,iscol;
9922:   PetscBool      newsubcomm=PETSC_FALSE;

9925:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
9926:   if (size == 1 || nsubcomm == 1) {
9927:     if (reuse == MAT_INITIAL_MATRIX) {
9928:       MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
9929:     } else {
9930:       MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
9931:     }
9932:     return(0);
9933:   }

9936:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9939:   }
9940:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9941:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9942:   MatCheckPreallocated(mat,1);

9944:   PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
9945:   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9946:     /* create psubcomm, then get subcomm */
9947:     PetscObjectGetComm((PetscObject)mat,&comm);
9948:     MPI_Comm_size(comm,&size);
9949:     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);

9951:     PetscSubcommCreate(comm,&psubcomm);
9952:     PetscSubcommSetNumber(psubcomm,nsubcomm);
9953:     PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
9954:     PetscSubcommSetFromOptions(psubcomm);
9955:     PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);
9956:     newsubcomm = PETSC_TRUE;
9957:     PetscSubcommDestroy(&psubcomm);
9958:   }

9960:   /* get isrow, iscol and a local sequential matrix matseq[0] */
9961:   if (reuse == MAT_INITIAL_MATRIX) {
9962:     mloc_sub = PETSC_DECIDE;
9963:     if (bs < 1) {
9964:       PetscSplitOwnership(subcomm,&mloc_sub,&M);
9965:     } else {
9966:       PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
9967:     }
9968:     MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
9969:     rstart = rend - mloc_sub;
9970:     ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
9971:     ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
9972:   } else { /* reuse == MAT_REUSE_MATRIX */
9973:     /* retrieve subcomm */
9974:     PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
9975:     redund = (*matredundant)->redundant;
9976:     isrow  = redund->isrow;
9977:     iscol  = redund->iscol;
9978:     matseq = redund->matseq;
9979:   }
9980:   MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);

9982:   /* get matredundant over subcomm */
9983:   if (reuse == MAT_INITIAL_MATRIX) {
9984:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);

9986:     /* create a supporting struct and attach it to C for reuse */
9987:     PetscNewLog(*matredundant,&redund);
9988:     (*matredundant)->redundant = redund;
9989:     redund->isrow              = isrow;
9990:     redund->iscol              = iscol;
9991:     redund->matseq             = matseq;
9992:     if (newsubcomm) {
9993:       redund->subcomm          = subcomm;
9994:     } else {
9995:       redund->subcomm          = MPI_COMM_NULL;
9996:     }
9997:   } else {
9998:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
9999:   }
10000:   PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
10001:   return(0);
10002: }

10006: /*@C
10007:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10008:    a given 'mat' object. Each submatrix can span multiple procs.

10010:    Collective on Mat

10012:    Input Parameters:
10013: +  mat - the matrix
10014: .  subcomm - the subcommunicator obtained by com_split(comm)
10015: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

10017:    Output Parameter:
10018: .  subMat - 'parallel submatrices each spans a given subcomm

10020:   Notes:
10021:   The submatrix partition across processors is dictated by 'subComm' a
10022:   communicator obtained by com_split(comm). The comm_split
10023:   is not restriced to be grouped with consecutive original ranks.

10025:   Due the comm_split() usage, the parallel layout of the submatrices
10026:   map directly to the layout of the original matrix [wrt the local
10027:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10028:   into the 'DiagonalMat' of the subMat, hence it is used directly from
10029:   the subMat. However the offDiagMat looses some columns - and this is
10030:   reconstructed with MatSetValues()

10032:   Level: advanced

10034:   Concepts: subcommunicator
10035:   Concepts: submatrices

10037: .seealso: MatGetSubMatrices()
10038: @*/
10039: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10040: {
10042:   PetscMPIInt    commsize,subCommSize;

10045:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
10046:   MPI_Comm_size(subComm,&subCommSize);
10047:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

10049:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
10050:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
10051:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
10052:   return(0);
10053: }

10057: /*@
10058:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

10060:    Not Collective

10062:    Input Arguments:
10063:    mat - matrix to extract local submatrix from
10064:    isrow - local row indices for submatrix
10065:    iscol - local column indices for submatrix

10067:    Output Arguments:
10068:    submat - the submatrix

10070:    Level: intermediate

10072:    Notes:
10073:    The submat should be returned with MatRestoreLocalSubMatrix().

10075:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10076:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

10078:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10079:    MatSetValuesBlockedLocal() will also be implemented.

10081:    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 
10082:    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.   

10084: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10085: @*/
10086: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10087: {

10096:   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10097: 
10098:   if (mat->ops->getlocalsubmatrix) {
10099:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
10100:   } else {
10101:     MatCreateLocalRef(mat,isrow,iscol,submat);
10102:   }
10103:   return(0);
10104: }

10108: /*@
10109:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

10111:    Not Collective

10113:    Input Arguments:
10114:    mat - matrix to extract local submatrix from
10115:    isrow - local row indices for submatrix
10116:    iscol - local column indices for submatrix
10117:    submat - the submatrix

10119:    Level: intermediate

10121: .seealso: MatGetLocalSubMatrix()
10122: @*/
10123: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10124: {

10133:   if (*submat) {
10135:   }

10137:   if (mat->ops->restorelocalsubmatrix) {
10138:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
10139:   } else {
10140:     MatDestroy(submat);
10141:   }
10142:   *submat = NULL;
10143:   return(0);
10144: }

10146: /* --------------------------------------------------------*/
10149: /*@
10150:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

10152:    Collective on Mat

10154:    Input Parameter:
10155: .  mat - the matrix

10157:    Output Parameter:
10158: .  is - if any rows have zero diagonals this contains the list of them

10160:    Level: developer

10162:    Concepts: matrix-vector product

10164: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10165: @*/
10166: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10167: {

10173:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10174:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

10176:   if (!mat->ops->findzerodiagonals) {
10177:     Vec                diag;
10178:     const PetscScalar *a;
10179:     PetscInt          *rows;
10180:     PetscInt           rStart, rEnd, r, nrow = 0;

10182:     MatCreateVecs(mat, &diag, NULL);
10183:     MatGetDiagonal(mat, diag);
10184:     MatGetOwnershipRange(mat, &rStart, &rEnd);
10185:     VecGetArrayRead(diag, &a);
10186:     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10187:     PetscMalloc1(nrow, &rows);
10188:     nrow = 0;
10189:     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10190:     VecRestoreArrayRead(diag, &a);
10191:     VecDestroy(&diag);
10192:     ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);
10193:   } else {
10194:     (*mat->ops->findzerodiagonals)(mat, is);
10195:   }
10196:   return(0);
10197: }

10201: /*@
10202:    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)

10204:    Collective on Mat

10206:    Input Parameter:
10207: .  mat - the matrix

10209:    Output Parameter:
10210: .  is - contains the list of rows with off block diagonal entries

10212:    Level: developer

10214:    Concepts: matrix-vector product

10216: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10217: @*/
10218: PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10219: {

10225:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10226:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

10228:   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10229:   (*mat->ops->findoffblockdiagonalentries)(mat,is);
10230:   return(0);
10231: }

10235: /*@C
10236:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

10238:   Collective on Mat

10240:   Input Parameters:
10241: . mat - the matrix

10243:   Output Parameters:
10244: . values - the block inverses in column major order (FORTRAN-like)

10246:    Note:
10247:    This routine is not available from Fortran.

10249:   Level: advanced
10250: @*/
10251: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10252: {

10257:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10258:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10259:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10260:   (*mat->ops->invertblockdiagonal)(mat,values);
10261:   return(0);
10262: }

10266: /*@C
10267:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10268:     via MatTransposeColoringCreate().

10270:     Collective on MatTransposeColoring

10272:     Input Parameter:
10273: .   c - coloring context

10275:     Level: intermediate

10277: .seealso: MatTransposeColoringCreate()
10278: @*/
10279: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10280: {
10281:   PetscErrorCode       ierr;
10282:   MatTransposeColoring matcolor=*c;

10285:   if (!matcolor) return(0);
10286:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

10288:   PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
10289:   PetscFree(matcolor->rows);
10290:   PetscFree(matcolor->den2sp);
10291:   PetscFree(matcolor->colorforcol);
10292:   PetscFree(matcolor->columns);
10293:   if (matcolor->brows>0) {
10294:     PetscFree(matcolor->lstart);
10295:   }
10296:   PetscHeaderDestroy(c);
10297:   return(0);
10298: }

10302: /*@C
10303:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10304:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10305:     MatTransposeColoring to sparse B.

10307:     Collective on MatTransposeColoring

10309:     Input Parameters:
10310: +   B - sparse matrix B
10311: .   Btdense - symbolic dense matrix B^T
10312: -   coloring - coloring context created with MatTransposeColoringCreate()

10314:     Output Parameter:
10315: .   Btdense - dense matrix B^T

10317:     Options Database Keys:
10318: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
10319: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
10320: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

10322:     Level: intermediate

10324: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

10326: .keywords: coloring
10327: @*/
10328: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10329: {


10337:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10338:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
10339:   return(0);
10340: }

10344: /*@C
10345:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10346:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10347:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10348:     Csp from Cden.

10350:     Collective on MatTransposeColoring

10352:     Input Parameters:
10353: +   coloring - coloring context created with MatTransposeColoringCreate()
10354: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

10356:     Output Parameter:
10357: .   Csp - sparse matrix

10359:     Options Database Keys:
10360: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
10361: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
10362: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

10364:     Level: intermediate

10366: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

10368: .keywords: coloring
10369: @*/
10370: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10371: {


10379:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10380:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
10381:   return(0);
10382: }

10386: /*@C
10387:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

10389:    Collective on Mat

10391:    Input Parameters:
10392: +  mat - the matrix product C
10393: -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()

10395:     Output Parameter:
10396: .   color - the new coloring context

10398:     Level: intermediate

10400: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
10401:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
10402: @*/
10403: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10404: {
10405:   MatTransposeColoring c;
10406:   MPI_Comm             comm;
10407:   PetscErrorCode       ierr;

10410:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
10411:   PetscObjectGetComm((PetscObject)mat,&comm);
10412:   PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);

10414:   c->ctype = iscoloring->ctype;
10415:   if (mat->ops->transposecoloringcreate) {
10416:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
10417:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

10419:   *color = c;
10420:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
10421:   return(0);
10422: }

10426: /*@
10427:       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10428:         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10429:         same, otherwise it will be larger

10431:      Not Collective

10433:   Input Parameter:
10434: .    A  - the matrix

10436:   Output Parameter:
10437: .    state - the current state

10439:   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10440:          different matrices

10442:   Level: intermediate

10444: @*/
10445: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10446: {
10449:   *state = mat->nonzerostate;
10450:   return(0);
10451: }

10455: /*@
10456:       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10457:                  matrices from each processor

10459:     Collective on MPI_Comm

10461:    Input Parameters:
10462: +    comm - the communicators the parallel matrix will live on
10463: .    seqmat - the input sequential matrices
10464: .    n - number of local columns (or PETSC_DECIDE)
10465: -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

10467:    Output Parameter:
10468: .    mpimat - the parallel matrix generated

10470:     Level: advanced

10472:    Notes: The number of columns of the matrix in EACH processor MUST be the same.

10474: @*/
10475: PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10476: {
10478:   PetscMPIInt    size;

10481:   MPI_Comm_size(comm,&size);
10482:   if (size == 1) {
10483:     if (reuse == MAT_INITIAL_MATRIX) {
10484:       MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);
10485:     } else {
10486:       MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);
10487:     }
10488:     return(0);
10489:   }

10491:   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10492:   PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);
10493:   (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);
10494:   PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);
10495:   return(0);
10496: }

10500: /*@
10501:      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10502:                  ranks' ownership ranges.

10504:     Collective on A

10506:    Input Parameters:
10507: +    A   - the matrix to create subdomains from
10508: -    N   - requested number of subdomains


10511:    Output Parameters:
10512: +    n   - number of subdomains resulting on this rank
10513: -    iss - IS list with indices of subdomains on this rank

10515:     Level: advanced

10517:     Notes: number of subdomains must be smaller than the communicator size
10518: @*/
10519: PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10520: {
10521:   MPI_Comm        comm,subcomm;
10522:   PetscMPIInt     size,rank,color;
10523:   PetscInt        rstart,rend,k;
10524:   PetscErrorCode  ierr;

10527:   PetscObjectGetComm((PetscObject)A,&comm);
10528:   MPI_Comm_size(comm,&size);
10529:   MPI_Comm_rank(comm,&rank);
10530:   if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N);
10531:   *n = 1;
10532:   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10533:   color = rank/k;
10534:   MPI_Comm_split(comm,color,rank,&subcomm);
10535:   PetscMalloc1(1,iss);
10536:   MatGetOwnershipRange(A,&rstart,&rend);
10537:   ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);
10538:   MPI_Comm_free(&subcomm);
10539:   return(0);
10540: }