Actual source code: matrix.c

petsc-master 2016-05-02
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 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 MUSAT 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 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: +  x - 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,"Mat type %s",((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) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4241:   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4242:   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);

4244:   (*conv)(mat,ftype,f);
4245:   return(0);
4246: }

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

4253:    Not Collective

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

4260:    Output Parameter:
4261: .    flg - PETSC_TRUE if the factorization is available

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

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

4269:    Level: intermediate

4271: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4272: @*/
4273: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4274: {
4275:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);


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

4284:   *flg = PETSC_FALSE;
4285:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4286:   if (gconv) {
4287:     *flg = PETSC_TRUE;
4288:   }
4289:   return(0);
4290: }

4292: #include <petscdmtypes.h>

4296: /*@
4297:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4299:    Collective on Mat

4301:    Input Parameters:
4302: +  mat - the matrix
4303: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4304:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

4306:    Output Parameter:
4307: .  M - pointer to place new matrix

4309:    Level: intermediate

4311:    Concepts: matrices^duplicating

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

4315: .seealso: MatCopy(), MatConvert()
4316: @*/
4317: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4318: {
4320:   Mat            B;
4321:   PetscInt       i;
4322:   DM             dm;

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

4332:   *M = 0;
4333:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4334:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4335:   (*mat->ops->duplicate)(mat,op,M);
4336:   B    = *M;

4338:   B->stencil.dim = mat->stencil.dim;
4339:   B->stencil.noc = mat->stencil.noc;
4340:   for (i=0; i<=mat->stencil.dim; i++) {
4341:     B->stencil.dims[i]   = mat->stencil.dims[i];
4342:     B->stencil.starts[i] = mat->stencil.starts[i];
4343:   }

4345:   B->nooffproczerorows = mat->nooffproczerorows;
4346:   B->nooffprocentries  = mat->nooffprocentries;

4348:   PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4349:   if (dm) {
4350:     PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4351:   }
4352:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4353:   PetscObjectStateIncrease((PetscObject)B);
4354:   return(0);
4355: }

4359: /*@
4360:    MatGetDiagonal - Gets the diagonal of a matrix.

4362:    Logically Collective on Mat and Vec

4364:    Input Parameters:
4365: +  mat - the matrix
4366: -  v - the vector for storing the diagonal

4368:    Output Parameter:
4369: .  v - the diagonal of the matrix

4371:    Level: intermediate

4373:    Note:
4374:    Currently only correct in parallel for square matrices.

4376:    Concepts: matrices^accessing diagonals

4378: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4379: @*/
4380: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4381: {

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

4392:   (*mat->ops->getdiagonal)(mat,v);
4393:   PetscObjectStateIncrease((PetscObject)v);
4394:   return(0);
4395: }

4399: /*@C
4400:    MatGetRowMin - Gets the minimum value (of the real part) of each
4401:         row of the matrix

4403:    Logically Collective on Mat and Vec

4405:    Input Parameters:
4406: .  mat - the matrix

4408:    Output Parameter:
4409: +  v - the vector for storing the maximums
4410: -  idx - the indices of the column found for each row (optional)

4412:    Level: intermediate

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

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

4419:    Concepts: matrices^getting row maximums

4421: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4422:           MatGetRowMax()
4423: @*/
4424: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4425: {

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

4436:   (*mat->ops->getrowmin)(mat,v,idx);
4437:   PetscObjectStateIncrease((PetscObject)v);
4438:   return(0);
4439: }

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

4447:    Logically Collective on Mat and Vec

4449:    Input Parameters:
4450: .  mat - the matrix

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

4456:    Level: intermediate

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

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

4463:    Concepts: matrices^getting row maximums

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

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

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

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

4491:    Logically Collective on Mat and Vec

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

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

4500:    Level: intermediate

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

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

4507:    Concepts: matrices^getting row maximums

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

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

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

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

4534:    Logically Collective on Mat and Vec

4536:    Input Parameters:
4537: .  mat - the matrix

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

4543:    Level: intermediate

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

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

4550:    Concepts: matrices^getting row maximums

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

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

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

4574: /*@
4575:    MatGetRowSum - Gets the sum of each row of the matrix

4577:    Logically Collective on Mat and Vec

4579:    Input Parameters:
4580: .  mat - the matrix

4582:    Output Parameter:
4583: .  v - the vector for storing the sum of rows

4585:    Level: intermediate

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

4589:    Concepts: matrices^getting row sums

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

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

4612:     array[row - start] = 0.0;

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

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

4630:    Collective on Mat

4632:    Input Parameter:
4633: +  mat - the matrix to transpose
4634: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4636:    Output Parameters:
4637: .  B - the transpose

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

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

4644:    Level: intermediate

4646:    Concepts: matrices^transposing

4648: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4649: @*/
4650: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4651: {

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

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

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

4675:    Collective on Mat

4677:    Input Parameter:
4678: +  A - the matrix to test
4679: -  B - the matrix to test against, this can equal the first parameter

4681:    Output Parameters:
4682: .  flg - the result

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

4689:    Level: intermediate

4691:    Concepts: matrices^transposing, matrix^symmetry

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

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

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

4727:    Collective on Mat

4729:    Input Parameter:
4730: +  mat - the matrix to transpose and complex conjugate
4731: -  reuse - store the transpose matrix in the provided B

4733:    Output Parameters:
4734: .  B - the Hermitian

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

4739:    Level: intermediate

4741:    Concepts: matrices^transposing, complex conjugatex

4743: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4744: @*/
4745: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4746: {

4750:   MatTranspose(mat,reuse,B);
4751: #if defined(PETSC_USE_COMPLEX)
4752:   MatConjugate(*B);
4753: #endif
4754:   return(0);
4755: }

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

4762:    Collective on Mat

4764:    Input Parameter:
4765: +  A - the matrix to test
4766: -  B - the matrix to test against, this can equal the first parameter

4768:    Output Parameters:
4769: .  flg - the result

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

4776:    Level: intermediate

4778:    Concepts: matrices^transposing, matrix^symmetry

4780: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4781: @*/
4782: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4783: {
4784:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4790:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4791:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4792:   if (f && g) {
4793:     if (f==g) {
4794:       (*f)(A,B,tol,flg);
4795:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4796:   }
4797:   return(0);
4798: }

4802: /*@
4803:    MatPermute - Creates a new matrix with rows and columns permuted from the
4804:    original.

4806:    Collective on Mat

4808:    Input Parameters:
4809: +  mat - the matrix to permute
4810: .  row - row permutation, each processor supplies only the permutation for its rows
4811: -  col - column permutation, each processor supplies only the permutation for its columns

4813:    Output Parameters:
4814: .  B - the permuted matrix

4816:    Level: advanced

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

4822:    Concepts: matrices^permuting

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

4826: @*/
4827: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4828: {

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

4842:   (*mat->ops->permute)(mat,row,col,B);
4843:   PetscObjectStateIncrease((PetscObject)*B);
4844:   return(0);
4845: }

4849: /*@
4850:    MatEqual - Compares two matrices.

4852:    Collective on Mat

4854:    Input Parameters:
4855: +  A - the first matrix
4856: -  B - the second matrix

4858:    Output Parameter:
4859: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4861:    Level: intermediate

4863:    Concepts: matrices^equality between
4864: @*/
4865: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4866: {

4876:   MatCheckPreallocated(B,2);
4877:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4878:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4879:   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);
4880:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4881:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4882:   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);
4883:   MatCheckPreallocated(A,1);

4885:   (*A->ops->equal)(A,B,flg);
4886:   return(0);
4887: }

4891: /*@
4892:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4893:    matrices that are stored as vectors.  Either of the two scaling
4894:    matrices can be NULL.

4896:    Collective on Mat

4898:    Input Parameters:
4899: +  mat - the matrix to be scaled
4900: .  l - the left scaling vector (or NULL)
4901: -  r - the right scaling vector (or NULL)

4903:    Notes:
4904:    MatDiagonalScale() computes A = LAR, where
4905:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4906:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4908:    Level: intermediate

4910:    Concepts: matrices^diagonal scaling
4911:    Concepts: diagonal scaling of matrices

4913: .seealso: MatScale()
4914: @*/
4915: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4916: {

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

4929:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4930:   (*mat->ops->diagonalscale)(mat,l,r);
4931:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4932:   PetscObjectStateIncrease((PetscObject)mat);
4933: #if defined(PETSC_HAVE_CUSP)
4934:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4935:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4936:   }
4937: #elif defined(PETSC_HAVE_VIENNACL)
4938:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4939:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4940:   }
4941: #elif defined(PETSC_HAVE_VECCUDA)
4942:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4943:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4944:   }
4945: #endif
4946:   return(0);
4947: }

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

4954:     Logically Collective on Mat

4956:     Input Parameters:
4957: +   mat - the matrix to be scaled
4958: -   a  - the scaling value

4960:     Output Parameter:
4961: .   mat - the scaled matrix

4963:     Level: intermediate

4965:     Concepts: matrices^scaling all entries

4967: .seealso: MatDiagonalScale()
4968: @*/
4969: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4970: {

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

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

5006: /*@
5007:    MatNorm - Calculates various norms of a matrix.

5009:    Collective on Mat

5011:    Input Parameters:
5012: +  mat - the matrix
5013: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

5015:    Output Parameters:
5016: .  nrm - the resulting norm

5018:    Level: intermediate

5020:    Concepts: matrices^norm
5021:    Concepts: norm^of matrix
5022: @*/
5023: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5024: {


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

5037:   (*mat->ops->norm)(mat,type,nrm);
5038:   return(0);
5039: }

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

5052:    Collective on Mat

5054:    Input Parameters:
5055: +  mat - the matrix
5056: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5058:    Notes:
5059:    MatSetValues() generally caches the values.  The matrix is ready to
5060:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5061:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5062:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5063:    using the matrix.

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

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

5073:    Level: beginner

5075:    Concepts: matrices^assembling

5077: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5078: @*/
5079: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5080: {

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

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

5108:    Not Collective

5110:    Input Parameter:
5111: .  mat - the matrix

5113:    Output Parameter:
5114: .  assembled - PETSC_TRUE or PETSC_FALSE

5116:    Level: advanced

5118:    Concepts: matrices^assembled?

5120: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5121: @*/
5122: PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5123: {
5128:   *assembled = mat->assembled;
5129:   return(0);
5130: }

5134: /*@
5135:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5136:    be called after MatAssemblyBegin().

5138:    Collective on Mat

5140:    Input Parameters:
5141: +  mat - the matrix
5142: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

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

5157:    Notes:
5158:    MatSetValues() generally caches the values.  The matrix is ready to
5159:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5160:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5161:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5162:    using the matrix.

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

5168:    Level: beginner

5170: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5171: @*/
5172: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5173: {
5174:   PetscErrorCode  ierr;
5175:   static PetscInt inassm = 0;
5176:   PetscBool       flg    = PETSC_FALSE;


5182:   inassm++;
5183:   MatAssemblyEnd_InUse++;
5184:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5185:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5186:     if (mat->ops->assemblyend) {
5187:       (*mat->ops->assemblyend)(mat,type);
5188:     }
5189:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5190:   } else if (mat->ops->assemblyend) {
5191:     (*mat->ops->assemblyend)(mat,type);
5192:   }

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

5222:     if (mat->checksymmetryonassembly) {
5223:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5224:       if (flg) {
5225:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5226:       } else {
5227:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5228:       }
5229:     }
5230:     if (mat->nullsp && mat->checknullspaceonassembly) {
5231:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5232:     }
5233:   }
5234:   inassm--;
5235:   return(0);
5236: }

5240: /*@
5241:    MatSetOption - Sets a parameter option for a matrix. Some options
5242:    may be specific to certain storage formats.  Some options
5243:    determine how values will be inserted (or added). Sorted,
5244:    row-oriented input will generally assemble the fastest. The default
5245:    is row-oriented.

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

5249:    Input Parameters:
5250: +  mat - the matrix
5251: .  option - the option, one of those listed below (and possibly others),
5252: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

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


5266:    Options For Use with MatSetValues():
5267:    Insert a logically dense subblock, which can be
5268: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

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

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

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

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

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

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

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

5322:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5323:    searches during matrix assembly. When this flag is set, the hash table
5324:    is created during the first Matrix Assembly. This hash table is
5325:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5326:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5327:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5328:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5346:    Level: intermediate

5348:    Concepts: matrices^setting options

5350: .seealso:  MatOption, Mat

5352: @*/
5353: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5354: {

5360:   if (op > 0) {
5363:   }

5365:   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);
5366:   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()");

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

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

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

5425:    Input Parameters:
5426: +  mat - the matrix
5427: -  option - the option, this only responds to certain options, check the code for which ones

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

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

5434:    Level: intermediate

5436:    Concepts: matrices^setting options

5438: .seealso:  MatOption, MatSetOption()

5440: @*/
5441: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5442: {

5447:   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);
5448:   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()");

5450:   switch (op) {
5451:   case MAT_NO_OFF_PROC_ENTRIES:
5452:     *flg = mat->nooffprocentries;
5453:     break;
5454:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5455:     *flg = mat->nooffproczerorows;
5456:     break;
5457:   case MAT_SYMMETRIC:
5458:     *flg = mat->symmetric;
5459:     break;
5460:   case MAT_HERMITIAN:
5461:     *flg = mat->hermitian;
5462:     break;
5463:   case MAT_STRUCTURALLY_SYMMETRIC:
5464:     *flg = mat->structurally_symmetric;
5465:     break;
5466:   case MAT_SYMMETRY_ETERNAL:
5467:     *flg = mat->symmetric_eternal;
5468:     break;
5469:   default:
5470:     break;
5471:   }
5472:   return(0);
5473: }

5477: /*@
5478:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5479:    this routine retains the old nonzero structure.

5481:    Logically Collective on Mat

5483:    Input Parameters:
5484: .  mat - the matrix

5486:    Level: intermediate

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

5491:    Concepts: matrices^zeroing

5493: .seealso: MatZeroRows()
5494: @*/
5495: PetscErrorCode MatZeroEntries(Mat mat)
5496: {

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

5507:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5508:   (*mat->ops->zeroentries)(mat);
5509:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5510:   PetscObjectStateIncrease((PetscObject)mat);
5511: #if defined(PETSC_HAVE_CUSP)
5512:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5513:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5514:   }
5515: #elif defined(PETSC_HAVE_VIENNACL)
5516:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5517:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5518:   }
5519: #elif defined(PETSC_HAVE_VECCUDA)
5520:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5521:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5522:   }
5523: #endif
5524:   return(0);
5525: }

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

5533:    Collective on Mat

5535:    Input Parameters:
5536: +  mat - the matrix
5537: .  numRows - the number of rows to remove
5538: .  rows - the global row indices
5539: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5540: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5541: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5560:    Level: intermediate

5562:    Concepts: matrices^zeroing rows

5564: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5565: @*/
5566: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5567: {

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

5579:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5580:   MatViewFromOptions(mat,NULL,"-mat_view");
5581:   PetscObjectStateIncrease((PetscObject)mat);
5582: #if defined(PETSC_HAVE_CUSP)
5583:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5584:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5585:   }
5586: #elif defined(PETSC_HAVE_VIENNACL)
5587:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5588:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5589:   }
5590: #elif defined(PETSC_HAVE_VECCUDA)
5591:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5592:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5593:   }
5594: #endif
5595:   return(0);
5596: }

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

5604:    Collective on Mat

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

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

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

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

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

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

5630:    Level: intermediate

5632:    Concepts: matrices^zeroing rows

5634: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5635: @*/
5636: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5637: {
5639:   PetscInt       numRows;
5640:   const PetscInt *rows;

5647:   ISGetLocalSize(is,&numRows);
5648:   ISGetIndices(is,&rows);
5649:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5650:   ISRestoreIndices(is,&rows);
5651:   return(0);
5652: }

5656: /*@C
5657:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5658:    of a set of rows of a matrix.

5660:    Collective on Mat

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

5670:    Notes:
5671:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5672:    but does not release memory.  For the dense and block diagonal
5673:    formats this does not alter the nonzero structure.

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

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

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

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

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

5694:    Level: intermediate

5696:    Concepts: matrices^zeroing rows

5698: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5699: @*/
5700: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5701: {

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

5713:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5714:   MatViewFromOptions(mat,NULL,"-mat_view");
5715:   PetscObjectStateIncrease((PetscObject)mat);
5716: #if defined(PETSC_HAVE_CUSP)
5717:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5718:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5719:   }
5720: #elif defined(PETSC_HAVE_VIENNACL)
5721:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5722:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5723:   }
5724: #elif defined(PETSC_HAVE_VECCUDA)
5725:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5726:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5727:   }
5728: #endif
5729:   return(0);
5730: }

5734: /*@C
5735:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5736:    of a set of rows of a matrix.

5738:    Collective on Mat

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

5747:    Notes:
5748:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5749:    but does not release memory.  For the dense and block diagonal
5750:    formats this does not alter the nonzero structure.

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

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

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

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

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

5771:    Level: intermediate

5773:    Concepts: matrices^zeroing rows

5775: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5776: @*/
5777: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5778: {
5779:   PetscInt       numRows;
5780:   const PetscInt *rows;

5787:   ISGetLocalSize(is,&numRows);
5788:   ISGetIndices(is,&rows);
5789:   MatZeroRows(mat,numRows,rows,diag,x,b);
5790:   ISRestoreIndices(is,&rows);
5791:   return(0);
5792: }

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

5800:    Collective on Mat

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

5810:    Notes:
5811:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5812:    but does not release memory.  For the dense and block diagonal
5813:    formats this does not alter the nonzero structure.

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

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

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

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

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

5833:    In Fortran idxm and idxn should be declared as
5834: $     MatStencil idxm(4,m)
5835:    and the values inserted using
5836: $    idxm(MatStencil_i,1) = i
5837: $    idxm(MatStencil_j,1) = j
5838: $    idxm(MatStencil_k,1) = k
5839: $    idxm(MatStencil_c,1) = c
5840:    etc

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

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

5850:    Level: intermediate

5852:    Concepts: matrices^zeroing rows

5854: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5855: @*/
5856: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5857: {
5858:   PetscInt       dim     = mat->stencil.dim;
5859:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5860:   PetscInt       *dims   = mat->stencil.dims+1;
5861:   PetscInt       *starts = mat->stencil.starts;
5862:   PetscInt       *dxm    = (PetscInt*) rows;
5863:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


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

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

5902:    Collective on Mat

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

5912:    Notes:
5913:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5914:    but does not release memory.  For the dense and block diagonal
5915:    formats this does not alter the nonzero structure.

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

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

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

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

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

5935:    In Fortran idxm and idxn should be declared as
5936: $     MatStencil idxm(4,m)
5937:    and the values inserted using
5938: $    idxm(MatStencil_i,1) = i
5939: $    idxm(MatStencil_j,1) = j
5940: $    idxm(MatStencil_k,1) = k
5941: $    idxm(MatStencil_c,1) = c
5942:    etc

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

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

5952:    Level: intermediate

5954:    Concepts: matrices^zeroing rows

5956: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5957: @*/
5958: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5959: {
5960:   PetscInt       dim     = mat->stencil.dim;
5961:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5962:   PetscInt       *dims   = mat->stencil.dims+1;
5963:   PetscInt       *starts = mat->stencil.starts;
5964:   PetscInt       *dxm    = (PetscInt*) rows;
5965:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5973:   PetscMalloc1(numRows, &jdxm);
5974:   for (i = 0; i < numRows; ++i) {
5975:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5976:     for (j = 0; j < 3-sdim; ++j) dxm++;
5977:     /* Local index in X dir */
5978:     tmp = *dxm++ - starts[0];
5979:     /* Loop over remaining dimensions */
5980:     for (j = 0; j < dim-1; ++j) {
5981:       /* If nonlocal, set index to be negative */
5982:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5983:       /* Update local index */
5984:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5985:     }
5986:     /* Skip component slot if necessary */
5987:     if (mat->stencil.noc) dxm++;
5988:     /* Local row number */
5989:     if (tmp >= 0) {
5990:       jdxm[numNewRows++] = tmp;
5991:     }
5992:   }
5993:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5994:   PetscFree(jdxm);
5995:   return(0);
5996: }

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

6004:    Collective on Mat

6006:    Input Parameters:
6007: +  mat - the matrix
6008: .  numRows - the number of rows to remove
6009: .  rows - the global row indices
6010: .  diag - value put in all diagonals of eliminated rows
6011: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6012: -  b - optional vector of right hand side, that will be adjusted by provided solution

6014:    Notes:
6015:    Before calling MatZeroRowsLocal(), the user must first set the
6016:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6018:    For the AIJ matrix formats this removes the old nonzero structure,
6019:    but does not release memory.  For the dense and block diagonal
6020:    formats this does not alter the nonzero structure.

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

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

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

6033:    Level: intermediate

6035:    Concepts: matrices^zeroing

6037: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6038: @*/
6039: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6040: {

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

6051:   if (mat->ops->zerorowslocal) {
6052:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6053:   } else {
6054:     IS             is, newis;
6055:     const PetscInt *newRows;

6057:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6058:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6059:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6060:     ISGetIndices(newis,&newRows);
6061:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6062:     ISRestoreIndices(newis,&newRows);
6063:     ISDestroy(&newis);
6064:     ISDestroy(&is);
6065:   }
6066:   PetscObjectStateIncrease((PetscObject)mat);
6067: #if defined(PETSC_HAVE_CUSP)
6068:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6069:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6070:   }
6071: #elif defined(PETSC_HAVE_VIENNACL)
6072:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6073:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6074:   }
6075: #elif defined(PETSC_HAVE_VECCUDA)
6076:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6077:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6078:   }
6079: #endif
6080:   return(0);
6081: }

6085: /*@C
6086:    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6087:    of a set of rows of a matrix; using local numbering of rows.

6089:    Collective on Mat

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

6098:    Notes:
6099:    Before calling MatZeroRowsLocalIS(), the user must first set the
6100:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6102:    For the AIJ matrix formats this removes the old nonzero structure,
6103:    but does not release memory.  For the dense and block diagonal
6104:    formats this does not alter the nonzero structure.

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

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

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

6117:    Level: intermediate

6119:    Concepts: matrices^zeroing

6121: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6122: @*/
6123: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6124: {
6126:   PetscInt       numRows;
6127:   const PetscInt *rows;

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

6137:   ISGetLocalSize(is,&numRows);
6138:   ISGetIndices(is,&rows);
6139:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6140:   ISRestoreIndices(is,&rows);
6141:   return(0);
6142: }

6146: /*@C
6147:    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6148:    of a set of rows and columns of a matrix; using local numbering of rows.

6150:    Collective on Mat

6152:    Input Parameters:
6153: +  mat - the matrix
6154: .  numRows - the number of rows to remove
6155: .  rows - the global row indices
6156: .  diag - value put in all diagonals of eliminated rows
6157: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6158: -  b - optional vector of right hand side, that will be adjusted by provided solution

6160:    Notes:
6161:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6162:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6168:    Level: intermediate

6170:    Concepts: matrices^zeroing

6172: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6173: @*/
6174: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6175: {
6177:   IS             is, newis;
6178:   const PetscInt *newRows;

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

6188:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6189:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6190:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6191:   ISGetIndices(newis,&newRows);
6192:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6193:   ISRestoreIndices(newis,&newRows);
6194:   ISDestroy(&newis);
6195:   ISDestroy(&is);
6196:   PetscObjectStateIncrease((PetscObject)mat);
6197: #if defined(PETSC_HAVE_CUSP)
6198:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6199:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6200:   }
6201: #elif defined(PETSC_HAVE_VIENNACL)
6202:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6203:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6204:   }
6205: #elif defined(PETSC_HAVE_VECCUDA)
6206:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6207:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6208:   }
6209: #endif
6210:   return(0);
6211: }

6215: /*@C
6216:    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6217:    of a set of rows and columns of a matrix; using local numbering of rows.

6219:    Collective on Mat

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

6228:    Notes:
6229:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6230:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6236:    Level: intermediate

6238:    Concepts: matrices^zeroing

6240: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6241: @*/
6242: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6243: {
6245:   PetscInt       numRows;
6246:   const PetscInt *rows;

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

6256:   ISGetLocalSize(is,&numRows);
6257:   ISGetIndices(is,&rows);
6258:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6259:   ISRestoreIndices(is,&rows);
6260:   return(0);
6261: }

6265: /*@
6266:    MatGetSize - Returns the numbers of rows and columns in a matrix.

6268:    Not Collective

6270:    Input Parameter:
6271: .  mat - the matrix

6273:    Output Parameters:
6274: +  m - the number of global rows
6275: -  n - the number of global columns

6277:    Note: both output parameters can be NULL on input.

6279:    Level: beginner

6281:    Concepts: matrices^size

6283: .seealso: MatGetLocalSize()
6284: @*/
6285: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6286: {
6289:   if (m) *m = mat->rmap->N;
6290:   if (n) *n = mat->cmap->N;
6291:   return(0);
6292: }

6296: /*@
6297:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6298:    stored locally.  This information may be implementation dependent, so
6299:    use with care.

6301:    Not Collective

6303:    Input Parameters:
6304: .  mat - the matrix

6306:    Output Parameters:
6307: +  m - the number of local rows
6308: -  n - the number of local columns

6310:    Note: both output parameters can be NULL on input.

6312:    Level: beginner

6314:    Concepts: matrices^local size

6316: .seealso: MatGetSize()
6317: @*/
6318: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6319: {
6324:   if (m) *m = mat->rmap->n;
6325:   if (n) *n = mat->cmap->n;
6326:   return(0);
6327: }

6331: /*@
6332:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6333:    this processor. (The columns of the "diagonal block")

6335:    Not Collective, unless matrix has not been allocated, then collective on Mat

6337:    Input Parameters:
6338: .  mat - the matrix

6340:    Output Parameters:
6341: +  m - the global index of the first local column
6342: -  n - one more than the global index of the last local column

6344:    Notes: both output parameters can be NULL on input.

6346:    Level: developer

6348:    Concepts: matrices^column ownership

6350: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

6352: @*/
6353: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6354: {
6360:   MatCheckPreallocated(mat,1);
6361:   if (m) *m = mat->cmap->rstart;
6362:   if (n) *n = mat->cmap->rend;
6363:   return(0);
6364: }

6368: /*@
6369:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6370:    this processor, assuming that the matrix is laid out with the first
6371:    n1 rows on the first processor, the next n2 rows on the second, etc.
6372:    For certain parallel layouts this range may not be well defined.

6374:    Not Collective

6376:    Input Parameters:
6377: .  mat - the matrix

6379:    Output Parameters:
6380: +  m - the global index of the first local row
6381: -  n - one more than the global index of the last local row

6383:    Note: Both output parameters can be NULL on input.
6384: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6385: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6386: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

6388:    Level: beginner

6390:    Concepts: matrices^row ownership

6392: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

6394: @*/
6395: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6396: {
6402:   MatCheckPreallocated(mat,1);
6403:   if (m) *m = mat->rmap->rstart;
6404:   if (n) *n = mat->rmap->rend;
6405:   return(0);
6406: }

6410: /*@C
6411:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6412:    each process

6414:    Not Collective, unless matrix has not been allocated, then collective on Mat

6416:    Input Parameters:
6417: .  mat - the matrix

6419:    Output Parameters:
6420: .  ranges - start of each processors portion plus one more than the total length at the end

6422:    Level: beginner

6424:    Concepts: matrices^row ownership

6426: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6428: @*/
6429: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6430: {

6436:   MatCheckPreallocated(mat,1);
6437:   PetscLayoutGetRanges(mat->rmap,ranges);
6438:   return(0);
6439: }

6443: /*@C
6444:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6445:    this processor. (The columns of the "diagonal blocks" for each process)

6447:    Not Collective, unless matrix has not been allocated, then collective on Mat

6449:    Input Parameters:
6450: .  mat - the matrix

6452:    Output Parameters:
6453: .  ranges - start of each processors portion plus one more then the total length at the end

6455:    Level: beginner

6457:    Concepts: matrices^column ownership

6459: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6461: @*/
6462: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6463: {

6469:   MatCheckPreallocated(mat,1);
6470:   PetscLayoutGetRanges(mat->cmap,ranges);
6471:   return(0);
6472: }

6476: /*@C
6477:    MatGetOwnershipIS - Get row and column ownership as index sets

6479:    Not Collective

6481:    Input Arguments:
6482: .  A - matrix of type Elemental

6484:    Output Arguments:
6485: +  rows - rows in which this process owns elements
6486: .  cols - columns in which this process owns elements

6488:    Level: intermediate

6490: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6491: @*/
6492: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6493: {
6494:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6497:   MatCheckPreallocated(A,1);
6498:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6499:   if (f) {
6500:     (*f)(A,rows,cols);
6501:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6502:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6503:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6504:   }
6505:   return(0);
6506: }

6510: /*@C
6511:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6512:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6513:    to complete the factorization.

6515:    Collective on Mat

6517:    Input Parameters:
6518: +  mat - the matrix
6519: .  row - row permutation
6520: .  column - column permutation
6521: -  info - structure containing
6522: $      levels - number of levels of fill.
6523: $      expected fill - as ratio of original fill.
6524: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6525:                 missing diagonal entries)

6527:    Output Parameters:
6528: .  fact - new matrix that has been symbolically factored

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

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

6536:    Level: developer

6538:   Concepts: matrices^symbolic LU factorization
6539:   Concepts: matrices^factorization
6540:   Concepts: LU^symbolic factorization

6542: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6543:           MatGetOrdering(), MatFactorInfo

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

6548: @*/
6549: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6550: {

6560:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6561:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6562:   if (!(fact)->ops->ilufactorsymbolic) {
6563:     const MatSolverPackage spackage;
6564:     MatFactorGetSolverPackage(fact,&spackage);
6565:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6566:   }
6567:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6568:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6569:   MatCheckPreallocated(mat,2);

6571:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6572:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6573:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6574:   return(0);
6575: }

6579: /*@C
6580:    MatICCFactorSymbolic - Performs symbolic incomplete
6581:    Cholesky factorization for a symmetric matrix.  Use
6582:    MatCholeskyFactorNumeric() to complete the factorization.

6584:    Collective on Mat

6586:    Input Parameters:
6587: +  mat - the matrix
6588: .  perm - row and column permutation
6589: -  info - structure containing
6590: $      levels - number of levels of fill.
6591: $      expected fill - as ratio of original fill.

6593:    Output Parameter:
6594: .  fact - the factored matrix

6596:    Notes:
6597:    Most users should employ the KSP interface for linear solvers
6598:    instead of working directly with matrix algebra routines such as this.
6599:    See, e.g., KSPCreate().

6601:    Level: developer

6603:   Concepts: matrices^symbolic incomplete Cholesky factorization
6604:   Concepts: matrices^factorization
6605:   Concepts: Cholsky^symbolic factorization

6607: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

6612: @*/
6613: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6614: {

6623:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6624:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6625:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6626:   if (!(fact)->ops->iccfactorsymbolic) {
6627:     const MatSolverPackage spackage;
6628:     MatFactorGetSolverPackage(fact,&spackage);
6629:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6630:   }
6631:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6632:   MatCheckPreallocated(mat,2);

6634:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6635:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6636:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6637:   return(0);
6638: }

6642: /*@C
6643:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6644:    points to an array of valid matrices, they may be reused to store the new
6645:    submatrices.

6647:    Collective on Mat

6649:    Input Parameters:
6650: +  mat - the matrix
6651: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6652: .  irow, icol - index sets of rows and columns to extract
6653: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6655:    Output Parameter:
6656: .  submat - the array of submatrices

6658:    Notes:
6659:    MatGetSubMatrices() can extract ONLY sequential submatrices
6660:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6661:    to extract a parallel submatrix.

6663:    Some matrix types place restrictions on the row and column
6664:    indices, such as that they be sorted or that they be equal to each other.

6666:    The index sets may not have duplicate entries.

6668:    When extracting submatrices from a parallel matrix, each processor can
6669:    form a different submatrix by setting the rows and columns of its
6670:    individual index sets according to the local submatrix desired.

6672:    When finished using the submatrices, the user should destroy
6673:    them with MatDestroyMatrices().

6675:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6676:    original matrix has not changed from that last call to MatGetSubMatrices().

6678:    This routine creates the matrices in submat; you should NOT create them before
6679:    calling it. It also allocates the array of matrix pointers submat.

6681:    For BAIJ matrices the index sets must respect the block structure, that is if they
6682:    request one row/column in a block, they must request all rows/columns that are in
6683:    that block. For example, if the block size is 2 you cannot request just row 0 and
6684:    column 0.

6686:    Fortran Note:
6687:    The Fortran interface is slightly different from that given below; it
6688:    requires one to pass in  as submat a Mat (integer) array of size at least m.

6690:    Level: advanced

6692:    Concepts: matrices^accessing submatrices
6693:    Concepts: submatrices

6695: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6696: @*/
6697: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6698: {
6700:   PetscInt       i;
6701:   PetscBool      eq;

6706:   if (n) {
6711:   }
6713:   if (n && scall == MAT_REUSE_MATRIX) {
6716:   }
6717:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6718:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6719:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6720:   MatCheckPreallocated(mat,1);

6722:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6723:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6724:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6725:   for (i=0; i<n; i++) {
6726:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6727:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6728:       ISEqual(irow[i],icol[i],&eq);
6729:       if (eq) {
6730:         if (mat->symmetric) {
6731:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6732:         } else if (mat->hermitian) {
6733:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6734:         } else if (mat->structurally_symmetric) {
6735:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6736:         }
6737:       }
6738:     }
6739:   }
6740:   return(0);
6741: }

6745: PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6746: {
6748:   PetscInt       i;
6749:   PetscBool      eq;

6754:   if (n) {
6759:   }
6761:   if (n && scall == MAT_REUSE_MATRIX) {
6764:   }
6765:   if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6766:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6767:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6768:   MatCheckPreallocated(mat,1);

6770:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6771:   (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6772:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6773:   for (i=0; i<n; i++) {
6774:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6775:       ISEqual(irow[i],icol[i],&eq);
6776:       if (eq) {
6777:         if (mat->symmetric) {
6778:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6779:         } else if (mat->hermitian) {
6780:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6781:         } else if (mat->structurally_symmetric) {
6782:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6783:         }
6784:       }
6785:     }
6786:   }
6787:   return(0);
6788: }

6792: /*@C
6793:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().

6795:    Collective on Mat

6797:    Input Parameters:
6798: +  n - the number of local matrices
6799: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6800:                        sequence of MatGetSubMatrices())

6802:    Level: advanced

6804:     Notes: Frees not only the matrices, but also the array that contains the matrices
6805:            In Fortran will not free the array.

6807: .seealso: MatGetSubMatrices()
6808: @*/
6809: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6810: {
6812:   PetscInt       i;

6815:   if (!*mat) return(0);
6816:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6818:   for (i=0; i<n; i++) {
6819:     MatDestroy(&(*mat)[i]);
6820:   }
6821:   /* memory is allocated even if n = 0 */
6822:   PetscFree(*mat);
6823:   *mat = NULL;
6824:   return(0);
6825: }

6829: /*@C
6830:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.

6832:    Collective on Mat

6834:    Input Parameters:
6835: .  mat - the matrix

6837:    Output Parameter:
6838: .  matstruct - the sequential matrix with the nonzero structure of mat

6840:   Level: intermediate

6842: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6843: @*/
6844: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6845: {


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

6856:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6857:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6858:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6859:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6860:   return(0);
6861: }

6865: /*@C
6866:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6868:    Collective on Mat

6870:    Input Parameters:
6871: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6872:                        sequence of MatGetSequentialNonzeroStructure())

6874:    Level: advanced

6876:     Notes: Frees not only the matrices, but also the array that contains the matrices

6878: .seealso: MatGetSeqNonzeroStructure()
6879: @*/
6880: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6881: {

6886:   MatDestroy(mat);
6887:   return(0);
6888: }

6892: /*@
6893:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6894:    replaces the index sets by larger ones that represent submatrices with
6895:    additional overlap.

6897:    Collective on Mat

6899:    Input Parameters:
6900: +  mat - the matrix
6901: .  n   - the number of index sets
6902: .  is  - the array of index sets (these index sets will changed during the call)
6903: -  ov  - the additional overlap requested

6905:    Options Database:
6906: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

6908:    Level: developer

6910:    Concepts: overlap
6911:    Concepts: ASM^computing overlap

6913: .seealso: MatGetSubMatrices()
6914: @*/
6915: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6916: {

6922:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6923:   if (n) {
6926:   }
6927:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6928:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6929:   MatCheckPreallocated(mat,1);

6931:   if (!ov) return(0);
6932:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6933:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6934:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6935:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6936:   return(0);
6937: }


6940: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);

6944: /*@
6945:    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6946:    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6947:    additional overlap.

6949:    Collective on Mat

6951:    Input Parameters:
6952: +  mat - the matrix
6953: .  n   - the number of index sets
6954: .  is  - the array of index sets (these index sets will changed during the call)
6955: -  ov  - the additional overlap requested

6957:    Options Database:
6958: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

6960:    Level: developer

6962:    Concepts: overlap
6963:    Concepts: ASM^computing overlap

6965: .seealso: MatGetSubMatrices()
6966: @*/
6967: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6968: {
6969:   PetscInt       i;

6975:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6976:   if (n) {
6979:   }
6980:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6981:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6982:   MatCheckPreallocated(mat,1);
6983:   if (!ov) return(0);
6984:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6985:   for(i=0; i<n; i++){
6986:          MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
6987:   }
6988:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6989:   return(0);
6990: }




6997: /*@
6998:    MatGetBlockSize - Returns the matrix block size.

7000:    Not Collective

7002:    Input Parameter:
7003: .  mat - the matrix

7005:    Output Parameter:
7006: .  bs - block size

7008:    Notes:
7009:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

7011:    If the block size has not been set yet this routine returns 1.

7013:    Level: intermediate

7015:    Concepts: matrices^block size

7017: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7018: @*/
7019: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7020: {
7024:   *bs = PetscAbs(mat->rmap->bs);
7025:   return(0);
7026: }

7030: /*@
7031:    MatGetBlockSizes - Returns the matrix block row and column sizes.

7033:    Not Collective

7035:    Input Parameter:
7036: .  mat - the matrix

7038:    Output Parameter:
7039: .  rbs - row block size
7040: .  cbs - coumn block size

7042:    Notes:
7043:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7044:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

7046:    If a block size has not been set yet this routine returns 1.

7048:    Level: intermediate

7050:    Concepts: matrices^block size

7052: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7053: @*/
7054: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7055: {
7060:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7061:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7062:   return(0);
7063: }

7067: /*@
7068:    MatSetBlockSize - Sets the matrix block size.

7070:    Logically Collective on Mat

7072:    Input Parameters:
7073: +  mat - the matrix
7074: -  bs - block size

7076:    Notes:
7077:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

7079:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

7081:    Level: intermediate

7083:    Concepts: matrices^block size

7085: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7086: @*/
7087: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7088: {

7094:   PetscLayoutSetBlockSize(mat->rmap,bs);
7095:   PetscLayoutSetBlockSize(mat->cmap,bs);
7096:   return(0);
7097: }

7101: /*@
7102:    MatSetBlockSizes - Sets the matrix block row and column sizes.

7104:    Logically Collective on Mat

7106:    Input Parameters:
7107: +  mat - the matrix
7108: -  rbs - row block size
7109: -  cbs - column block size

7111:    Notes:
7112:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7113:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

7115:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

7117:     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().

7119:    Level: intermediate

7121:    Concepts: matrices^block size

7123: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7124: @*/
7125: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7126: {

7133:   PetscLayoutSetBlockSize(mat->rmap,rbs);
7134:   PetscLayoutSetBlockSize(mat->cmap,cbs);
7135:   return(0);
7136: }

7140: /*@
7141:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

7143:    Logically Collective on Mat

7145:    Input Parameters:
7146: +  mat - the matrix
7147: .  fromRow - matrix from which to copy row block size
7148: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

7150:    Level: developer

7152:    Concepts: matrices^block size

7154: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7155: @*/
7156: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7157: {

7164:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7165:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7166:   return(0);
7167: }

7171: /*@
7172:    MatResidual - Default routine to calculate the residual.

7174:    Collective on Mat and Vec

7176:    Input Parameters:
7177: +  mat - the matrix
7178: .  b   - the right-hand-side
7179: -  x   - the approximate solution

7181:    Output Parameter:
7182: .  r - location to store the residual

7184:    Level: developer

7186: .keywords: MG, default, multigrid, residual

7188: .seealso: PCMGSetResidual()
7189: @*/
7190: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7191: {

7200:   MatCheckPreallocated(mat,1);
7201:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7202:   if (!mat->ops->residual) {
7203:     MatMult(mat,x,r);
7204:     VecAYPX(r,-1.0,b);
7205:   } else {
7206:     (*mat->ops->residual)(mat,b,x,r);
7207:   }
7208:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7209:   return(0);
7210: }

7214: /*@C
7215:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.

7217:    Collective on Mat

7219:     Input Parameters:
7220: +   mat - the matrix
7221: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7222: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7223: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7224:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7225:                  always used.

7227:     Output Parameters:
7228: +   n - number of rows in the (possibly compressed) matrix
7229: .   ia - the row pointers [of length n+1]
7230: .   ja - the column indices
7231: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7232:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

7234:     Level: developer

7236:     Notes: You CANNOT change any of the ia[] or ja[] values.

7238:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

7240:     Fortran Node

7242:            In Fortran use
7243: $           PetscInt ia(1), ja(1)
7244: $           PetscOffset iia, jja
7245: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7246: $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7247: $
7248: $          or
7249: $
7250: $           PetscInt, pointer :: ia(:),ja(:)
7251: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7252: $      Acess the ith and jth entries via ia(i) and ja(j)



7256: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7257: @*/
7258: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7259: {

7269:   MatCheckPreallocated(mat,1);
7270:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7271:   else {
7272:     *done = PETSC_TRUE;
7273:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7274:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7275:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7276:   }
7277:   return(0);
7278: }

7282: /*@C
7283:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.

7285:     Collective on Mat

7287:     Input Parameters:
7288: +   mat - the matrix
7289: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7290: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7291:                 symmetrized
7292: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7293:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7294:                  always used.
7295: .   n - number of columns in the (possibly compressed) matrix
7296: .   ia - the column pointers
7297: -   ja - the row indices

7299:     Output Parameters:
7300: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

7302:     Note:
7303:     This routine zeros out n, ia, and ja. This is to prevent accidental
7304:     us of the array after it has been restored. If you pass NULL, it will
7305:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

7307:     Level: developer

7309: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7310: @*/
7311: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7312: {

7322:   MatCheckPreallocated(mat,1);
7323:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7324:   else {
7325:     *done = PETSC_TRUE;
7326:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7327:   }
7328:   return(0);
7329: }

7333: /*@C
7334:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7335:     MatGetRowIJ().

7337:     Collective on Mat

7339:     Input Parameters:
7340: +   mat - the matrix
7341: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7342: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7343:                 symmetrized
7344: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7345:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7346:                  always used.
7347: .   n - size of (possibly compressed) matrix
7348: .   ia - the row pointers
7349: -   ja - the column indices

7351:     Output Parameters:
7352: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7354:     Note:
7355:     This routine zeros out n, ia, and ja. This is to prevent accidental
7356:     us of the array after it has been restored. If you pass NULL, it will
7357:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

7359:     Level: developer

7361: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7362: @*/
7363: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7364: {

7373:   MatCheckPreallocated(mat,1);

7375:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7376:   else {
7377:     *done = PETSC_TRUE;
7378:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7379:     if (n)  *n = 0;
7380:     if (ia) *ia = NULL;
7381:     if (ja) *ja = NULL;
7382:   }
7383:   return(0);
7384: }

7388: /*@C
7389:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7390:     MatGetColumnIJ().

7392:     Collective on Mat

7394:     Input Parameters:
7395: +   mat - the matrix
7396: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7397: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7398:                 symmetrized
7399: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7400:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7401:                  always used.

7403:     Output Parameters:
7404: +   n - size of (possibly compressed) matrix
7405: .   ia - the column pointers
7406: .   ja - the row indices
7407: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7409:     Level: developer

7411: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7412: @*/
7413: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7414: {

7423:   MatCheckPreallocated(mat,1);

7425:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7426:   else {
7427:     *done = PETSC_TRUE;
7428:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7429:     if (n)  *n = 0;
7430:     if (ia) *ia = NULL;
7431:     if (ja) *ja = NULL;
7432:   }
7433:   return(0);
7434: }

7438: /*@C
7439:     MatColoringPatch -Used inside matrix coloring routines that
7440:     use MatGetRowIJ() and/or MatGetColumnIJ().

7442:     Collective on Mat

7444:     Input Parameters:
7445: +   mat - the matrix
7446: .   ncolors - max color value
7447: .   n   - number of entries in colorarray
7448: -   colorarray - array indicating color for each column

7450:     Output Parameters:
7451: .   iscoloring - coloring generated using colorarray information

7453:     Level: developer

7455: .seealso: MatGetRowIJ(), MatGetColumnIJ()

7457: @*/
7458: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7459: {

7467:   MatCheckPreallocated(mat,1);

7469:   if (!mat->ops->coloringpatch) {
7470:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7471:   } else {
7472:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7473:   }
7474:   return(0);
7475: }


7480: /*@
7481:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.

7483:    Logically Collective on Mat

7485:    Input Parameter:
7486: .  mat - the factored matrix to be reset

7488:    Notes:
7489:    This routine should be used only with factored matrices formed by in-place
7490:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7491:    format).  This option can save memory, for example, when solving nonlinear
7492:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7493:    ILU(0) preconditioner.

7495:    Note that one can specify in-place ILU(0) factorization by calling
7496: .vb
7497:      PCType(pc,PCILU);
7498:      PCFactorSeUseInPlace(pc);
7499: .ve
7500:    or by using the options -pc_type ilu -pc_factor_in_place

7502:    In-place factorization ILU(0) can also be used as a local
7503:    solver for the blocks within the block Jacobi or additive Schwarz
7504:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7505:    for details on setting local solver options.

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

7511:    Level: developer

7513: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()

7515:    Concepts: matrices^unfactored

7517: @*/
7518: PetscErrorCode MatSetUnfactored(Mat mat)
7519: {

7525:   MatCheckPreallocated(mat,1);
7526:   mat->factortype = MAT_FACTOR_NONE;
7527:   if (!mat->ops->setunfactored) return(0);
7528:   (*mat->ops->setunfactored)(mat);
7529:   return(0);
7530: }

7532: /*MC
7533:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7535:     Synopsis:
7536:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7538:     Not collective

7540:     Input Parameter:
7541: .   x - matrix

7543:     Output Parameters:
7544: +   xx_v - the Fortran90 pointer to the array
7545: -   ierr - error code

7547:     Example of Usage:
7548: .vb
7549:       PetscScalar, pointer xx_v(:,:)
7550:       ....
7551:       call MatDenseGetArrayF90(x,xx_v,ierr)
7552:       a = xx_v(3)
7553:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7554: .ve

7556:     Level: advanced

7558: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()

7560:     Concepts: matrices^accessing array

7562: M*/

7564: /*MC
7565:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7566:     accessed with MatDenseGetArrayF90().

7568:     Synopsis:
7569:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7571:     Not collective

7573:     Input Parameters:
7574: +   x - matrix
7575: -   xx_v - the Fortran90 pointer to the array

7577:     Output Parameter:
7578: .   ierr - error code

7580:     Example of Usage:
7581: .vb
7582:        PetscScalar, pointer xx_v(:,:)
7583:        ....
7584:        call MatDenseGetArrayF90(x,xx_v,ierr)
7585:        a = xx_v(3)
7586:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7587: .ve

7589:     Level: advanced

7591: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()

7593: M*/


7596: /*MC
7597:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7599:     Synopsis:
7600:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7602:     Not collective

7604:     Input Parameter:
7605: .   x - matrix

7607:     Output Parameters:
7608: +   xx_v - the Fortran90 pointer to the array
7609: -   ierr - error code

7611:     Example of Usage:
7612: .vb
7613:       PetscScalar, pointer xx_v(:)
7614:       ....
7615:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7616:       a = xx_v(3)
7617:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7618: .ve

7620:     Level: advanced

7622: .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()

7624:     Concepts: matrices^accessing array

7626: M*/

7628: /*MC
7629:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7630:     accessed with MatSeqAIJGetArrayF90().

7632:     Synopsis:
7633:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7635:     Not collective

7637:     Input Parameters:
7638: +   x - matrix
7639: -   xx_v - the Fortran90 pointer to the array

7641:     Output Parameter:
7642: .   ierr - error code

7644:     Example of Usage:
7645: .vb
7646:        PetscScalar, pointer xx_v(:)
7647:        ....
7648:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7649:        a = xx_v(3)
7650:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7651: .ve

7653:     Level: advanced

7655: .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()

7657: M*/


7662: /*@
7663:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7664:                       as the original matrix.

7666:     Collective on Mat

7668:     Input Parameters:
7669: +   mat - the original matrix
7670: .   isrow - parallel IS containing the rows this processor should obtain
7671: .   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.
7672: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7674:     Output Parameter:
7675: .   newmat - the new submatrix, of the same type as the old

7677:     Level: advanced

7679:     Notes:
7680:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7682:     Some matrix types place restrictions on the row and column indices, such
7683:     as that they be sorted or that they be equal to each other.

7685:     The index sets may not have duplicate entries.

7687:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7688:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7689:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7690:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7691:    you are finished using it.

7693:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7694:     the input matrix.

7696:     If iscol is NULL then all columns are obtained (not supported in Fortran).

7698:    Example usage:
7699:    Consider the following 8x8 matrix with 34 non-zero values, that is
7700:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7701:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7702:    as follows:

7704: .vb
7705:             1  2  0  |  0  3  0  |  0  4
7706:     Proc0   0  5  6  |  7  0  0  |  8  0
7707:             9  0 10  | 11  0  0  | 12  0
7708:     -------------------------------------
7709:            13  0 14  | 15 16 17  |  0  0
7710:     Proc1   0 18  0  | 19 20 21  |  0  0
7711:             0  0  0  | 22 23  0  | 24  0
7712:     -------------------------------------
7713:     Proc2  25 26 27  |  0  0 28  | 29  0
7714:            30  0  0  | 31 32 33  |  0 34
7715: .ve

7717:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7719: .vb
7720:             2  0  |  0  3  0  |  0
7721:     Proc0   5  6  |  7  0  0  |  8
7722:     -------------------------------
7723:     Proc1  18  0  | 19 20 21  |  0
7724:     -------------------------------
7725:     Proc2  26 27  |  0  0 28  | 29
7726:             0  0  | 31 32 33  |  0
7727: .ve


7730:     Concepts: matrices^submatrices

7732: .seealso: MatGetSubMatrices()
7733: @*/
7734: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7735: {
7737:   PetscMPIInt    size;
7738:   Mat            *local;
7739:   IS             iscoltmp;

7748:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7749:   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");

7751:   MatCheckPreallocated(mat,1);
7752:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7754:   if (!iscol || isrow == iscol) {
7755:     PetscBool   stride;
7756:     PetscMPIInt grabentirematrix = 0,grab;
7757:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7758:     if (stride) {
7759:       PetscInt first,step,n,rstart,rend;
7760:       ISStrideGetInfo(isrow,&first,&step);
7761:       if (step == 1) {
7762:         MatGetOwnershipRange(mat,&rstart,&rend);
7763:         if (rstart == first) {
7764:           ISGetLocalSize(isrow,&n);
7765:           if (n == rend-rstart) {
7766:             grabentirematrix = 1;
7767:           }
7768:         }
7769:       }
7770:     }
7771:     MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7772:     if (grab) {
7773:       PetscInfo(mat,"Getting entire matrix as submatrix\n");
7774:       if (cll == MAT_INITIAL_MATRIX) {
7775:         *newmat = mat;
7776:         PetscObjectReference((PetscObject)mat);
7777:       }
7778:       return(0);
7779:     }
7780:   }

7782:   if (!iscol) {
7783:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7784:   } else {
7785:     iscoltmp = iscol;
7786:   }

7788:   /* if original matrix is on just one processor then use submatrix generated */
7789:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7790:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7791:     if (!iscol) {ISDestroy(&iscoltmp);}
7792:     return(0);
7793:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7794:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7795:     *newmat = *local;
7796:     PetscFree(local);
7797:     if (!iscol) {ISDestroy(&iscoltmp);}
7798:     return(0);
7799:   } else if (!mat->ops->getsubmatrix) {
7800:     /* Create a new matrix type that implements the operation using the full matrix */
7801:     PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7802:     switch (cll) {
7803:     case MAT_INITIAL_MATRIX:
7804:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7805:       break;
7806:     case MAT_REUSE_MATRIX:
7807:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7808:       break;
7809:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7810:     }
7811:     PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7812:     if (!iscol) {ISDestroy(&iscoltmp);}
7813:     return(0);
7814:   }

7816:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7817:   PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7818:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7819:   PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7820:   if (!iscol) {ISDestroy(&iscoltmp);}
7821:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7822:   return(0);
7823: }

7827: /*@
7828:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7829:    used during the assembly process to store values that belong to
7830:    other processors.

7832:    Not Collective

7834:    Input Parameters:
7835: +  mat   - the matrix
7836: .  size  - the initial size of the stash.
7837: -  bsize - the initial size of the block-stash(if used).

7839:    Options Database Keys:
7840: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7841: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7843:    Level: intermediate

7845:    Notes:
7846:      The block-stash is used for values set with MatSetValuesBlocked() while
7847:      the stash is used for values set with MatSetValues()

7849:      Run with the option -info and look for output of the form
7850:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7851:      to determine the appropriate value, MM, to use for size and
7852:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7853:      to determine the value, BMM to use for bsize

7855:    Concepts: stash^setting matrix size
7856:    Concepts: matrices^stash

7858: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7860: @*/
7861: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7862: {

7868:   MatStashSetInitialSize_Private(&mat->stash,size);
7869:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7870:   return(0);
7871: }

7875: /*@
7876:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7877:      the matrix

7879:    Neighbor-wise Collective on Mat

7881:    Input Parameters:
7882: +  mat   - the matrix
7883: .  x,y - the vectors
7884: -  w - where the result is stored

7886:    Level: intermediate

7888:    Notes:
7889:     w may be the same vector as y.

7891:     This allows one to use either the restriction or interpolation (its transpose)
7892:     matrix to do the interpolation

7894:     Concepts: interpolation

7896: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7898: @*/
7899: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7900: {
7902:   PetscInt       M,N,Ny;

7910:   MatCheckPreallocated(A,1);
7911:   MatGetSize(A,&M,&N);
7912:   VecGetSize(y,&Ny);
7913:   if (M == Ny) {
7914:     MatMultAdd(A,x,y,w);
7915:   } else {
7916:     MatMultTransposeAdd(A,x,y,w);
7917:   }
7918:   return(0);
7919: }

7923: /*@
7924:    MatInterpolate - y = A*x or A'*x depending on the shape of
7925:      the matrix

7927:    Neighbor-wise Collective on Mat

7929:    Input Parameters:
7930: +  mat   - the matrix
7931: -  x,y - the vectors

7933:    Level: intermediate

7935:    Notes:
7936:     This allows one to use either the restriction or interpolation (its transpose)
7937:     matrix to do the interpolation

7939:    Concepts: matrices^interpolation

7941: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7943: @*/
7944: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7945: {
7947:   PetscInt       M,N,Ny;

7954:   MatCheckPreallocated(A,1);
7955:   MatGetSize(A,&M,&N);
7956:   VecGetSize(y,&Ny);
7957:   if (M == Ny) {
7958:     MatMult(A,x,y);
7959:   } else {
7960:     MatMultTranspose(A,x,y);
7961:   }
7962:   return(0);
7963: }

7967: /*@
7968:    MatRestrict - y = A*x or A'*x

7970:    Neighbor-wise Collective on Mat

7972:    Input Parameters:
7973: +  mat   - the matrix
7974: -  x,y - the vectors

7976:    Level: intermediate

7978:    Notes:
7979:     This allows one to use either the restriction or interpolation (its transpose)
7980:     matrix to do the restriction

7982:    Concepts: matrices^restriction

7984: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()

7986: @*/
7987: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7988: {
7990:   PetscInt       M,N,Ny;

7997:   MatCheckPreallocated(A,1);

7999:   MatGetSize(A,&M,&N);
8000:   VecGetSize(y,&Ny);
8001:   if (M == Ny) {
8002:     MatMult(A,x,y);
8003:   } else {
8004:     MatMultTranspose(A,x,y);
8005:   }
8006:   return(0);
8007: }

8011: /*@
8012:    MatGetNullSpace - retrieves the null space to a matrix.

8014:    Logically Collective on Mat and MatNullSpace

8016:    Input Parameters:
8017: +  mat - the matrix
8018: -  nullsp - the null space object

8020:    Level: developer

8022:    Concepts: null space^attaching to matrix

8024: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8025: @*/
8026: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8027: {
8032:   *nullsp = mat->nullsp;
8033:   return(0);
8034: }

8038: /*@
8039:    MatSetNullSpace - attaches a null space to a matrix.

8041:    Logically Collective on Mat and MatNullSpace

8043:    Input Parameters:
8044: +  mat - the matrix
8045: -  nullsp - the null space object

8047:    Level: advanced

8049:    Notes:
8050:       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached

8052:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8053:       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.

8055:       You can remove the null space by calling this routine with an nullsp of NULL


8058:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8059:    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).
8060:    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
8061:    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
8062:    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).

8064:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

8066:    Concepts: null space^attaching to matrix

8068: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8069: @*/
8070: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8071: {

8078:   MatCheckPreallocated(mat,1);
8079:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8080:   MatNullSpaceDestroy(&mat->nullsp);
8081:   mat->nullsp = nullsp;
8082:   return(0);
8083: }

8087: /*@
8088:    MatGetTransposeNullSpace - retrieves the null space to a matrix.

8090:    Logically Collective on Mat and MatNullSpace

8092:    Input Parameters:
8093: +  mat - the matrix
8094: -  nullsp - the null space object

8096:    Level: developer

8098:    Notes:
8099:       This null space is used by solvers. Overwrites any previous null space that may have been attached

8101:    Concepts: null space^attaching to matrix

8103: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
8104: @*/
8105: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8106: {
8111:   *nullsp = mat->transnullsp;
8112:   return(0);
8113: }

8117: /*@
8118:    MatSetTransposeNullSpace - attaches a null space to a matrix.

8120:    Logically Collective on Mat and MatNullSpace

8122:    Input Parameters:
8123: +  mat - the matrix
8124: -  nullsp - the null space object

8126:    Level: advanced

8128:    Notes:
8129:       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.
8130:       You must also call MatSetNullSpace()


8133:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8134:    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).
8135:    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
8136:    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
8137:    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).

8139:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

8141:    Concepts: null space^attaching to matrix

8143: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetNullSpace(), MatNullSpaceRemove()
8144: @*/
8145: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8146: {

8153:   MatCheckPreallocated(mat,1);
8154:   PetscObjectReference((PetscObject)nullsp);
8155:   MatNullSpaceDestroy(&mat->transnullsp);
8156:   mat->transnullsp = nullsp;
8157:   return(0);
8158: }

8162: /*@
8163:    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8164:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

8166:    Logically Collective on Mat and MatNullSpace

8168:    Input Parameters:
8169: +  mat - the matrix
8170: -  nullsp - the null space object

8172:    Level: advanced

8174:    Notes:
8175:       Overwrites any previous near null space that may have been attached

8177:       You can remove the null space by calling this routine with an nullsp of NULL

8179:    Concepts: null space^attaching to matrix

8181: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody()
8182: @*/
8183: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8184: {

8191:   MatCheckPreallocated(mat,1);
8192:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8193:   MatNullSpaceDestroy(&mat->nearnullsp);
8194:   mat->nearnullsp = nullsp;
8195:   return(0);
8196: }

8200: /*@
8201:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

8203:    Not Collective

8205:    Input Parameters:
8206: .  mat - the matrix

8208:    Output Parameters:
8209: .  nullsp - the null space object, NULL if not set

8211:    Level: developer

8213:    Concepts: null space^attaching to matrix

8215: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
8216: @*/
8217: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8218: {
8223:   MatCheckPreallocated(mat,1);
8224:   *nullsp = mat->nearnullsp;
8225:   return(0);
8226: }

8230: /*@C
8231:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

8233:    Collective on Mat

8235:    Input Parameters:
8236: +  mat - the matrix
8237: .  row - row/column permutation
8238: .  fill - expected fill factor >= 1.0
8239: -  level - level of fill, for ICC(k)

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

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

8249:    Level: developer

8251:    Concepts: matrices^incomplete Cholesky factorization
8252:    Concepts: Cholesky factorization

8254: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

8259: @*/
8260: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8261: {

8269:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8270:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8271:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8272:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8273:   MatCheckPreallocated(mat,1);
8274:   (*mat->ops->iccfactor)(mat,row,info);
8275:   PetscObjectStateIncrease((PetscObject)mat);
8276:   return(0);
8277: }

8281: /*@
8282:    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.

8284:    Not Collective

8286:    Input Parameters:
8287: +  mat - the matrix
8288: .  nl - leading dimension of v
8289: -  v - the values compute with ADIFOR

8291:    Level: developer

8293:    Notes:
8294:      Must call MatSetColoring() before using this routine. Also this matrix must already
8295:      have its nonzero pattern determined.

8297: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8298:           MatSetValues(), MatSetColoring()
8299: @*/
8300: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8301: {


8309:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8310:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
8311:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8312:   (*mat->ops->setvaluesadifor)(mat,nl,v);
8313:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
8314:   PetscObjectStateIncrease((PetscObject)mat);
8315:   return(0);
8316: }

8320: /*@
8321:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8322:          ghosted ones.

8324:    Not Collective

8326:    Input Parameters:
8327: +  mat - the matrix
8328: -  diag = the diagonal values, including ghost ones

8330:    Level: developer

8332:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

8334: .seealso: MatDiagonalScale()
8335: @*/
8336: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8337: {
8339:   PetscMPIInt    size;


8346:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8347:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8348:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8349:   if (size == 1) {
8350:     PetscInt n,m;
8351:     VecGetSize(diag,&n);
8352:     MatGetSize(mat,0,&m);
8353:     if (m == n) {
8354:       MatDiagonalScale(mat,0,diag);
8355:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8356:   } else {
8357:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8358:   }
8359:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8360:   PetscObjectStateIncrease((PetscObject)mat);
8361:   return(0);
8362: }

8366: /*@
8367:    MatGetInertia - Gets the inertia from a factored matrix

8369:    Collective on Mat

8371:    Input Parameter:
8372: .  mat - the matrix

8374:    Output Parameters:
8375: +   nneg - number of negative eigenvalues
8376: .   nzero - number of zero eigenvalues
8377: -   npos - number of positive eigenvalues

8379:    Level: advanced

8381:    Notes: Matrix must have been factored by MatCholeskyFactor()


8384: @*/
8385: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8386: {

8392:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8393:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8394:   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8395:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8396:   return(0);
8397: }

8399: /* ----------------------------------------------------------------*/
8402: /*@C
8403:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

8405:    Neighbor-wise Collective on Mat and Vecs

8407:    Input Parameters:
8408: +  mat - the factored matrix
8409: -  b - the right-hand-side vectors

8411:    Output Parameter:
8412: .  x - the result vectors

8414:    Notes:
8415:    The vectors b and x cannot be the same.  I.e., one cannot
8416:    call MatSolves(A,x,x).

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

8423:    Level: developer

8425:    Concepts: matrices^triangular solves

8427: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8428: @*/
8429: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8430: {

8436:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8437:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8438:   if (!mat->rmap->N && !mat->cmap->N) return(0);

8440:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8441:   MatCheckPreallocated(mat,1);
8442:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8443:   (*mat->ops->solves)(mat,b,x);
8444:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8445:   return(0);
8446: }

8450: /*@
8451:    MatIsSymmetric - Test whether a matrix is symmetric

8453:    Collective on Mat

8455:    Input Parameter:
8456: +  A - the matrix to test
8457: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

8459:    Output Parameters:
8460: .  flg - the result

8462:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

8464:    Level: intermediate

8466:    Concepts: matrix^symmetry

8468: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8469: @*/
8470: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8471: {


8478:   if (!A->symmetric_set) {
8479:     if (!A->ops->issymmetric) {
8480:       MatType mattype;
8481:       MatGetType(A,&mattype);
8482:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8483:     }
8484:     (*A->ops->issymmetric)(A,tol,flg);
8485:     if (!tol) {
8486:       A->symmetric_set = PETSC_TRUE;
8487:       A->symmetric     = *flg;
8488:       if (A->symmetric) {
8489:         A->structurally_symmetric_set = PETSC_TRUE;
8490:         A->structurally_symmetric     = PETSC_TRUE;
8491:       }
8492:     }
8493:   } else if (A->symmetric) {
8494:     *flg = PETSC_TRUE;
8495:   } else if (!tol) {
8496:     *flg = PETSC_FALSE;
8497:   } else {
8498:     if (!A->ops->issymmetric) {
8499:       MatType mattype;
8500:       MatGetType(A,&mattype);
8501:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8502:     }
8503:     (*A->ops->issymmetric)(A,tol,flg);
8504:   }
8505:   return(0);
8506: }

8510: /*@
8511:    MatIsHermitian - Test whether a matrix is Hermitian

8513:    Collective on Mat

8515:    Input Parameter:
8516: +  A - the matrix to test
8517: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

8519:    Output Parameters:
8520: .  flg - the result

8522:    Level: intermediate

8524:    Concepts: matrix^symmetry

8526: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8527:           MatIsSymmetricKnown(), MatIsSymmetric()
8528: @*/
8529: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8530: {


8537:   if (!A->hermitian_set) {
8538:     if (!A->ops->ishermitian) {
8539:       MatType mattype;
8540:       MatGetType(A,&mattype);
8541:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8542:     }
8543:     (*A->ops->ishermitian)(A,tol,flg);
8544:     if (!tol) {
8545:       A->hermitian_set = PETSC_TRUE;
8546:       A->hermitian     = *flg;
8547:       if (A->hermitian) {
8548:         A->structurally_symmetric_set = PETSC_TRUE;
8549:         A->structurally_symmetric     = PETSC_TRUE;
8550:       }
8551:     }
8552:   } else if (A->hermitian) {
8553:     *flg = PETSC_TRUE;
8554:   } else if (!tol) {
8555:     *flg = PETSC_FALSE;
8556:   } else {
8557:     if (!A->ops->ishermitian) {
8558:       MatType mattype;
8559:       MatGetType(A,&mattype);
8560:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8561:     }
8562:     (*A->ops->ishermitian)(A,tol,flg);
8563:   }
8564:   return(0);
8565: }

8569: /*@
8570:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

8572:    Not Collective

8574:    Input Parameter:
8575: .  A - the matrix to check

8577:    Output Parameters:
8578: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8579: -  flg - the result

8581:    Level: advanced

8583:    Concepts: matrix^symmetry

8585:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8586:          if you want it explicitly checked

8588: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8589: @*/
8590: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8591: {
8596:   if (A->symmetric_set) {
8597:     *set = PETSC_TRUE;
8598:     *flg = A->symmetric;
8599:   } else {
8600:     *set = PETSC_FALSE;
8601:   }
8602:   return(0);
8603: }

8607: /*@
8608:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8610:    Not Collective

8612:    Input Parameter:
8613: .  A - the matrix to check

8615:    Output Parameters:
8616: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8617: -  flg - the result

8619:    Level: advanced

8621:    Concepts: matrix^symmetry

8623:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8624:          if you want it explicitly checked

8626: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8627: @*/
8628: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8629: {
8634:   if (A->hermitian_set) {
8635:     *set = PETSC_TRUE;
8636:     *flg = A->hermitian;
8637:   } else {
8638:     *set = PETSC_FALSE;
8639:   }
8640:   return(0);
8641: }

8645: /*@
8646:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8648:    Collective on Mat

8650:    Input Parameter:
8651: .  A - the matrix to test

8653:    Output Parameters:
8654: .  flg - the result

8656:    Level: intermediate

8658:    Concepts: matrix^symmetry

8660: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8661: @*/
8662: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8663: {

8669:   if (!A->structurally_symmetric_set) {
8670:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8671:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);

8673:     A->structurally_symmetric_set = PETSC_TRUE;
8674:   }
8675:   *flg = A->structurally_symmetric;
8676:   return(0);
8677: }

8681: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8682: /*@
8683:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8684:        to be communicated to other processors during the MatAssemblyBegin/End() process

8686:     Not collective

8688:    Input Parameter:
8689: .   vec - the vector

8691:    Output Parameters:
8692: +   nstash   - the size of the stash
8693: .   reallocs - the number of additional mallocs incurred.
8694: .   bnstash   - the size of the block stash
8695: -   breallocs - the number of additional mallocs incurred.in the block stash

8697:    Level: advanced

8699: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()

8701: @*/
8702: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8703: {

8707:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8708:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8709:   return(0);
8710: }

8714: /*@C
8715:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8716:      parallel layout

8718:    Collective on Mat

8720:    Input Parameter:
8721: .  mat - the matrix

8723:    Output Parameter:
8724: +   right - (optional) vector that the matrix can be multiplied against
8725: -   left - (optional) vector that the matrix vector product can be stored in

8727:    Notes:
8728:     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().

8730:   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed

8732:   Level: advanced

8734: .seealso: MatCreate(), VecDestroy()
8735: @*/
8736: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8737: {

8743:   if (mat->ops->getvecs) {
8744:     (*mat->ops->getvecs)(mat,right,left);
8745:   } else {
8746:     PetscInt rbs,cbs;
8747:     MatGetBlockSizes(mat,&rbs,&cbs);
8748:     if (right) {
8749:       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8750:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8751:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8752:       VecSetBlockSize(*right,cbs);
8753:       VecSetType(*right,VECSTANDARD);
8754:       PetscLayoutReference(mat->cmap,&(*right)->map);
8755:     }
8756:     if (left) {
8757:       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8758:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8759:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8760:       VecSetBlockSize(*left,rbs);
8761:       VecSetType(*left,VECSTANDARD);
8762:       PetscLayoutReference(mat->rmap,&(*left)->map);
8763:     }
8764:   }
8765:   return(0);
8766: }

8770: /*@C
8771:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8772:      with default values.

8774:    Not Collective

8776:    Input Parameters:
8777: .    info - the MatFactorInfo data structure


8780:    Notes: The solvers are generally used through the KSP and PC objects, for example
8781:           PCLU, PCILU, PCCHOLESKY, PCICC

8783:    Level: developer

8785: .seealso: MatFactorInfo

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

8790: @*/

8792: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8793: {

8797:   PetscMemzero(info,sizeof(MatFactorInfo));
8798:   return(0);
8799: }

8803: /*@
8804:    MatFactorSetSchurIS - Set indices corresponding to the Schur complement

8806:    Collective on Mat

8808:    Input Parameters:
8809: +  mat - the factored matrix
8810: -  is - the index set defining the Schur indices (0-based)

8812:    Notes:

8814:    Level: developer

8816:    Concepts:

8818: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()

8820: @*/
8821: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8822: {
8823:   PetscErrorCode ierr,(*f)(Mat,IS);

8831:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8832:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8833:   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");
8834:   (*f)(mat,is);
8835:   return(0);
8836: }

8840: /*@
8841:   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step

8843:    Logically Collective on Mat

8845:    Input Parameters:
8846: +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8847: .  *S - location where to return the Schur complement (MATDENSE)

8849:    Notes:
8850:    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.
8851:    If MatFactorInvertSchurComplement has been called, the routine gets back the inverse

8853:    Level: advanced

8855:    References:

8857: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement()
8858: @*/
8859: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S)
8860: {

8865:   PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));
8866:   return(0);
8867: }

8871: /*@
8872:   MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data

8874:    Logically Collective on Mat

8876:    Input Parameters:
8877: +  F - the factored matrix obtained by calling MatGetFactor()
8878: .  *S - location where to return the Schur complement (in MATDENSE format)

8880:    Notes:
8881:    Schur complement mode is currently implemented for sequential matrices.
8882:    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.
8883:    The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.

8885:    Level: advanced

8887:    References:

8889: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8890: @*/
8891: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S)
8892: {

8897:   PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));
8898:   return(0);
8899: }

8903: /*@
8904:   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement

8906:    Logically Collective on Mat

8908:    Input Parameters:
8909: +  F - the factored matrix obtained by calling MatGetFactor()
8910: .  *S - location where the Schur complement is stored

8912:    Notes:

8914:    Level: advanced

8916:    References:

8918: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8919: @*/
8920: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S)
8921: {

8927:   MatDestroy(S);
8928:   return(0);
8929: }

8933: /*@
8934:   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step

8936:    Logically Collective on Mat

8938:    Input Parameters:
8939: +  F - the factored matrix obtained by calling MatGetFactor()
8940: .  rhs - location where the right hand side of the Schur complement system is stored
8941: -  sol - location where the solution of the Schur complement system has to be returned

8943:    Notes:
8944:    The sizes of the vectors should match the size of the Schur complement

8946:    Level: advanced

8948:    References:

8950: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8951: @*/
8952: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8953: {

8962:   PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));
8963:   return(0);
8964: }

8968: /*@
8969:   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step

8971:    Logically Collective on Mat

8973:    Input Parameters:
8974: +  F - the factored matrix obtained by calling MatGetFactor()
8975: .  rhs - location where the right hand side of the Schur complement system is stored
8976: -  sol - location where the solution of the Schur complement system has to be returned

8978:    Notes:
8979:    The sizes of the vectors should match the size of the Schur complement

8981:    Level: advanced

8983:    References:

8985: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8986: @*/
8987: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8988: {

8997:   PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));
8998:   return(0);
8999: }

9003: /*@
9004:   MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step

9006:    Logically Collective on Mat

9008:    Input Parameters:
9009: +  F - the factored matrix obtained by calling MatGetFactor()

9011:    Notes:

9013:    Level: advanced

9015:    References:

9017: .seealso: MatGetFactor(), MatFactorSetSchurIS()
9018: @*/
9019: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9020: {

9025:   PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));
9026:   return(0);
9027: }


9032: /*@
9033:    MatPtAP - Creates the matrix product C = P^T * A * P

9035:    Neighbor-wise Collective on Mat

9037:    Input Parameters:
9038: +  A - the matrix
9039: .  P - the projection matrix
9040: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9041: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9042:           if the result is a dense matrix this is irrelevent

9044:    Output Parameters:
9045: .  C - the product matrix

9047:    Notes:
9048:    C will be created and must be destroyed by the user with MatDestroy().

9050:    This routine is currently only implemented for pairs of AIJ matrices and classes
9051:    which inherit from AIJ.

9053:    Level: intermediate

9055: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9056: @*/
9057: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9058: {
9060:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9061:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9062:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9063:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

9066:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
9067:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

9071:   MatCheckPreallocated(A,1);
9072:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9073:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9076:   MatCheckPreallocated(P,2);
9077:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9078:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9080:   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);
9081:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9082:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9084:   if (scall == MAT_REUSE_MATRIX) {
9087:     if (viatranspose || viamatmatmatmult) {
9088:       Mat Pt;
9089:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9090:       if (viamatmatmatmult) {
9091:         MatMatMatMult(Pt,A,P,scall,fill,C);
9092:       } else {
9093:         Mat AP;
9094:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9095:         MatMatMult(Pt,AP,scall,fill,C);
9096:         MatDestroy(&AP);
9097:       }
9098:       MatDestroy(&Pt);
9099:     } else {
9100:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9101:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9102:       (*(*C)->ops->ptapnumeric)(A,P,*C);
9103:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9104:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9105:     }
9106:     return(0);
9107:   }

9109:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9110:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9112:   fA = A->ops->ptap;
9113:   fP = P->ops->ptap;
9114:   if (fP == fA) {
9115:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9116:     ptap = fA;
9117:   } else {
9118:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9119:     char ptapname[256];
9120:     PetscStrcpy(ptapname,"MatPtAP_");
9121:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
9122:     PetscStrcat(ptapname,"_");
9123:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
9124:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9125:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9126:     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);
9127:   }

9129:   if (viatranspose || viamatmatmatmult) {
9130:     Mat Pt;
9131:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9132:     if (viamatmatmatmult) {
9133:       MatMatMatMult(Pt,A,P,scall,fill,C);
9134:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
9135:     } else {
9136:       Mat AP;
9137:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9138:       MatMatMult(Pt,AP,scall,fill,C);
9139:       MatDestroy(&AP);
9140:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
9141:     }
9142:     MatDestroy(&Pt);
9143:   } else {
9144:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9145:     (*ptap)(A,P,scall,fill,C);
9146:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9147:   }
9148:   return(0);
9149: }

9153: /*@
9154:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

9156:    Neighbor-wise Collective on Mat

9158:    Input Parameters:
9159: +  A - the matrix
9160: -  P - the projection matrix

9162:    Output Parameters:
9163: .  C - the product matrix

9165:    Notes:
9166:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9167:    the user using MatDeatroy().

9169:    This routine is currently only implemented for pairs of AIJ matrices and classes
9170:    which inherit from AIJ.  C will be of type MATAIJ.

9172:    Level: intermediate

9174: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9175: @*/
9176: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9177: {

9183:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9184:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9187:   MatCheckPreallocated(P,2);
9188:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9189:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9192:   MatCheckPreallocated(C,3);
9193:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9194:   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);
9195:   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);
9196:   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);
9197:   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);
9198:   MatCheckPreallocated(A,1);

9200:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9201:   (*C->ops->ptapnumeric)(A,P,C);
9202:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9203:   return(0);
9204: }

9208: /*@
9209:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

9211:    Neighbor-wise Collective on Mat

9213:    Input Parameters:
9214: +  A - the matrix
9215: -  P - the projection matrix

9217:    Output Parameters:
9218: .  C - the (i,j) structure of the product matrix

9220:    Notes:
9221:    C will be created and must be destroyed by the user with MatDestroy().

9223:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9224:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9225:    this (i,j) structure by calling MatPtAPNumeric().

9227:    Level: intermediate

9229: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9230: @*/
9231: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9232: {

9238:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9239:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9240:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9243:   MatCheckPreallocated(P,2);
9244:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9245:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9248:   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);
9249:   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);
9250:   MatCheckPreallocated(A,1);
9251:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9252:   (*A->ops->ptapsymbolic)(A,P,fill,C);
9253:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

9255:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
9256:   return(0);
9257: }

9261: /*@
9262:    MatRARt - Creates the matrix product C = R * A * R^T

9264:    Neighbor-wise Collective on Mat

9266:    Input Parameters:
9267: +  A - the matrix
9268: .  R - the projection matrix
9269: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9270: -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9271:           if the result is a dense matrix this is irrelevent

9273:    Output Parameters:
9274: .  C - the product matrix

9276:    Notes:
9277:    C will be created and must be destroyed by the user with MatDestroy().

9279:    This routine is currently only implemented for pairs of AIJ matrices and classes
9280:    which inherit from AIJ.

9282:    Level: intermediate

9284: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9285: @*/
9286: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9287: {

9293:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9294:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9297:   MatCheckPreallocated(R,2);
9298:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9299:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9301:   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);

9303:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9304:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9305:   MatCheckPreallocated(A,1);

9307:   if (!A->ops->rart) {
9308:     MatType mattype;
9309:     MatGetType(A,&mattype);
9310:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
9311:   }
9312:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
9313:   (*A->ops->rart)(A,R,scall,fill,C);
9314:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
9315:   return(0);
9316: }

9320: /*@
9321:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

9323:    Neighbor-wise Collective on Mat

9325:    Input Parameters:
9326: +  A - the matrix
9327: -  R - the projection matrix

9329:    Output Parameters:
9330: .  C - the product matrix

9332:    Notes:
9333:    C must have been created by calling MatRARtSymbolic and must be destroyed by
9334:    the user using MatDestroy().

9336:    This routine is currently only implemented for pairs of AIJ matrices and classes
9337:    which inherit from AIJ.  C will be of type MATAIJ.

9339:    Level: intermediate

9341: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9342: @*/
9343: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9344: {

9350:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9351:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9354:   MatCheckPreallocated(R,2);
9355:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9356:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9359:   MatCheckPreallocated(C,3);
9360:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9361:   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);
9362:   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);
9363:   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);
9364:   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);
9365:   MatCheckPreallocated(A,1);

9367:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
9368:   (*A->ops->rartnumeric)(A,R,C);
9369:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
9370:   return(0);
9371: }

9375: /*@
9376:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

9378:    Neighbor-wise Collective on Mat

9380:    Input Parameters:
9381: +  A - the matrix
9382: -  R - the projection matrix

9384:    Output Parameters:
9385: .  C - the (i,j) structure of the product matrix

9387:    Notes:
9388:    C will be created and must be destroyed by the user with MatDestroy().

9390:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9391:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9392:    this (i,j) structure by calling MatRARtNumeric().

9394:    Level: intermediate

9396: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9397: @*/
9398: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9399: {

9405:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9406:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9407:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9410:   MatCheckPreallocated(R,2);
9411:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9412:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9415:   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);
9416:   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);
9417:   MatCheckPreallocated(A,1);
9418:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9419:   (*A->ops->rartsymbolic)(A,R,fill,C);
9420:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

9422:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9423:   return(0);
9424: }

9428: /*@
9429:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

9431:    Neighbor-wise Collective on Mat

9433:    Input Parameters:
9434: +  A - the left matrix
9435: .  B - the right matrix
9436: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9437: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9438:           if the result is a dense matrix this is irrelevent

9440:    Output Parameters:
9441: .  C - the product matrix

9443:    Notes:
9444:    Unless scall is MAT_REUSE_MATRIX C will be created.

9446:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9448:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9449:    actually needed.

9451:    If you have many matrices with the same non-zero structure to multiply, you
9452:    should either
9453: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9454: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9455:    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
9456:    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.

9458:    Level: intermediate

9460: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9461: @*/
9462: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9463: {
9465:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9466:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9467:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9472:   MatCheckPreallocated(A,1);
9473:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9474:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9477:   MatCheckPreallocated(B,2);
9478:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9479:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9481:   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);
9482:   if (scall == MAT_REUSE_MATRIX) {
9485:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9486:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9487:     (*(*C)->ops->matmultnumeric)(A,B,*C);
9488:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9489:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9490:     return(0);
9491:   }
9492:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9493:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9495:   fA = A->ops->matmult;
9496:   fB = B->ops->matmult;
9497:   if (fB == fA) {
9498:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9499:     mult = fB;
9500:   } else {
9501:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9502:     char multname[256];
9503:     PetscStrcpy(multname,"MatMatMult_");
9504:     PetscStrcat(multname,((PetscObject)A)->type_name);
9505:     PetscStrcat(multname,"_");
9506:     PetscStrcat(multname,((PetscObject)B)->type_name);
9507:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9508:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9509:     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);
9510:   }
9511:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9512:   (*mult)(A,B,scall,fill,C);
9513:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9514:   return(0);
9515: }

9519: /*@
9520:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9521:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

9523:    Neighbor-wise Collective on Mat

9525:    Input Parameters:
9526: +  A - the left matrix
9527: .  B - the right matrix
9528: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9529:       if C is a dense matrix this is irrelevent

9531:    Output Parameters:
9532: .  C - the product matrix

9534:    Notes:
9535:    Unless scall is MAT_REUSE_MATRIX C will be created.

9537:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9538:    actually needed.

9540:    This routine is currently implemented for
9541:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9542:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9543:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9545:    Level: intermediate

9547:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9548:      We should incorporate them into PETSc.

9550: .seealso: MatMatMult(), MatMatMultNumeric()
9551: @*/
9552: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9553: {
9555:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9556:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9557:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

9562:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9563:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9567:   MatCheckPreallocated(B,2);
9568:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9569:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9572:   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);
9573:   if (fill == PETSC_DEFAULT) fill = 2.0;
9574:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9575:   MatCheckPreallocated(A,1);

9577:   Asymbolic = A->ops->matmultsymbolic;
9578:   Bsymbolic = B->ops->matmultsymbolic;
9579:   if (Asymbolic == Bsymbolic) {
9580:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9581:     symbolic = Bsymbolic;
9582:   } else { /* dispatch based on the type of A and B */
9583:     char symbolicname[256];
9584:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9585:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9586:     PetscStrcat(symbolicname,"_");
9587:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9588:     PetscStrcat(symbolicname,"_C");
9589:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9590:     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);
9591:   }
9592:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9593:   (*symbolic)(A,B,fill,C);
9594:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9595:   return(0);
9596: }

9600: /*@
9601:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9602:    Call this routine after first calling MatMatMultSymbolic().

9604:    Neighbor-wise Collective on Mat

9606:    Input Parameters:
9607: +  A - the left matrix
9608: -  B - the right matrix

9610:    Output Parameters:
9611: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

9613:    Notes:
9614:    C must have been created with MatMatMultSymbolic().

9616:    This routine is currently implemented for
9617:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9618:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9619:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9621:    Level: intermediate

9623: .seealso: MatMatMult(), MatMatMultSymbolic()
9624: @*/
9625: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9626: {

9630:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9631:   return(0);
9632: }

9636: /*@
9637:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

9639:    Neighbor-wise Collective on Mat

9641:    Input Parameters:
9642: +  A - the left matrix
9643: .  B - the right matrix
9644: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9645: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9647:    Output Parameters:
9648: .  C - the product matrix

9650:    Notes:
9651:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

9653:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9655:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9656:    actually needed.

9658:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

9660:    Level: intermediate

9662: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9663: @*/
9664: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9665: {
9667:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9668:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

9673:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9674:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9677:   MatCheckPreallocated(B,2);
9678:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9679:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9681:   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);
9682:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9683:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9684:   MatCheckPreallocated(A,1);

9686:   fA = A->ops->mattransposemult;
9687:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9688:   fB = B->ops->mattransposemult;
9689:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9690:   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);

9692:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9693:   if (scall == MAT_INITIAL_MATRIX) {
9694:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9695:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9696:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9697:   }
9698:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9699:   (*A->ops->mattransposemultnumeric)(A,B,*C);
9700:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9701:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9702:   return(0);
9703: }

9707: /*@
9708:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

9710:    Neighbor-wise Collective on Mat

9712:    Input Parameters:
9713: +  A - the left matrix
9714: .  B - the right matrix
9715: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9716: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9718:    Output Parameters:
9719: .  C - the product matrix

9721:    Notes:
9722:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

9724:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

9726:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9727:    actually needed.

9729:    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9730:    which inherit from SeqAIJ.  C will be of same type as the input matrices.

9732:    Level: intermediate

9734: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9735: @*/
9736: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9737: {
9739:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9740:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9741:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

9746:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9747:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9750:   MatCheckPreallocated(B,2);
9751:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9752:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9754:   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);
9755:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9756:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9757:   MatCheckPreallocated(A,1);

9759:   fA = A->ops->transposematmult;
9760:   fB = B->ops->transposematmult;
9761:   if (fB==fA) {
9762:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9763:     transposematmult = fA;
9764:   } else {
9765:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9766:     char multname[256];
9767:     PetscStrcpy(multname,"MatTransposeMatMult_");
9768:     PetscStrcat(multname,((PetscObject)A)->type_name);
9769:     PetscStrcat(multname,"_");
9770:     PetscStrcat(multname,((PetscObject)B)->type_name);
9771:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9772:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9773:     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);
9774:   }
9775:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9776:   (*transposematmult)(A,B,scall,fill,C);
9777:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9778:   return(0);
9779: }

9783: /*@
9784:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

9786:    Neighbor-wise Collective on Mat

9788:    Input Parameters:
9789: +  A - the left matrix
9790: .  B - the middle matrix
9791: .  C - the right matrix
9792: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9793: -  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
9794:           if the result is a dense matrix this is irrelevent

9796:    Output Parameters:
9797: .  D - the product matrix

9799:    Notes:
9800:    Unless scall is MAT_REUSE_MATRIX D will be created.

9802:    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call

9804:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9805:    actually needed.

9807:    If you have many matrices with the same non-zero structure to multiply, you
9808:    should use MAT_REUSE_MATRIX in all calls but the first or

9810:    Level: intermediate

9812: .seealso: MatMatMult, MatPtAP()
9813: @*/
9814: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9815: {
9817:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9818:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9819:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9820:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9825:   MatCheckPreallocated(A,1);
9826:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9827:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9830:   MatCheckPreallocated(B,2);
9831:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9832:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9835:   MatCheckPreallocated(C,3);
9836:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9837:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9838:   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);
9839:   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);
9840:   if (scall == MAT_REUSE_MATRIX) {
9843:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9844:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9845:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9846:     return(0);
9847:   }
9848:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9849:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9851:   fA = A->ops->matmatmult;
9852:   fB = B->ops->matmatmult;
9853:   fC = C->ops->matmatmult;
9854:   if (fA == fB && fA == fC) {
9855:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9856:     mult = fA;
9857:   } else {
9858:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9859:     char multname[256];
9860:     PetscStrcpy(multname,"MatMatMatMult_");
9861:     PetscStrcat(multname,((PetscObject)A)->type_name);
9862:     PetscStrcat(multname,"_");
9863:     PetscStrcat(multname,((PetscObject)B)->type_name);
9864:     PetscStrcat(multname,"_");
9865:     PetscStrcat(multname,((PetscObject)C)->type_name);
9866:     PetscStrcat(multname,"_C");
9867:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9868:     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);
9869:   }
9870:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9871:   (*mult)(A,B,C,scall,fill,D);
9872:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9873: