Actual source code: matrix.c

petsc-master 2017-11-22
Report Typos and Errors

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

  6:  #include <petsc/private/matimpl.h>
  7:  #include <petsc/private/isimpl.h>
  8:  #include <petsc/private/vecimpl.h>

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

 16: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
 17: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
 18: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
 19: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
 20: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
 21: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, 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_CreateSubMat;
 24: PetscLogEvent MAT_TransposeColoringCreate;
 25: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
 26: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
 27: PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
 28: PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
 29: PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
 30: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
 31: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
 32: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
 33: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
 34: PetscLogEvent MAT_GetMultiProcBlock;
 35: PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
 36: PetscLogEvent MAT_ViennaCLCopyToGPU;
 37: PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
 38: PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;

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

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

 45:    Logically Collective on Vec

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

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

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

 62:    Level: intermediate

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

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


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

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

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

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

 99:    Logically Collective on Mat

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

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

109:    Level: advanced

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

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

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

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

130:    Logically Collective on Mat

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

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

138:    Level: advanced

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

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

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

155:    Logically Collective on Mat

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

160:    Level: developer

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

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

176: static PetscErrorCode MatFindNonzeroRows_Basic(Mat mat,IS *keptrows)
177: {
178:   PetscErrorCode    ierr;
179:   Vec               r,l;
180:   const PetscScalar *al;
181:   PetscInt          i,nz,gnz,N,n;

184:   MatGetSize(mat,&N,NULL);
185:   MatGetLocalSize(mat,&n,NULL);
186:   MatCreateVecs(mat,&r,&l);
187:   VecSet(l,0.0);
188:   VecSetRandom(r,NULL);
189:   MatMult(mat,r,l);
190:   VecGetArrayRead(l,&al);
191:   for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++;
192:   MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));
193:   if (gnz != N) {
194:     PetscInt *nzr;
195:     PetscMalloc1(nz,&nzr);
196:     if (nz) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
197:     ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,keptrows);
198:   } else *keptrows = NULL;
199:   VecRestoreArrayRead(l,&al);
200:   VecDestroy(&l);
201:   VecDestroy(&r);
202:   return(0);
203: }

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

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

211:   Output Parameter:
212: .    keptrows - the rows that are not completely zero

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

216:   Level: intermediate

218:  @*/
219: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
220: {

227:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
228:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
229:   if (!mat->ops->findnonzerorows) {
230:     MatFindNonzeroRows_Basic(mat,keptrows);
231:   } else {
232:     (*mat->ops->findnonzerorows)(mat,keptrows);
233:   }
234:   return(0);
235: }

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

240:   Input Parameter:
241: .    A  - the matrix

243:   Output Parameter:
244: .    zerorows - the rows that are completely zero

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

248:   Level: intermediate

250:  @*/
251: PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
252: {
254:   IS keptrows;
255:   PetscInt m, n;


260:   MatFindNonzeroRows(mat, &keptrows);
261:   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
262:      In keeping with this convention, we set zerorows to NULL if there are no zero
263:      rows. */
264:   if (keptrows == NULL) {
265:     *zerorows = NULL;
266:   } else {
267:     MatGetOwnershipRange(mat,&m,&n);
268:     ISComplement(keptrows,m,n,zerorows);
269:     ISDestroy(&keptrows);
270:   }
271:   return(0);
272: }

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

277:    Not Collective

279:    Input Parameters:
280: .   A - the matrix

282:    Output Parameters:
283: .   a - the diagonal part (which is a SEQUENTIAL matrix)

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

289:    Level: advanced

291: @*/
292: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
293: {

300:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
301:   if (!A->ops->getdiagonalblock) {
302:     PetscMPIInt size;
303:     MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
304:     if (size == 1) {
305:       *a = A;
306:       return(0);
307:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
308:   }
309:   (*A->ops->getdiagonalblock)(A,a);
310:   return(0);
311: }

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

316:    Collective on Mat

318:    Input Parameters:
319: .  mat - the matrix

321:    Output Parameter:
322: .   trace - the sum of the diagonal entries

324:    Level: advanced

326: @*/
327: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
328: {
330:   Vec            diag;

333:   MatCreateVecs(mat,&diag,NULL);
334:   MatGetDiagonal(mat,diag);
335:   VecSum(diag,trace);
336:   VecDestroy(&diag);
337:   return(0);
338: }

340: /*@
341:    MatRealPart - Zeros out the imaginary part of the matrix

343:    Logically Collective on Mat

345:    Input Parameters:
346: .  mat - the matrix

348:    Level: advanced


351: .seealso: MatImaginaryPart()
352: @*/
353: PetscErrorCode MatRealPart(Mat mat)
354: {

360:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
361:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
362:   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
363:   MatCheckPreallocated(mat,1);
364:   (*mat->ops->realpart)(mat);
365: #if defined(PETSC_HAVE_CUSP)
366:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
367:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
368:   }
369: #elif defined(PETSC_HAVE_VIENNACL)
370:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
371:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
372:   }
373: #elif defined(PETSC_HAVE_VECCUDA)
374:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
375:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
376:   }
377: #endif
378:   return(0);
379: }

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

384:    Collective on Mat

386:    Input Parameter:
387: .  mat - the matrix

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

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

395:    Level: advanced

397: @*/
398: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
399: {

405:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
406:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
407:   if (!mat->ops->getghosts) {
408:     if (nghosts) *nghosts = 0;
409:     if (ghosts) *ghosts = 0;
410:   } else {
411:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
412:   }
413:   return(0);
414: }


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

420:    Logically Collective on Mat

422:    Input Parameters:
423: .  mat - the matrix

425:    Level: advanced


428: .seealso: MatRealPart()
429: @*/
430: PetscErrorCode MatImaginaryPart(Mat mat)
431: {

437:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
438:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
439:   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
440:   MatCheckPreallocated(mat,1);
441:   (*mat->ops->imaginarypart)(mat);
442: #if defined(PETSC_HAVE_CUSP)
443:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
444:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
445:   }
446: #elif defined(PETSC_HAVE_VIENNACL)
447:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
448:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
449:   }
450: #elif defined(PETSC_HAVE_VECCUDA)
451:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
452:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
453:   }
454: #endif
455:   return(0);
456: }

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

461:    Not Collective

463:    Input Parameter:
464: .  mat - the matrix

466:    Output Parameters:
467: +  missing - is any diagonal missing
468: -  dd - first diagonal entry that is missing (optional) on this process

470:    Level: advanced


473: .seealso: MatRealPart()
474: @*/
475: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
476: {

482:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
483:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
484:   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
485:   (*mat->ops->missingdiagonal)(mat,missing,dd);
486:   return(0);
487: }

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

494:    Not Collective

496:    Input Parameters:
497: +  mat - the matrix
498: -  row - the row to get

500:    Output Parameters:
501: +  ncols -  if not NULL, the number of nonzeros in the row
502: .  cols - if not NULL, the column numbers
503: -  vals - if not NULL, the values

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

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

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

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

520:    You can only have one call to MatGetRow() outstanding for a particular
521:    matrix at a time, per processor. MatGetRow() can only obtain rows
522:    associated with the given processor, it cannot get rows from the
523:    other processors; for that we suggest using MatCreateSubMatrices(), then
524:    MatGetRow() on the submatrix. The row index passed to MatGetRows()
525:    is in the global number of rows.

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


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

544:    Level: advanced

546:    Concepts: matrices^row access

548: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
549: @*/
550: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
551: {
553:   PetscInt       incols;

558:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
559:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
560:   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
561:   MatCheckPreallocated(mat,1);
562:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
563:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
564:   if (ncols) *ncols = incols;
565:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
566:   return(0);
567: }

569: /*@
570:    MatConjugate - replaces the matrix values with their complex conjugates

572:    Logically Collective on Mat

574:    Input Parameters:
575: .  mat - the matrix

577:    Level: advanced

579: .seealso:  VecConjugate()
580: @*/
581: PetscErrorCode MatConjugate(Mat mat)
582: {
583: #if defined(PETSC_USE_COMPLEX)

588:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
589:   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");
590:   (*mat->ops->conjugate)(mat);
591: #if defined(PETSC_HAVE_CUSP)
592:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
593:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
594:   }
595: #elif defined(PETSC_HAVE_VIENNACL)
596:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
597:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
598:   }
599: #elif defined(PETSC_HAVE_VECCUDA)
600:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
601:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
602:   }
603: #endif
604:   return(0);
605: #else
606:   return 0;
607: #endif
608: }

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

613:    Not Collective

615:    Input Parameters:
616: +  mat - the matrix
617: .  row - the row to get
618: .  ncols, cols - the number of nonzeros and their columns
619: -  vals - if nonzero the column values

621:    Notes:
622:    This routine should be called after you have finished examining the entries.

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

628:    Fortran Notes:
629:    The calling sequence from Fortran is
630: .vb
631:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
632:       Mat     matrix (input)
633:       integer row    (input)
634:       integer ncols  (output)
635:       integer cols(maxcols) (output)
636:       double precision (or double complex) values(maxcols) output
637: .ve
638:    Where maxcols >= maximum nonzeros in any row of the matrix.

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

643:    Level: advanced

645: .seealso:  MatGetRow()
646: @*/
647: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
648: {

654:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
655:   if (!mat->ops->restorerow) return(0);
656:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
657:   if (ncols) *ncols = 0;
658:   if (cols)  *cols = NULL;
659:   if (vals)  *vals = NULL;
660:   return(0);
661: }

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

667:    Not Collective

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

672:    Notes:
673:    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.

675:    Level: advanced

677:    Concepts: matrices^row access

679: .seealso: MatRestoreRowRowUpperTriangular()
680: @*/
681: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
682: {

688:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
689:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
690:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
691:   MatCheckPreallocated(mat,1);
692:   (*mat->ops->getrowuppertriangular)(mat);
693:   return(0);
694: }

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

699:    Not Collective

701:    Input Parameters:
702: +  mat - the matrix

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


708:    Level: advanced

710: .seealso:  MatGetRowUpperTriangular()
711: @*/
712: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
713: {

718:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
719:   if (!mat->ops->restorerowuppertriangular) return(0);
720:   (*mat->ops->restorerowuppertriangular)(mat);
721:   return(0);
722: }

724: /*@C
725:    MatSetOptionsPrefix - Sets the prefix used for searching for all
726:    Mat options in the database.

728:    Logically Collective on Mat

730:    Input Parameter:
731: +  A - the Mat context
732: -  prefix - the prefix to prepend to all option names

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

738:    Level: advanced

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

742: .seealso: MatSetFromOptions()
743: @*/
744: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
745: {

750:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
751:   return(0);
752: }

754: /*@C
755:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
756:    Mat options in the database.

758:    Logically Collective on Mat

760:    Input Parameters:
761: +  A - the Mat context
762: -  prefix - the prefix to prepend to all option names

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

768:    Level: advanced

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

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

780:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
781:   return(0);
782: }

784: /*@C
785:    MatGetOptionsPrefix - Sets the prefix used for searching for all
786:    Mat options in the database.

788:    Not Collective

790:    Input Parameter:
791: .  A - the Mat context

793:    Output Parameter:
794: .  prefix - pointer to the prefix string used

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

799:    Level: advanced

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

803: .seealso: MatAppendOptionsPrefix()
804: @*/
805: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
806: {

811:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
812:   return(0);
813: }

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

818:    Collective on Mat

820:    Input Parameters:
821: .  A - the Mat context

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

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

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

830:    Level: beginner

832: .keywords: Mat, setup

834: .seealso: MatCreate(), MatDestroy()
835: @*/
836: PetscErrorCode MatSetUp(Mat A)
837: {
838:   PetscMPIInt    size;

843:   if (!((PetscObject)A)->type_name) {
844:     MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
845:     if (size == 1) {
846:       MatSetType(A, MATSEQAIJ);
847:     } else {
848:       MatSetType(A, MATMPIAIJ);
849:     }
850:   }
851:   if (!A->preallocated && A->ops->setup) {
852:     PetscInfo(A,"Warning not preallocating matrix storage\n");
853:     (*A->ops->setup)(A);
854:   }
855:   PetscLayoutSetUp(A->rmap);
856:   PetscLayoutSetUp(A->cmap);
857:   A->preallocated = PETSC_TRUE;
858:   return(0);
859: }

861: #if defined(PETSC_HAVE_SAWS)
862:  #include <petscviewersaws.h>
863: #endif
864: /*@C
865:    MatView - Visualizes a matrix object.

867:    Collective on Mat

869:    Input Parameters:
870: +  mat - the matrix
871: -  viewer - visualization context

873:   Notes:
874:   The available visualization contexts include
875: +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
876: .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
877: .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
878: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

880:    The user can open alternative visualization contexts with
881: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
882: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
883:          specified file; corresponding input uses MatLoad()
884: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
885:          an X window display
886: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
887:          Currently only the sequential dense and AIJ
888:          matrix types support the Socket viewer.

890:    The user can call PetscViewerPushFormat() to specify the output
891:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
892:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
893: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
894: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
895: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
896: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
897:          format common among all matrix types
898: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
899:          format (which is in many cases the same as the default)
900: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
901:          size and structure (not the matrix entries)
902: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
903:          the matrix structure

905:    Options Database Keys:
906: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
907: .  -mat_view ::ascii_info_detail - Prints more detailed info
908: .  -mat_view - Prints matrix in ASCII format
909: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
910: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
911: .  -display <name> - Sets display name (default is host)
912: .  -draw_pause <sec> - Sets number of seconds to pause after display
913: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 12 Using MATLAB with PETSc for details)
914: .  -viewer_socket_machine <machine> -
915: .  -viewer_socket_port <port> -
916: .  -mat_view binary - save matrix to file in binary format
917: -  -viewer_binary_filename <name> -
918:    Level: beginner

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

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

926:       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
927:       And then use the following mouse functions:
928:           left mouse: zoom in
929:           middle mouse: zoom out
930:           right mouse: continue with the simulation

932:    Concepts: matrices^viewing
933:    Concepts: matrices^plotting
934:    Concepts: matrices^printing

936: .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
937:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
938: @*/
939: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
940: {
941:   PetscErrorCode    ierr;
942:   PetscInt          rows,cols,rbs,cbs;
943:   PetscBool         iascii,ibinary;
944:   PetscViewerFormat format;
945: #if defined(PETSC_HAVE_SAWS)
946:   PetscBool         issaws;
947: #endif

952:   if (!viewer) {
953:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
954:   }
957:   MatCheckPreallocated(mat,1);
958:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
959:   if (ibinary) {
960:     PetscBool mpiio;
961:     PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
962:     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
963:   }

965:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
966:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
967:   PetscViewerGetFormat(viewer,&format);
968:   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
969:     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
970:   }

972: #if defined(PETSC_HAVE_SAWS)
973:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
974: #endif
975:   if (iascii) {
976:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
977:     PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
978:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
979:       PetscViewerASCIIPushTab(viewer);
980:       MatGetSize(mat,&rows,&cols);
981:       MatGetBlockSizes(mat,&rbs,&cbs);
982:       if (rbs != 1 || cbs != 1) {
983:         if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
984:         else            {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
985:       } else {
986:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
987:       }
988:       if (mat->factortype) {
989:         const MatSolverPackage solver;
990:         MatFactorGetSolverPackage(mat,&solver);
991:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
992:       }
993:       if (mat->ops->getinfo) {
994:         MatInfo info;
995:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
996:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
997:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
998:       }
999:       if (mat->nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached null space\n");}
1000:       if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");}
1001:     }
1002: #if defined(PETSC_HAVE_SAWS)
1003:   } else if (issaws) {
1004:     PetscMPIInt rank;

1006:     PetscObjectName((PetscObject)mat);
1007:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
1008:     if (!((PetscObject)mat)->amsmem && !rank) {
1009:       PetscObjectViewSAWs((PetscObject)mat,viewer);
1010:     }
1011: #endif
1012:   }
1013:   if (mat->ops->view) {
1014:     PetscViewerASCIIPushTab(viewer);
1015:     (*mat->ops->view)(mat,viewer);
1016:     PetscViewerASCIIPopTab(viewer);
1017:   }
1018:   if (iascii) {
1019:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1020:     PetscViewerGetFormat(viewer,&format);
1021:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1022:       PetscViewerASCIIPopTab(viewer);
1023:     }
1024:   }
1025:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
1026:   return(0);
1027: }

1029: #if defined(PETSC_USE_DEBUG)
1030: #include <../src/sys/totalview/tv_data_display.h>
1031: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1032: {
1033:   TV_add_row("Local rows", "int", &mat->rmap->n);
1034:   TV_add_row("Local columns", "int", &mat->cmap->n);
1035:   TV_add_row("Global rows", "int", &mat->rmap->N);
1036:   TV_add_row("Global columns", "int", &mat->cmap->N);
1037:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1038:   return TV_format_OK;
1039: }
1040: #endif

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

1048:    Collective on PetscViewer

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

1055:    Options Database Keys:
1056:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1057:    block size
1058: .    -matload_block_size <bs>

1060:    Level: beginner

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

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

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

1075:    In parallel, each processor can load a subset of rows (or the
1076:    entire matrix).  This routine is especially useful when a large
1077:    matrix is stored on disk and only part of it is desired on each
1078:    processor.  For example, a parallel solver may access only some of
1079:    the rows from each processor.  The algorithm used here reads
1080:    relatively small blocks of data rather than reading the entire
1081:    matrix and then subsetting it.

1083:    Notes for advanced users:
1084:    Most users should not need to know the details of the binary storage
1085:    format, since MatLoad() and MatView() completely hide these details.
1086:    But for anyone who's interested, the standard binary matrix storage
1087:    format is

1089: $    int    MAT_FILE_CLASSID
1090: $    int    number of rows
1091: $    int    number of columns
1092: $    int    total number of nonzeros
1093: $    int    *number nonzeros in each row
1094: $    int    *column indices of all nonzeros (starting index is zero)
1095: $    PetscScalar *values of all nonzeros

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

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

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

1107:  @*/
1108: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1109: {
1111:   PetscBool      isbinary,flg;

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

1119:   if (!((PetscObject)newmat)->type_name) {
1120:     MatSetType(newmat,MATAIJ);
1121:   }

1123:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1124:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1125:   (*newmat->ops->load)(newmat,viewer);
1126:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

1128:   flg  = PETSC_FALSE;
1129:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1130:   if (flg) {
1131:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1132:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1133:   }
1134:   flg  = PETSC_FALSE;
1135:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1136:   if (flg) {
1137:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1138:   }
1139:   return(0);
1140: }

1142: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1143: {
1145:   Mat_Redundant  *redund = *redundant;
1146:   PetscInt       i;

1149:   if (redund){
1150:     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1151:       ISDestroy(&redund->isrow);
1152:       ISDestroy(&redund->iscol);
1153:       MatDestroySubMatrices(1,&redund->matseq);
1154:     } else {
1155:       PetscFree2(redund->send_rank,redund->recv_rank);
1156:       PetscFree(redund->sbuf_j);
1157:       PetscFree(redund->sbuf_a);
1158:       for (i=0; i<redund->nrecvs; i++) {
1159:         PetscFree(redund->rbuf_j[i]);
1160:         PetscFree(redund->rbuf_a[i]);
1161:       }
1162:       PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1163:     }

1165:     if (redund->subcomm) {
1166:       PetscCommDestroy(&redund->subcomm);
1167:     }
1168:     PetscFree(redund);
1169:   }
1170:   return(0);
1171: }

1173: /*@
1174:    MatDestroy - Frees space taken by a matrix.

1176:    Collective on Mat

1178:    Input Parameter:
1179: .  A - the matrix

1181:    Level: beginner

1183: @*/
1184: PetscErrorCode MatDestroy(Mat *A)
1185: {

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

1193:   /* if memory was published with SAWs then destroy it */
1194:   PetscObjectSAWsViewOff((PetscObject)*A);
1195:   if ((*A)->ops->destroy) {
1196:     (*(*A)->ops->destroy)(*A);
1197:   }

1199:   PetscFree((*A)->solvertype);
1200:   MatDestroy_Redundant(&(*A)->redundant);
1201:   MatNullSpaceDestroy(&(*A)->nullsp);
1202:   MatNullSpaceDestroy(&(*A)->transnullsp);
1203:   MatNullSpaceDestroy(&(*A)->nearnullsp);
1204:   MatDestroy(&(*A)->schur);
1205:   PetscLayoutDestroy(&(*A)->rmap);
1206:   PetscLayoutDestroy(&(*A)->cmap);
1207:   PetscHeaderDestroy(A);
1208:   return(0);
1209: }

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

1216:    Not Collective

1218:    Input Parameters:
1219: +  mat - the matrix
1220: .  v - a logically two-dimensional array of values
1221: .  m, idxm - the number of rows and their global indices
1222: .  n, idxn - the number of columns and their global indices
1223: -  addv - either ADD_VALUES or INSERT_VALUES, where
1224:    ADD_VALUES adds values to any existing entries, and
1225:    INSERT_VALUES replaces existing entries with new values

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

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

1233:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1234:    options cannot be mixed without intervening calls to the assembly
1235:    routines.

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

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

1245:    Efficiency Alert:
1246:    The routine MatSetValuesBlocked() may offer much better efficiency
1247:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1249:    Level: beginner

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

1254:    Concepts: matrices^putting entries in

1256: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1257:           InsertMode, INSERT_VALUES, ADD_VALUES
1258: @*/
1259: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1260: {
1262: #if defined(PETSC_USE_DEBUG)
1263:   PetscInt       i,j;
1264: #endif

1269:   if (!m || !n) return(0); /* no values to insert */
1273:   MatCheckPreallocated(mat,1);
1274:   if (mat->insertmode == NOT_SET_VALUES) {
1275:     mat->insertmode = addv;
1276:   }
1277: #if defined(PETSC_USE_DEBUG)
1278:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1279:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1280:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);

1282:   for (i=0; i<m; i++) {
1283:     for (j=0; j<n; j++) {
1284:       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1285: #if defined(PETSC_USE_COMPLEX)
1286:         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]);
1287: #else
1288:         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1289: #endif
1290:     }
1291:   }
1292: #endif

1294:   if (mat->assembled) {
1295:     mat->was_assembled = PETSC_TRUE;
1296:     mat->assembled     = PETSC_FALSE;
1297:   }
1298:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1299:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1300:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1301: #if defined(PETSC_HAVE_CUSP)
1302:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1303:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1304:   }
1305: #elif defined(PETSC_HAVE_VIENNACL)
1306:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1307:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1308:   }
1309: #elif defined(PETSC_HAVE_VECCUDA)
1310:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1311:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1312:   }
1313: #endif
1314:   return(0);
1315: }


1318: /*@
1319:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1320:         values into a matrix

1322:    Not Collective

1324:    Input Parameters:
1325: +  mat - the matrix
1326: .  row - the (block) row to set
1327: -  v - a logically two-dimensional array of values

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

1332:    All the nonzeros in the row must be provided

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

1336:    The row must belong to this process

1338:    Level: intermediate

1340:    Concepts: matrices^putting entries in

1342: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1343:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1344: @*/
1345: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1346: {
1348:   PetscInt       globalrow;

1354:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1355:   MatSetValuesRow(mat,globalrow,v);
1356: #if defined(PETSC_HAVE_CUSP)
1357:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1358:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1359:   }
1360: #elif defined(PETSC_HAVE_VIENNACL)
1361:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1362:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1363:   }
1364: #elif defined(PETSC_HAVE_VECCUDA)
1365:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1366:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1367:   }
1368: #endif
1369:   return(0);
1370: }

1372: /*@
1373:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1374:         values into a matrix

1376:    Not Collective

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

1383:    Notes:
1384:    The values, v, are column-oriented for the block version.

1386:    All the nonzeros in the row must be provided

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

1390:    The row must belong to this process

1392:    Level: advanced

1394:    Concepts: matrices^putting entries in

1396: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1397:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1398: @*/
1399: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1400: {

1406:   MatCheckPreallocated(mat,1);
1408: #if defined(PETSC_USE_DEBUG)
1409:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1410:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1411: #endif
1412:   mat->insertmode = INSERT_VALUES;

1414:   if (mat->assembled) {
1415:     mat->was_assembled = PETSC_TRUE;
1416:     mat->assembled     = PETSC_FALSE;
1417:   }
1418:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1419:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1420:   (*mat->ops->setvaluesrow)(mat,row,v);
1421:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1422: #if defined(PETSC_HAVE_CUSP)
1423:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1424:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1425:   }
1426: #elif defined(PETSC_HAVE_VIENNACL)
1427:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1428:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1429:   }
1430: #elif defined(PETSC_HAVE_VECCUDA)
1431:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1432:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1433:   }
1434: #endif
1435:   return(0);
1436: }

1438: /*@
1439:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1440:      Using structured grid indexing

1442:    Not Collective

1444:    Input Parameters:
1445: +  mat - the matrix
1446: .  m - number of rows being entered
1447: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1448: .  n - number of columns being entered
1449: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1450: .  v - a logically two-dimensional array of values
1451: -  addv - either ADD_VALUES or INSERT_VALUES, where
1452:    ADD_VALUES adds values to any existing entries, and
1453:    INSERT_VALUES replaces existing entries with new values

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

1458:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1459:    options cannot be mixed without intervening calls to the assembly
1460:    routines.

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

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

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

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

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

1478:    In Fortran idxm and idxn should be declared as
1479: $     MatStencil idxm(4,m),idxn(4,n)
1480:    and the values inserted using
1481: $    idxm(MatStencil_i,1) = i
1482: $    idxm(MatStencil_j,1) = j
1483: $    idxm(MatStencil_k,1) = k
1484: $    idxm(MatStencil_c,1) = c
1485:    etc

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

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

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

1498:    Efficiency Alert:
1499:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1500:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1502:    Level: beginner

1504:    Concepts: matrices^putting entries in

1506: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1507:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1508: @*/
1509: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1510: {
1512:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1513:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1514:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1524:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1525:     jdxm = buf; jdxn = buf+m;
1526:   } else {
1527:     PetscMalloc2(m,&bufm,n,&bufn);
1528:     jdxm = bufm; jdxn = bufn;
1529:   }
1530:   for (i=0; i<m; i++) {
1531:     for (j=0; j<3-sdim; j++) dxm++;
1532:     tmp = *dxm++ - starts[0];
1533:     for (j=0; j<dim-1; j++) {
1534:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1535:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1536:     }
1537:     if (mat->stencil.noc) dxm++;
1538:     jdxm[i] = tmp;
1539:   }
1540:   for (i=0; i<n; i++) {
1541:     for (j=0; j<3-sdim; j++) dxn++;
1542:     tmp = *dxn++ - starts[0];
1543:     for (j=0; j<dim-1; j++) {
1544:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1545:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1546:     }
1547:     if (mat->stencil.noc) dxn++;
1548:     jdxn[i] = tmp;
1549:   }
1550:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1551:   PetscFree2(bufm,bufn);
1552:   return(0);
1553: }

1555: /*@
1556:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1557:      Using structured grid indexing

1559:    Not Collective

1561:    Input Parameters:
1562: +  mat - the matrix
1563: .  m - number of rows being entered
1564: .  idxm - grid coordinates for matrix rows being entered
1565: .  n - number of columns being entered
1566: .  idxn - grid coordinates for matrix columns being entered
1567: .  v - a logically two-dimensional array of values
1568: -  addv - either ADD_VALUES or INSERT_VALUES, where
1569:    ADD_VALUES adds values to any existing entries, and
1570:    INSERT_VALUES replaces existing entries with new values

1572:    Notes:
1573:    By default the values, v, are row-oriented and unsorted.
1574:    See MatSetOption() for other options.

1576:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1577:    options cannot be mixed without intervening calls to the assembly
1578:    routines.

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

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

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

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

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

1596:    In Fortran idxm and idxn should be declared as
1597: $     MatStencil idxm(4,m),idxn(4,n)
1598:    and the values inserted using
1599: $    idxm(MatStencil_i,1) = i
1600: $    idxm(MatStencil_j,1) = j
1601: $    idxm(MatStencil_k,1) = k
1602:    etc

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

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

1612:    Level: beginner

1614:    Concepts: matrices^putting entries in

1616: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1617:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1618:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1619: @*/
1620: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1621: {
1623:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1624:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1625:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1635:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1636:     jdxm = buf; jdxn = buf+m;
1637:   } else {
1638:     PetscMalloc2(m,&bufm,n,&bufn);
1639:     jdxm = bufm; jdxn = bufn;
1640:   }
1641:   for (i=0; i<m; i++) {
1642:     for (j=0; j<3-sdim; j++) dxm++;
1643:     tmp = *dxm++ - starts[0];
1644:     for (j=0; j<sdim-1; j++) {
1645:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1646:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1647:     }
1648:     dxm++;
1649:     jdxm[i] = tmp;
1650:   }
1651:   for (i=0; i<n; i++) {
1652:     for (j=0; j<3-sdim; j++) dxn++;
1653:     tmp = *dxn++ - starts[0];
1654:     for (j=0; j<sdim-1; j++) {
1655:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1656:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1657:     }
1658:     dxn++;
1659:     jdxn[i] = tmp;
1660:   }
1661:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1662:   PetscFree2(bufm,bufn);
1663: #if defined(PETSC_HAVE_CUSP)
1664:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1665:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1666:   }
1667: #elif defined(PETSC_HAVE_VIENNACL)
1668:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1669:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1670:   }
1671: #elif defined(PETSC_HAVE_VECCUDA)
1672:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1673:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1674:   }
1675: #endif
1676:   return(0);
1677: }

1679: /*@
1680:    MatSetStencil - Sets the grid information for setting values into a matrix via
1681:         MatSetValuesStencil()

1683:    Not Collective

1685:    Input Parameters:
1686: +  mat - the matrix
1687: .  dim - dimension of the grid 1, 2, or 3
1688: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1689: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1690: -  dof - number of degrees of freedom per node


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

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

1699:    Level: beginner

1701:    Concepts: matrices^putting entries in

1703: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1704:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1705: @*/
1706: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1707: {
1708:   PetscInt i;


1715:   mat->stencil.dim = dim + (dof > 1);
1716:   for (i=0; i<dim; i++) {
1717:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1718:     mat->stencil.starts[i] = starts[dim-i-1];
1719:   }
1720:   mat->stencil.dims[dim]   = dof;
1721:   mat->stencil.starts[dim] = 0;
1722:   mat->stencil.noc         = (PetscBool)(dof == 1);
1723:   return(0);
1724: }

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

1729:    Not Collective

1731:    Input Parameters:
1732: +  mat - the matrix
1733: .  v - a logically two-dimensional array of values
1734: .  m, idxm - the number of block rows and their global block indices
1735: .  n, idxn - the number of block columns and their global block indices
1736: -  addv - either ADD_VALUES or INSERT_VALUES, where
1737:    ADD_VALUES adds values to any existing entries, and
1738:    INSERT_VALUES replaces existing entries with new values

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

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

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

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

1756:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1757:    options cannot be mixed without intervening calls to the assembly
1758:    routines.

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

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

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

1774:    Example:
1775: $   Suppose m=n=2 and block size(bs) = 2 The array is
1776: $
1777: $   1  2  | 3  4
1778: $   5  6  | 7  8
1779: $   - - - | - - -
1780: $   9  10 | 11 12
1781: $   13 14 | 15 16
1782: $
1783: $   v[] should be passed in like
1784: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1785: $
1786: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1787: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

1789:    Level: intermediate

1791:    Concepts: matrices^putting entries in blocked

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

1802:   if (!m || !n) return(0); /* no values to insert */
1806:   MatCheckPreallocated(mat,1);
1807:   if (mat->insertmode == NOT_SET_VALUES) {
1808:     mat->insertmode = addv;
1809:   }
1810: #if defined(PETSC_USE_DEBUG)
1811:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1812:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1813:   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1814: #endif

1816:   if (mat->assembled) {
1817:     mat->was_assembled = PETSC_TRUE;
1818:     mat->assembled     = PETSC_FALSE;
1819:   }
1820:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1821:   if (mat->ops->setvaluesblocked) {
1822:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1823:   } else {
1824:     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1825:     PetscInt i,j,bs,cbs;
1826:     MatGetBlockSizes(mat,&bs,&cbs);
1827:     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1828:       iidxm = buf; iidxn = buf + m*bs;
1829:     } else {
1830:       PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1831:       iidxm = bufr; iidxn = bufc;
1832:     }
1833:     for (i=0; i<m; i++) {
1834:       for (j=0; j<bs; j++) {
1835:         iidxm[i*bs+j] = bs*idxm[i] + j;
1836:       }
1837:     }
1838:     for (i=0; i<n; i++) {
1839:       for (j=0; j<cbs; j++) {
1840:         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1841:       }
1842:     }
1843:     MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1844:     PetscFree2(bufr,bufc);
1845:   }
1846:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1847: #if defined(PETSC_HAVE_CUSP)
1848:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1849:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1850:   }
1851: #elif defined(PETSC_HAVE_VIENNACL)
1852:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1853:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1854:   }
1855: #elif defined(PETSC_HAVE_VECCUDA)
1856:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1857:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1858:   }
1859: #endif
1860:   return(0);
1861: }

1863: /*@
1864:    MatGetValues - Gets a block of values from a matrix.

1866:    Not Collective; currently only returns a local block

1868:    Input Parameters:
1869: +  mat - the matrix
1870: .  v - a logically two-dimensional array for storing the values
1871: .  m, idxm - the number of rows and their global indices
1872: -  n, idxn - the number of columns and their global indices

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

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

1882:    MatGetValues() requires that the matrix has been assembled
1883:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1884:    MatSetValues() and MatGetValues() CANNOT be made in succession
1885:    without intermediate matrix assembly.

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

1890:    Level: advanced

1892:    Concepts: matrices^accessing values

1894: .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1895: @*/
1896: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1897: {

1903:   if (!m || !n) return(0);
1907:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1908:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1909:   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1910:   MatCheckPreallocated(mat,1);

1912:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1913:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1914:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1915:   return(0);
1916: }

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

1922:   Not Collective

1924:   Input Parameters:
1925: + mat - the matrix
1926: . nb - the number of blocks
1927: . bs - the number of rows (and columns) in each block
1928: . rows - a concatenation of the rows for each block
1929: - v - a concatenation of logically two-dimensional arrays of values

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

1934:   Level: advanced

1936:   Concepts: matrices^putting entries in

1938: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1939:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1940: @*/
1941: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1942: {

1950: #if defined(PETSC_USE_DEBUG)
1951:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1952: #endif

1954:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1955:   if (mat->ops->setvaluesbatch) {
1956:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1957:   } else {
1958:     PetscInt b;
1959:     for (b = 0; b < nb; ++b) {
1960:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1961:     }
1962:   }
1963:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1964:   return(0);
1965: }

1967: /*@
1968:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1969:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1970:    using a local (per-processor) numbering.

1972:    Not Collective

1974:    Input Parameters:
1975: +  x - the matrix
1976: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1977: - cmapping - column mapping

1979:    Level: intermediate

1981:    Concepts: matrices^local to global mapping
1982:    Concepts: local to global mapping^for matrices

1984: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1985: @*/
1986: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1987: {


1996:   if (x->ops->setlocaltoglobalmapping) {
1997:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1998:   } else {
1999:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
2000:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
2001:   }
2002:   return(0);
2003: }


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

2009:    Not Collective

2011:    Input Parameters:
2012: .  A - the matrix

2014:    Output Parameters:
2015: + rmapping - row mapping
2016: - cmapping - column mapping

2018:    Level: advanced

2020:    Concepts: matrices^local to global mapping
2021:    Concepts: local to global mapping^for matrices

2023: .seealso:  MatSetValuesLocal()
2024: @*/
2025: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2026: {
2032:   if (rmapping) *rmapping = A->rmap->mapping;
2033:   if (cmapping) *cmapping = A->cmap->mapping;
2034:   return(0);
2035: }

2037: /*@
2038:    MatGetLayouts - Gets the PetscLayout objects for rows and columns

2040:    Not Collective

2042:    Input Parameters:
2043: .  A - the matrix

2045:    Output Parameters:
2046: + rmap - row layout
2047: - cmap - column layout

2049:    Level: advanced

2051: .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2052: @*/
2053: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2054: {
2060:   if (rmap) *rmap = A->rmap;
2061:   if (cmap) *cmap = A->cmap;
2062:   return(0);
2063: }

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

2069:    Not Collective

2071:    Input Parameters:
2072: +  mat - the matrix
2073: .  nrow, irow - number of rows and their local indices
2074: .  ncol, icol - number of columns and their local indices
2075: .  y -  a logically two-dimensional array of values
2076: -  addv - either INSERT_VALUES or ADD_VALUES, where
2077:    ADD_VALUES adds values to any existing entries, and
2078:    INSERT_VALUES replaces existing entries with new values

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

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

2086:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2087:    options cannot be mixed without intervening calls to the assembly
2088:    routines.

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

2093:    Level: intermediate

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

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

2100: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2101:            MatSetValueLocal()
2102: @*/
2103: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2104: {

2110:   MatCheckPreallocated(mat,1);
2111:   if (!nrow || !ncol) return(0); /* no values to insert */
2115:   if (mat->insertmode == NOT_SET_VALUES) {
2116:     mat->insertmode = addv;
2117:   }
2118: #if defined(PETSC_USE_DEBUG)
2119:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2120:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2121:   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2122: #endif

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

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

2165:    Not Collective

2167:    Input Parameters:
2168: +  x - the matrix
2169: .  nrow, irow - number of rows and their local indices
2170: .  ncol, icol - number of columns and their local indices
2171: .  y -  a logically two-dimensional array of values
2172: -  addv - either INSERT_VALUES or ADD_VALUES, where
2173:    ADD_VALUES adds values to any existing entries, and
2174:    INSERT_VALUES replaces existing entries with new values

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

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

2183:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2184:    options cannot be mixed without intervening calls to the assembly
2185:    routines.

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

2190:    Level: intermediate

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

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

2197: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2198:            MatSetValuesLocal(),  MatSetValuesBlocked()
2199: @*/
2200: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2201: {

2207:   MatCheckPreallocated(mat,1);
2208:   if (!nrow || !ncol) return(0); /* no values to insert */
2212:   if (mat->insertmode == NOT_SET_VALUES) {
2213:     mat->insertmode = addv;
2214:   }
2215: #if defined(PETSC_USE_DEBUG)
2216:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2217:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2218:   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);
2219: #endif

2221:   if (mat->assembled) {
2222:     mat->was_assembled = PETSC_TRUE;
2223:     mat->assembled     = PETSC_FALSE;
2224:   }
2225:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2226:   if (mat->ops->setvaluesblockedlocal) {
2227:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2228:   } else {
2229:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2230:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2231:       irowm = buf; icolm = buf + nrow;
2232:     } else {
2233:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2234:       irowm = bufr; icolm = bufc;
2235:     }
2236:     ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2237:     ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2238:     MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2239:     PetscFree2(bufr,bufc);
2240:   }
2241:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2242: #if defined(PETSC_HAVE_CUSP)
2243:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2244:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2245:   }
2246: #elif defined(PETSC_HAVE_VIENNACL)
2247:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2248:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2249:   }
2250: #elif defined(PETSC_HAVE_VECCUDA)
2251:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2252:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2253:   }
2254: #endif
2255:   return(0);
2256: }

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

2261:    Collective on Mat and Vec

2263:    Input Parameters:
2264: +  mat - the matrix
2265: -  x   - the vector to be multiplied

2267:    Output Parameters:
2268: .  y - the result

2270:    Notes:
2271:    The vectors x and y cannot be the same.  I.e., one cannot
2272:    call MatMult(A,y,y).

2274:    Level: developer

2276:    Concepts: matrix-vector product

2278: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2279: @*/
2280: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2281: {


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

2295:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2296:   (*mat->ops->multdiagonalblock)(mat,x,y);
2297:   PetscObjectStateIncrease((PetscObject)y);
2298:   return(0);
2299: }

2301: /* --------------------------------------------------------*/
2302: /*@
2303:    MatMult - Computes the matrix-vector product, y = Ax.

2305:    Neighbor-wise Collective on Mat and Vec

2307:    Input Parameters:
2308: +  mat - the matrix
2309: -  x   - the vector to be multiplied

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

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

2318:    Level: beginner

2320:    Concepts: matrix-vector product

2322: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2323: @*/
2324: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2325: {

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

2345:   VecLockPush(x);
2346:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2347:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2348:   (*mat->ops->mult)(mat,x,y);
2349:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2350:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2351:   VecLockPop(x);
2352:   return(0);
2353: }

2355: /*@
2356:    MatMultTranspose - Computes matrix transpose times a vector.

2358:    Neighbor-wise Collective on Mat and Vec

2360:    Input Parameters:
2361: +  mat - the matrix
2362: -  x   - the vector to be multilplied

2364:    Output Parameters:
2365: .  y - the result

2367:    Notes:
2368:    The vectors x and y cannot be the same.  I.e., one cannot
2369:    call MatMultTranspose(A,y,y).

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

2374:    Level: beginner

2376:    Concepts: matrix vector product^transpose

2378: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2379: @*/
2380: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2381: {


2390:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2391:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2392:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2393: #if !defined(PETSC_HAVE_CONSTRAINTS)
2394:   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);
2395:   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);
2396: #endif
2397:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2398:   MatCheckPreallocated(mat,1);

2400:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2401:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2402:   VecLockPush(x);
2403:   (*mat->ops->multtranspose)(mat,x,y);
2404:   VecLockPop(x);
2405:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2406:   PetscObjectStateIncrease((PetscObject)y);
2407:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2408:   return(0);
2409: }

2411: /*@
2412:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2414:    Neighbor-wise Collective on Mat and Vec

2416:    Input Parameters:
2417: +  mat - the matrix
2418: -  x   - the vector to be multilplied

2420:    Output Parameters:
2421: .  y - the result

2423:    Notes:
2424:    The vectors x and y cannot be the same.  I.e., one cannot
2425:    call MatMultHermitianTranspose(A,y,y).

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

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

2431:    Level: beginner

2433:    Concepts: matrix vector product^transpose

2435: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2436: @*/
2437: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2438: {
2440:   Vec            w;


2448:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2449:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2450:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2451: #if !defined(PETSC_HAVE_CONSTRAINTS)
2452:   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);
2453:   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);
2454: #endif
2455:   MatCheckPreallocated(mat,1);

2457:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2458:   if (mat->ops->multhermitiantranspose) {
2459:     VecLockPush(x);
2460:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2461:     VecLockPop(x);
2462:   } else {
2463:     VecDuplicate(x,&w);
2464:     VecCopy(x,w);
2465:     VecConjugate(w);
2466:     MatMultTranspose(mat,w,y);
2467:     VecDestroy(&w);
2468:     VecConjugate(y);
2469:   }
2470:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2471:   PetscObjectStateIncrease((PetscObject)y);
2472:   return(0);
2473: }

2475: /*@
2476:     MatMultAdd -  Computes v3 = v2 + A * v1.

2478:     Neighbor-wise Collective on Mat and Vec

2480:     Input Parameters:
2481: +   mat - the matrix
2482: -   v1, v2 - the vectors

2484:     Output Parameters:
2485: .   v3 - the result

2487:     Notes:
2488:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2489:     call MatMultAdd(A,v1,v2,v1).

2491:     Level: beginner

2493:     Concepts: matrix vector product^addition

2495: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2496: @*/
2497: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2498: {


2508:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2509:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2510:   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);
2511:   /* 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);
2512:      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); */
2513:   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);
2514:   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);
2515:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2516:   MatCheckPreallocated(mat,1);

2518:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2519:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2520:   VecLockPush(v1);
2521:   (*mat->ops->multadd)(mat,v1,v2,v3);
2522:   VecLockPop(v1);
2523:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2524:   PetscObjectStateIncrease((PetscObject)v3);
2525:   return(0);
2526: }

2528: /*@
2529:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2531:    Neighbor-wise Collective on Mat and Vec

2533:    Input Parameters:
2534: +  mat - the matrix
2535: -  v1, v2 - the vectors

2537:    Output Parameters:
2538: .  v3 - the result

2540:    Notes:
2541:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2542:    call MatMultTransposeAdd(A,v1,v2,v1).

2544:    Level: beginner

2546:    Concepts: matrix vector product^transpose and addition

2548: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2549: @*/
2550: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2551: {


2561:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2562:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2563:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2564:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2565:   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);
2566:   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);
2567:   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);
2568:   MatCheckPreallocated(mat,1);

2570:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2571:   VecLockPush(v1);
2572:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2573:   VecLockPop(v1);
2574:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2575:   PetscObjectStateIncrease((PetscObject)v3);
2576:   return(0);
2577: }

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

2582:    Neighbor-wise Collective on Mat and Vec

2584:    Input Parameters:
2585: +  mat - the matrix
2586: -  v1, v2 - the vectors

2588:    Output Parameters:
2589: .  v3 - the result

2591:    Notes:
2592:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2593:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2595:    Level: beginner

2597:    Concepts: matrix vector product^transpose and addition

2599: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2600: @*/
2601: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2602: {


2612:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2613:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2614:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2615:   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);
2616:   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);
2617:   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);
2618:   MatCheckPreallocated(mat,1);

2620:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2621:   VecLockPush(v1);
2622:   if (mat->ops->multhermitiantransposeadd) {
2623:     (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2624:    } else {
2625:     Vec w,z;
2626:     VecDuplicate(v1,&w);
2627:     VecCopy(v1,w);
2628:     VecConjugate(w);
2629:     VecDuplicate(v3,&z);
2630:     MatMultTranspose(mat,w,z);
2631:     VecDestroy(&w);
2632:     VecConjugate(z);
2633:     VecWAXPY(v3,1.0,v2,z);
2634:     VecDestroy(&z);
2635:   }
2636:   VecLockPop(v1);
2637:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2638:   PetscObjectStateIncrease((PetscObject)v3);
2639:   return(0);
2640: }

2642: /*@
2643:    MatMultConstrained - The inner multiplication routine for a
2644:    constrained matrix P^T A P.

2646:    Neighbor-wise Collective on Mat and Vec

2648:    Input Parameters:
2649: +  mat - the matrix
2650: -  x   - the vector to be multilplied

2652:    Output Parameters:
2653: .  y - the result

2655:    Notes:
2656:    The vectors x and y cannot be the same.  I.e., one cannot
2657:    call MatMult(A,y,y).

2659:    Level: beginner

2661: .keywords: matrix, multiply, matrix-vector product, constraint
2662: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2663: @*/
2664: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2665: {

2672:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2673:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2674:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2675:   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);
2676:   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);
2677:   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);

2679:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2680:   VecLockPush(x);
2681:   (*mat->ops->multconstrained)(mat,x,y);
2682:   VecLockPop(x);
2683:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2684:   PetscObjectStateIncrease((PetscObject)y);
2685:   return(0);
2686: }

2688: /*@
2689:    MatMultTransposeConstrained - The inner multiplication routine for a
2690:    constrained matrix P^T A^T P.

2692:    Neighbor-wise Collective on Mat and Vec

2694:    Input Parameters:
2695: +  mat - the matrix
2696: -  x   - the vector to be multilplied

2698:    Output Parameters:
2699: .  y - the result

2701:    Notes:
2702:    The vectors x and y cannot be the same.  I.e., one cannot
2703:    call MatMult(A,y,y).

2705:    Level: beginner

2707: .keywords: matrix, multiply, matrix-vector product, constraint
2708: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2709: @*/
2710: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2711: {

2718:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2719:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2720:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2721:   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);
2722:   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);

2724:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2725:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2726:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2727:   PetscObjectStateIncrease((PetscObject)y);
2728:   return(0);
2729: }

2731: /*@C
2732:    MatGetFactorType - gets the type of factorization it is

2734:    Note Collective
2735:    as the flag

2737:    Input Parameters:
2738: .  mat - the matrix

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

2743:     Level: intermediate

2745: .seealso:    MatFactorType, MatGetFactor()
2746: @*/
2747: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2748: {
2752:   *t = mat->factortype;
2753:   return(0);
2754: }

2756: /* ------------------------------------------------------------*/
2757: /*@C
2758:    MatGetInfo - Returns information about matrix storage (number of
2759:    nonzeros, memory, etc.).

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

2763:    Input Parameters:
2764: .  mat - the matrix

2766:    Output Parameters:
2767: +  flag - flag indicating the type of parameters to be returned
2768:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2769:    MAT_GLOBAL_SUM - sum over all processors)
2770: -  info - matrix information context

2772:    Notes:
2773:    The MatInfo context contains a variety of matrix data, including
2774:    number of nonzeros allocated and used, number of mallocs during
2775:    matrix assembly, etc.  Additional information for factored matrices
2776:    is provided (such as the fill ratio, number of mallocs during
2777:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2778:    when using the runtime options
2779: $       -info -mat_view ::ascii_info

2781:    Example for C/C++ Users:
2782:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2783:    data within the MatInfo context.  For example,
2784: .vb
2785:       MatInfo info;
2786:       Mat     A;
2787:       double  mal, nz_a, nz_u;

2789:       MatGetInfo(A,MAT_LOCAL,&info);
2790:       mal  = info.mallocs;
2791:       nz_a = info.nz_allocated;
2792: .ve

2794:    Example for Fortran Users:
2795:    Fortran users should declare info as a double precision
2796:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2797:    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2798:    a complete list of parameter names.
2799: .vb
2800:       double  precision info(MAT_INFO_SIZE)
2801:       double  precision mal, nz_a
2802:       Mat     A
2803:       integer ierr

2805:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2806:       mal = info(MAT_INFO_MALLOCS)
2807:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2808: .ve

2810:     Level: intermediate

2812:     Concepts: matrices^getting information on

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

2817: .seealso: MatStashGetInfo()

2819: @*/
2820: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2821: {

2828:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2829:   MatCheckPreallocated(mat,1);
2830:   (*mat->ops->getinfo)(mat,flag,info);
2831:   return(0);
2832: }

2834: /*
2835:    This is used by external packages where it is not easy to get the info from the actual
2836:    matrix factorization.
2837: */
2838: PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2839: {

2843:   PetscMemzero(info,sizeof(MatInfo));
2844:   return(0);
2845: }

2847: /* ----------------------------------------------------------*/

2849: /*@C
2850:    MatLUFactor - Performs in-place LU factorization of matrix.

2852:    Collective on Mat

2854:    Input Parameters:
2855: +  mat - the matrix
2856: .  row - row permutation
2857: .  col - column permutation
2858: -  info - options for factorization, includes
2859: $          fill - expected fill as ratio of original fill.
2860: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2861: $                   Run with the option -info to determine an optimal value to use

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

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

2871:    Level: developer

2873:    Concepts: matrices^LU factorization

2875: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2876:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2881: @*/
2882: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2883: {
2885:   MatFactorInfo  tinfo;

2893:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2894:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2895:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2896:   MatCheckPreallocated(mat,1);
2897:   if (!info) {
2898:     MatFactorInfoInitialize(&tinfo);
2899:     info = &tinfo;
2900:   }

2902:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2903:   (*mat->ops->lufactor)(mat,row,col,info);
2904:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2905:   PetscObjectStateIncrease((PetscObject)mat);
2906:   return(0);
2907: }

2909: /*@C
2910:    MatILUFactor - Performs in-place ILU factorization of matrix.

2912:    Collective on Mat

2914:    Input Parameters:
2915: +  mat - the matrix
2916: .  row - row permutation
2917: .  col - column permutation
2918: -  info - structure containing
2919: $      levels - number of levels of fill.
2920: $      expected fill - as ratio of original fill.
2921: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2922:                 missing diagonal entries)

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

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

2932:    Level: developer

2934:    Concepts: matrices^ILU factorization

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

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

2941: @*/
2942: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2943: {

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

2958:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2959:   (*mat->ops->ilufactor)(mat,row,col,info);
2960:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2961:   PetscObjectStateIncrease((PetscObject)mat);
2962:   return(0);
2963: }

2965: /*@C
2966:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2967:    Call this routine before calling MatLUFactorNumeric().

2969:    Collective on Mat

2971:    Input Parameters:
2972: +  fact - the factor matrix obtained with MatGetFactor()
2973: .  mat - the matrix
2974: .  row, col - row and column permutations
2975: -  info - options for factorization, includes
2976: $          fill - expected fill as ratio of original fill.
2977: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2978: $                   Run with the option -info to determine an optimal value to use


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

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

2987:    Level: developer

2989:    Concepts: matrices^LU symbolic factorization

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

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

2996: @*/
2997: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2998: {

3008:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3009:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3010:   if (!(fact)->ops->lufactorsymbolic) {
3011:     const MatSolverPackage spackage;
3012:     MatFactorGetSolverPackage(fact,&spackage);
3013:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3014:   }
3015:   MatCheckPreallocated(mat,2);

3017:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
3018:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
3019:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
3020:   PetscObjectStateIncrease((PetscObject)fact);
3021:   return(0);
3022: }

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

3028:    Collective on Mat

3030:    Input Parameters:
3031: +  fact - the factor matrix obtained with MatGetFactor()
3032: .  mat - the matrix
3033: -  info - options for factorization

3035:    Notes:
3036:    See MatLUFactor() for in-place factorization.  See
3037:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

3043:    Level: developer

3045:    Concepts: matrices^LU numeric factorization

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

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

3052: @*/
3053: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3054: {

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

3065:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3066:   MatCheckPreallocated(mat,2);
3067:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
3068:   (fact->ops->lufactornumeric)(fact,mat,info);
3069:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
3070:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3071:   PetscObjectStateIncrease((PetscObject)fact);
3072:   return(0);
3073: }

3075: /*@C
3076:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3077:    symmetric matrix.

3079:    Collective on Mat

3081:    Input Parameters:
3082: +  mat - the matrix
3083: .  perm - row and column permutations
3084: -  f - expected fill as ratio of original fill

3086:    Notes:
3087:    See MatLUFactor() for the nonsymmetric case.  See also
3088:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

3094:    Level: developer

3096:    Concepts: matrices^Cholesky factorization

3098: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3099:           MatGetOrdering()

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

3104: @*/
3105: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3106: {

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

3120:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3121:   (*mat->ops->choleskyfactor)(mat,perm,info);
3122:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3123:   PetscObjectStateIncrease((PetscObject)mat);
3124:   return(0);
3125: }

3127: /*@C
3128:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3129:    of a symmetric matrix.

3131:    Collective on Mat

3133:    Input Parameters:
3134: +  fact - the factor matrix obtained with MatGetFactor()
3135: .  mat - the matrix
3136: .  perm - row and column permutations
3137: -  info - options for factorization, includes
3138: $          fill - expected fill as ratio of original fill.
3139: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3140: $                   Run with the option -info to determine an optimal value to use

3142:    Notes:
3143:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3144:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

3150:    Level: developer

3152:    Concepts: matrices^Cholesky symbolic factorization

3154: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3155:           MatGetOrdering()

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

3160: @*/
3161: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3162: {

3171:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3172:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3173:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3174:   if (!(fact)->ops->choleskyfactorsymbolic) {
3175:     const MatSolverPackage spackage;
3176:     MatFactorGetSolverPackage(fact,&spackage);
3177:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3178:   }
3179:   MatCheckPreallocated(mat,2);

3181:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3182:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3183:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3184:   PetscObjectStateIncrease((PetscObject)fact);
3185:   return(0);
3186: }

3188: /*@C
3189:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3190:    of a symmetric matrix. Call this routine after first calling
3191:    MatCholeskyFactorSymbolic().

3193:    Collective on Mat

3195:    Input Parameters:
3196: +  fact - the factor matrix obtained with MatGetFactor()
3197: .  mat - the initial matrix
3198: .  info - options for factorization
3199: -  fact - the symbolic factor of mat


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

3207:    Level: developer

3209:    Concepts: matrices^Cholesky numeric factorization

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

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

3216: @*/
3217: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3218: {

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

3231:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3232:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3233:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3234:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3235:   PetscObjectStateIncrease((PetscObject)fact);
3236:   return(0);
3237: }

3239: /* ----------------------------------------------------------------*/
3240: /*@
3241:    MatSolve - Solves A x = b, given a factored matrix.

3243:    Neighbor-wise Collective on Mat and Vec

3245:    Input Parameters:
3246: +  mat - the factored matrix
3247: -  b - the right-hand-side vector

3249:    Output Parameter:
3250: .  x - the result vector

3252:    Notes:
3253:    The vectors b and x cannot be the same.  I.e., one cannot
3254:    call MatSolve(A,x,x).

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

3261:    Level: developer

3263:    Concepts: matrices^triangular solves

3265: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3266: @*/
3267: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3268: {

3278:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3279:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3280:   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);
3281:   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);
3282:   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);
3283:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3284:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3285:   MatCheckPreallocated(mat,1);

3287:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3288:   if (mat->factorerrortype) {
3289:     PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3290:     VecSetInf(x);
3291:   } else {
3292:     (*mat->ops->solve)(mat,b,x);
3293:   }
3294:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3295:   PetscObjectStateIncrease((PetscObject)x);
3296:   return(0);
3297: }

3299: static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3300: {
3302:   Vec            b,x;
3303:   PetscInt       m,N,i;
3304:   PetscScalar    *bb,*xx;
3305:   PetscBool      flg;

3308:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3309:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3310:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3311:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3313:   MatDenseGetArray(B,&bb);
3314:   MatDenseGetArray(X,&xx);
3315:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3316:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3317:   MatCreateVecs(A,&x,&b);
3318:   for (i=0; i<N; i++) {
3319:     VecPlaceArray(b,bb + i*m);
3320:     VecPlaceArray(x,xx + i*m);
3321:     if (trans) {
3322:       MatSolveTranspose(A,b,x);
3323:     } else {
3324:       MatSolve(A,b,x);
3325:     }
3326:     VecResetArray(x);
3327:     VecResetArray(b);
3328:   }
3329:   VecDestroy(&b);
3330:   VecDestroy(&x);
3331:   MatDenseRestoreArray(B,&bb);
3332:   MatDenseRestoreArray(X,&xx);
3333:   return(0);
3334: }

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

3339:    Neighbor-wise Collective on Mat

3341:    Input Parameters:
3342: +  A - the factored matrix
3343: -  B - the right-hand-side matrix  (dense matrix)

3345:    Output Parameter:
3346: .  X - the result matrix (dense matrix)

3348:    Notes:
3349:    The matrices b and x cannot be the same.  I.e., one cannot
3350:    call MatMatSolve(A,x,x).

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

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

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

3363:    Level: developer

3365:    Concepts: matrices^triangular solves

3367: .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3368: @*/
3369: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3370: {

3380:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3381:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3382:   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);
3383:   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);
3384:   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);
3385:   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");
3386:   if (!A->rmap->N && !A->cmap->N) return(0);
3387:   MatCheckPreallocated(A,1);

3389:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3390:   if (!A->ops->matsolve) {
3391:     PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3392:     MatMatSolve_Basic(A,B,X,PETSC_FALSE);
3393:   } else {
3394:     (*A->ops->matsolve)(A,B,X);
3395:   }
3396:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3397:   PetscObjectStateIncrease((PetscObject)X);
3398:   return(0);
3399: }

3401: /*@
3402:    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.

3404:    Neighbor-wise Collective on Mat

3406:    Input Parameters:
3407: +  A - the factored matrix
3408: -  B - the right-hand-side matrix  (dense matrix)

3410:    Output Parameter:
3411: .  X - the result matrix (dense matrix)

3413:    Notes:
3414:    The matrices b and x cannot be the same.  I.e., one cannot
3415:    call MatMatSolveTranspose(A,x,x).

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

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

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

3428:    Level: developer

3430:    Concepts: matrices^triangular solves

3432: .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3433: @*/
3434: PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3435: {

3445:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3446:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3447:   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);
3448:   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);
3449:   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);
3450:   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");
3451:   if (!A->rmap->N && !A->cmap->N) return(0);
3452:   MatCheckPreallocated(A,1);

3454:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3455:   if (!A->ops->matsolvetranspose) {
3456:     PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);
3457:     MatMatSolve_Basic(A,B,X,PETSC_TRUE);
3458:   } else {
3459:     (*A->ops->matsolvetranspose)(A,B,X);
3460:   }
3461:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3462:   PetscObjectStateIncrease((PetscObject)X);
3463:   return(0);
3464: }

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

3470:    Neighbor-wise Collective on Mat and Vec

3472:    Input Parameters:
3473: +  mat - the factored matrix
3474: -  b - the right-hand-side vector

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

3479:    Notes:
3480:    MatSolve() should be used for most applications, as it performs
3481:    a forward solve followed by a backward solve.

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

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

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

3496:    Level: developer

3498:    Concepts: matrices^forward solves

3500: .seealso: MatSolve(), MatBackwardSolve()
3501: @*/
3502: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3503: {

3513:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3514:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3515:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3516:   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);
3517:   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);
3518:   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);
3519:   MatCheckPreallocated(mat,1);
3520:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3521:   (*mat->ops->forwardsolve)(mat,b,x);
3522:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3523:   PetscObjectStateIncrease((PetscObject)x);
3524:   return(0);
3525: }

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

3531:    Neighbor-wise Collective on Mat and Vec

3533:    Input Parameters:
3534: +  mat - the factored matrix
3535: -  b - the right-hand-side vector

3537:    Output Parameter:
3538: .  x - the result vector

3540:    Notes:
3541:    MatSolve() should be used for most applications, as it performs
3542:    a forward solve followed by a backward solve.

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

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

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

3557:    Level: developer

3559:    Concepts: matrices^backward solves

3561: .seealso: MatSolve(), MatForwardSolve()
3562: @*/
3563: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3564: {

3574:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3575:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3576:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3577:   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);
3578:   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);
3579:   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);
3580:   MatCheckPreallocated(mat,1);

3582:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3583:   (*mat->ops->backwardsolve)(mat,b,x);
3584:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3585:   PetscObjectStateIncrease((PetscObject)x);
3586:   return(0);
3587: }

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

3592:    Neighbor-wise Collective on Mat and Vec

3594:    Input Parameters:
3595: +  mat - the factored matrix
3596: .  b - the right-hand-side vector
3597: -  y - the vector to be added to

3599:    Output Parameter:
3600: .  x - the result vector

3602:    Notes:
3603:    The vectors b and x cannot be the same.  I.e., one cannot
3604:    call MatSolveAdd(A,x,y,x).

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

3610:    Level: developer

3612:    Concepts: matrices^triangular solves

3614: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3615: @*/
3616: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3617: {
3618:   PetscScalar    one = 1.0;
3619:   Vec            tmp;

3631:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3632:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3633:   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);
3634:   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);
3635:   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);
3636:   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);
3637:   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);
3638:   MatCheckPreallocated(mat,1);

3640:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3641:   if (mat->ops->solveadd) {
3642:     (*mat->ops->solveadd)(mat,b,y,x);
3643:   } else {
3644:     /* do the solve then the add manually */
3645:     if (x != y) {
3646:       MatSolve(mat,b,x);
3647:       VecAXPY(x,one,y);
3648:     } else {
3649:       VecDuplicate(x,&tmp);
3650:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3651:       VecCopy(x,tmp);
3652:       MatSolve(mat,b,x);
3653:       VecAXPY(x,one,tmp);
3654:       VecDestroy(&tmp);
3655:     }
3656:   }
3657:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3658:   PetscObjectStateIncrease((PetscObject)x);
3659:   return(0);
3660: }

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

3665:    Neighbor-wise Collective on Mat and Vec

3667:    Input Parameters:
3668: +  mat - the factored matrix
3669: -  b - the right-hand-side vector

3671:    Output Parameter:
3672: .  x - the result vector

3674:    Notes:
3675:    The vectors b and x cannot be the same.  I.e., one cannot
3676:    call MatSolveTranspose(A,x,x).

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

3682:    Level: developer

3684:    Concepts: matrices^triangular solves

3686: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3687: @*/
3688: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3689: {

3699:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3700:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3701:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3702:   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);
3703:   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);
3704:   MatCheckPreallocated(mat,1);
3705:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3706:   if (mat->factorerrortype) {
3707:     PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3708:     VecSetInf(x);
3709:   } else {
3710:     (*mat->ops->solvetranspose)(mat,b,x);
3711:   }
3712:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3713:   PetscObjectStateIncrease((PetscObject)x);
3714:   return(0);
3715: }

3717: /*@
3718:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3719:                       factored matrix.

3721:    Neighbor-wise Collective on Mat and Vec

3723:    Input Parameters:
3724: +  mat - the factored matrix
3725: .  b - the right-hand-side vector
3726: -  y - the vector to be added to

3728:    Output Parameter:
3729: .  x - the result vector

3731:    Notes:
3732:    The vectors b and x cannot be the same.  I.e., one cannot
3733:    call MatSolveTransposeAdd(A,x,y,x).

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

3739:    Level: developer

3741:    Concepts: matrices^triangular solves

3743: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3744: @*/
3745: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3746: {
3747:   PetscScalar    one = 1.0;
3749:   Vec            tmp;

3760:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3761:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3762:   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);
3763:   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);
3764:   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);
3765:   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);
3766:   MatCheckPreallocated(mat,1);

3768:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3769:   if (mat->ops->solvetransposeadd) {
3770:     if (mat->factorerrortype) {
3771:       PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3772:       VecSetInf(x);
3773:     } else {
3774:       (*mat->ops->solvetransposeadd)(mat,b,y,x);
3775:     }
3776:   } else {
3777:     /* do the solve then the add manually */
3778:     if (x != y) {
3779:       MatSolveTranspose(mat,b,x);
3780:       VecAXPY(x,one,y);
3781:     } else {
3782:       VecDuplicate(x,&tmp);
3783:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3784:       VecCopy(x,tmp);
3785:       MatSolveTranspose(mat,b,x);
3786:       VecAXPY(x,one,tmp);
3787:       VecDestroy(&tmp);
3788:     }
3789:   }
3790:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3791:   PetscObjectStateIncrease((PetscObject)x);
3792:   return(0);
3793: }
3794: /* ----------------------------------------------------------------*/

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

3799:    Neighbor-wise Collective on Mat and Vec

3801:    Input Parameters:
3802: +  mat - the matrix
3803: .  b - the right hand side
3804: .  omega - the relaxation factor
3805: .  flag - flag indicating the type of SOR (see below)
3806: .  shift -  diagonal shift
3807: .  its - the number of iterations
3808: -  lits - the number of local iterations

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

3813:    SOR Flags:
3814: .     SOR_FORWARD_SWEEP - forward SOR
3815: .     SOR_BACKWARD_SWEEP - backward SOR
3816: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3817: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3818: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3819: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3820: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3821:          upper/lower triangular part of matrix to
3822:          vector (with omega)
3823: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3825:    Notes:
3826:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3827:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3828:    on each processor.

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

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

3835:    Notes for Advanced Users:
3836:    The flags are implemented as bitwise inclusive or operations.
3837:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3838:    to specify a zero initial guess for SSOR.

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

3844:    Vectors x and b CANNOT be the same

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

3848:    Level: developer

3850:    Concepts: matrices^relaxation
3851:    Concepts: matrices^SOR
3852:    Concepts: matrices^Gauss-Seidel

3854: @*/
3855: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3856: {

3866:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3867:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3868:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3869:   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);
3870:   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);
3871:   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);
3872:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3873:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3874:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3876:   MatCheckPreallocated(mat,1);
3877:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3878:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3879:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3880:   PetscObjectStateIncrease((PetscObject)x);
3881:   return(0);
3882: }

3884: /*
3885:       Default matrix copy routine.
3886: */
3887: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3888: {
3889:   PetscErrorCode    ierr;
3890:   PetscInt          i,rstart = 0,rend = 0,nz;
3891:   const PetscInt    *cwork;
3892:   const PetscScalar *vwork;

3895:   if (B->assembled) {
3896:     MatZeroEntries(B);
3897:   }
3898:   MatGetOwnershipRange(A,&rstart,&rend);
3899:   for (i=rstart; i<rend; i++) {
3900:     MatGetRow(A,i,&nz,&cwork,&vwork);
3901:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3902:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3903:   }
3904:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3905:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3906:   return(0);
3907: }

3909: /*@
3910:    MatCopy - Copys a matrix to another matrix.

3912:    Collective on Mat

3914:    Input Parameters:
3915: +  A - the matrix
3916: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3918:    Output Parameter:
3919: .  B - where the copy is put

3921:    Notes:
3922:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3923:    same nonzero pattern or the routine will crash.

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

3929:    Level: intermediate

3931:    Concepts: matrices^copying

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

3935: @*/
3936: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3937: {
3939:   PetscInt       i;

3947:   MatCheckPreallocated(B,2);
3948:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3949:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3950:   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);
3951:   MatCheckPreallocated(A,1);
3952:   if (A == B) return(0);

3954:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3955:   if (A->ops->copy) {
3956:     (*A->ops->copy)(A,B,str);
3957:   } else { /* generic conversion */
3958:     MatCopy_Basic(A,B,str);
3959:   }

3961:   B->stencil.dim = A->stencil.dim;
3962:   B->stencil.noc = A->stencil.noc;
3963:   for (i=0; i<=A->stencil.dim; i++) {
3964:     B->stencil.dims[i]   = A->stencil.dims[i];
3965:     B->stencil.starts[i] = A->stencil.starts[i];
3966:   }

3968:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3969:   PetscObjectStateIncrease((PetscObject)B);
3970:   return(0);
3971: }

3973: /*@C
3974:    MatConvert - Converts a matrix to another matrix, either of the same
3975:    or different type.

3977:    Collective on Mat

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

3987:    Output Parameter:
3988: .  M - pointer to place new matrix

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

3995:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3996:    the MPI communicator of the generated matrix is always the same as the communicator
3997:    of the input matrix.

3999:    Level: intermediate

4001:    Concepts: matrices^converting between storage formats

4003: .seealso: MatCopy(), MatDuplicate()
4004: @*/
4005: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4006: {
4008:   PetscBool      sametype,issame,flg;
4009:   char           convname[256],mtype[256];
4010:   Mat            B;

4016:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4017:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4018:   MatCheckPreallocated(mat,1);
4019:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

4021:   PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
4022:   if (flg) {
4023:     newtype = mtype;
4024:   }
4025:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
4026:   PetscStrcmp(newtype,"same",&issame);
4027:   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4028:   if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX");

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

4032:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4033:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
4034:   } else {
4035:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4036:     const char     *prefix[3] = {"seq","mpi",""};
4037:     PetscInt       i;
4038:     /*
4039:        Order of precedence:
4040:        1) See if a specialized converter is known to the current matrix.
4041:        2) See if a specialized converter is known to the desired matrix class.
4042:        3) See if a good general converter is registered for the desired class
4043:           (as of 6/27/03 only MATMPIADJ falls into this category).
4044:        4) See if a good general converter is known for the current matrix.
4045:        5) Use a really basic converter.
4046:     */

4048:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4049:     for (i=0; i<3; i++) {
4050:       PetscStrcpy(convname,"MatConvert_");
4051:       PetscStrcat(convname,((PetscObject)mat)->type_name);
4052:       PetscStrcat(convname,"_");
4053:       PetscStrcat(convname,prefix[i]);
4054:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
4055:       PetscStrcat(convname,"_C");
4056:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4057:       if (conv) goto foundconv;
4058:     }

4060:     /* 2)  See if a specialized converter is known to the desired matrix class. */
4061:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
4062:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
4063:     MatSetType(B,newtype);
4064:     for (i=0; i<3; i++) {
4065:       PetscStrcpy(convname,"MatConvert_");
4066:       PetscStrcat(convname,((PetscObject)mat)->type_name);
4067:       PetscStrcat(convname,"_");
4068:       PetscStrcat(convname,prefix[i]);
4069:       PetscStrcat(convname,newtype);
4070:       PetscStrcat(convname,"_C");
4071:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
4072:       if (conv) {
4073:         MatDestroy(&B);
4074:         goto foundconv;
4075:       }
4076:     }

4078:     /* 3) See if a good general converter is registered for the desired class */
4079:     conv = B->ops->convertfrom;
4080:     MatDestroy(&B);
4081:     if (conv) goto foundconv;

4083:     /* 4) See if a good general converter is known for the current matrix */
4084:     if (mat->ops->convert) {
4085:       conv = mat->ops->convert;
4086:     }
4087:     if (conv) goto foundconv;

4089:     /* 5) Use a really basic converter. */
4090:     conv = MatConvert_Basic;

4092: foundconv:
4093:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4094:     (*conv)(mat,newtype,reuse,M);
4095:     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4096:       /* the block sizes must be same if the mappings are copied over */
4097:       (*M)->rmap->bs = mat->rmap->bs;
4098:       (*M)->cmap->bs = mat->cmap->bs;
4099:       PetscObjectReference((PetscObject)mat->rmap->mapping);
4100:       PetscObjectReference((PetscObject)mat->cmap->mapping);
4101:       (*M)->rmap->mapping = mat->rmap->mapping;
4102:       (*M)->cmap->mapping = mat->cmap->mapping;
4103:     }
4104:     (*M)->stencil.dim = mat->stencil.dim;
4105:     (*M)->stencil.noc = mat->stencil.noc;
4106:     for (i=0; i<=mat->stencil.dim; i++) {
4107:       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4108:       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4109:     }
4110:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4111:   }
4112:   PetscObjectStateIncrease((PetscObject)*M);

4114:   /* Copy Mat options */
4115:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
4116:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
4117:   return(0);
4118: }

4120: /*@C
4121:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

4123:    Not Collective

4125:    Input Parameter:
4126: .  mat - the matrix, must be a factored matrix

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

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

4135:    Level: intermediate

4137: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4138: @*/
4139: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4140: {
4141:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

4146:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4147:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
4148:   if (!conv) {
4149:     *type = MATSOLVERPETSC;
4150:   } else {
4151:     (*conv)(mat,type);
4152:   }
4153:   return(0);
4154: }

4156: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4157: struct _MatSolverPackageForSpecifcType {
4158:   MatType                        mtype;
4159:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4160:   MatSolverPackageForSpecifcType next;
4161: };

4163: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4164: struct _MatSolverPackageHolder {
4165:   char                           *name;
4166:   MatSolverPackageForSpecifcType handlers;
4167:   MatSolverPackageHolder         next;
4168: };

4170: static MatSolverPackageHolder MatSolverPackageHolders = NULL;

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

4175:    Input Parameters:
4176: +    package - name of the package, for example petsc or superlu
4177: .    mtype - the matrix type that works with this package
4178: .    ftype - the type of factorization supported by the package
4179: -    getfactor - routine that will create the factored matrix ready to be used

4181:     Level: intermediate

4183: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4184: @*/
4185: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4186: {
4187:   PetscErrorCode                 ierr;
4188:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4189:   PetscBool                      flg;
4190:   MatSolverPackageForSpecifcType inext,iprev = NULL;

4193:   if (!next) {
4194:     PetscNew(&MatSolverPackageHolders);
4195:     PetscStrallocpy(package,&MatSolverPackageHolders->name);
4196:     PetscNew(&MatSolverPackageHolders->handlers);
4197:     PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4198:     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4199:     return(0);
4200:   }
4201:   while (next) {
4202:     PetscStrcasecmp(package,next->name,&flg);
4203:     if (flg) {
4204:       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverPackageHolder is missing handlers");
4205:       inext = next->handlers;
4206:       while (inext) {
4207:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4208:         if (flg) {
4209:           inext->getfactor[(int)ftype-1] = getfactor;
4210:           return(0);
4211:         }
4212:         iprev = inext;
4213:         inext = inext->next;
4214:       }
4215:       PetscNew(&iprev->next);
4216:       PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4217:       iprev->next->getfactor[(int)ftype-1] = getfactor;
4218:       return(0);
4219:     }
4220:     prev = next;
4221:     next = next->next;
4222:   }
4223:   PetscNew(&prev->next);
4224:   PetscStrallocpy(package,&prev->next->name);
4225:   PetscNew(&prev->next->handlers);
4226:   PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4227:   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4228:   return(0);
4229: }

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

4234:    Input Parameters:
4235: +    package - name of the package, for example petsc or superlu
4236: .    ftype - the type of factorization supported by the package
4237: -    mtype - the matrix type that works with this package

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

4244:     Level: intermediate

4246: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4247: @*/
4248: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4249: {
4250:   PetscErrorCode                 ierr;
4251:   MatSolverPackageHolder         next = MatSolverPackageHolders;
4252:   PetscBool                      flg;
4253:   MatSolverPackageForSpecifcType inext;

4256:   if (foundpackage) *foundpackage = PETSC_FALSE;
4257:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4258:   if (getfactor)    *getfactor    = NULL;

4260:   if (package) {
4261:     while (next) {
4262:       PetscStrcasecmp(package,next->name,&flg);
4263:       if (flg) {
4264:         if (foundpackage) *foundpackage = PETSC_TRUE;
4265:         inext = next->handlers;
4266:         while (inext) {
4267:           PetscStrbeginswith(mtype,inext->mtype,&flg);
4268:           if (flg) {
4269:             if (foundmtype) *foundmtype = PETSC_TRUE;
4270:             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4271:             return(0);
4272:           }
4273:           inext = inext->next;
4274:         }
4275:       }
4276:       next = next->next;
4277:     }
4278:   } else {
4279:     while (next) {
4280:       inext = next->handlers;
4281:       while (inext) {
4282:         PetscStrbeginswith(mtype,inext->mtype,&flg);
4283:         if (flg && inext->getfactor[(int)ftype-1]) {
4284:           if (foundpackage) *foundpackage = PETSC_TRUE;
4285:           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4286:           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4287:           return(0);
4288:         }
4289:         inext = inext->next;
4290:       }
4291:       next = next->next;
4292:     }
4293:   }
4294:   return(0);
4295: }

4297: PetscErrorCode MatSolverPackageDestroy(void)
4298: {
4299:   PetscErrorCode                 ierr;
4300:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4301:   MatSolverPackageForSpecifcType inext,iprev;

4304:   while (next) {
4305:     PetscFree(next->name);
4306:     inext = next->handlers;
4307:     while (inext) {
4308:       PetscFree(inext->mtype);
4309:       iprev = inext;
4310:       inext = inext->next;
4311:       PetscFree(iprev);
4312:     }
4313:     prev = next;
4314:     next = next->next;
4315:     PetscFree(prev);
4316:   }
4317:   MatSolverPackageHolders = NULL;
4318:   return(0);
4319: }

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

4324:    Collective on Mat

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

4331:    Output Parameters:
4332: .  f - the factor matrix used with MatXXFactorSymbolic() calls

4334:    Notes:
4335:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4336:      such as pastix, superlu, mumps etc.

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

4340:    Level: intermediate

4342: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4343: @*/
4344: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4345: {
4346:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4347:   PetscBool      foundpackage,foundmtype;


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

4356:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4357:   if (!foundpackage) {
4358:     if (type) {
4359:       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4360:     } else {
4361:       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4362:     }
4363:   }

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

4368: #if defined(PETSC_USE_COMPLEX)
4369:   if (mat->hermitian && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported");
4370: #endif

4372:   (*conv)(mat,ftype,f);
4373:   return(0);
4374: }

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

4379:    Not Collective

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

4386:    Output Parameter:
4387: .    flg - PETSC_TRUE if the factorization is available

4389:    Notes:
4390:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4391:      such as pastix, superlu, mumps etc.

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

4395:    Level: intermediate

4397: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4398: @*/
4399: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4400: {
4401:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);


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

4410:   *flg = PETSC_FALSE;
4411:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4412:   if (gconv) {
4413:     *flg = PETSC_TRUE;
4414:   }
4415:   return(0);
4416: }

4418:  #include <petscdmtypes.h>

4420: /*@
4421:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4423:    Collective on Mat

4425:    Input Parameters:
4426: +  mat - the matrix
4427: -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4428:         See the manual page for MatDuplicateOption for an explanation of these options.

4430:    Output Parameter:
4431: .  M - pointer to place new matrix

4433:    Level: intermediate

4435:    Concepts: matrices^duplicating

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

4439: .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4440: @*/
4441: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4442: {
4444:   Mat            B;
4445:   PetscInt       i;
4446:   DM             dm;

4452:   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4453:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4454:   MatCheckPreallocated(mat,1);

4456:   *M = 0;
4457:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4458:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4459:   (*mat->ops->duplicate)(mat,op,M);
4460:   B    = *M;

4462:   B->stencil.dim = mat->stencil.dim;
4463:   B->stencil.noc = mat->stencil.noc;
4464:   for (i=0; i<=mat->stencil.dim; i++) {
4465:     B->stencil.dims[i]   = mat->stencil.dims[i];
4466:     B->stencil.starts[i] = mat->stencil.starts[i];
4467:   }

4469:   B->nooffproczerorows = mat->nooffproczerorows;
4470:   B->nooffprocentries  = mat->nooffprocentries;

4472:   PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4473:   if (dm) {
4474:     PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4475:   }
4476:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4477:   PetscObjectStateIncrease((PetscObject)B);
4478:   return(0);
4479: }

4481: /*@
4482:    MatGetDiagonal - Gets the diagonal of a matrix.

4484:    Logically Collective on Mat and Vec

4486:    Input Parameters:
4487: +  mat - the matrix
4488: -  v - the vector for storing the diagonal

4490:    Output Parameter:
4491: .  v - the diagonal of the matrix

4493:    Level: intermediate

4495:    Note:
4496:    Currently only correct in parallel for square matrices.

4498:    Concepts: matrices^accessing diagonals

4500: .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4501: @*/
4502: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4503: {

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

4514:   (*mat->ops->getdiagonal)(mat,v);
4515:   PetscObjectStateIncrease((PetscObject)v);
4516:   return(0);
4517: }

4519: /*@C
4520:    MatGetRowMin - Gets the minimum value (of the real part) of each
4521:         row of the matrix

4523:    Logically Collective on Mat and Vec

4525:    Input Parameters:
4526: .  mat - the matrix

4528:    Output Parameter:
4529: +  v - the vector for storing the maximums
4530: -  idx - the indices of the column found for each row (optional)

4532:    Level: intermediate

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

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

4539:    Concepts: matrices^getting row maximums

4541: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4542:           MatGetRowMax()
4543: @*/
4544: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4545: {

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

4556:   (*mat->ops->getrowmin)(mat,v,idx);
4557:   PetscObjectStateIncrease((PetscObject)v);
4558:   return(0);
4559: }

4561: /*@C
4562:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4563:         row of the matrix

4565:    Logically Collective on Mat and Vec

4567:    Input Parameters:
4568: .  mat - the matrix

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

4574:    Level: intermediate

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

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

4581:    Concepts: matrices^getting row maximums

4583: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4584: @*/
4585: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4586: {

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

4598:   (*mat->ops->getrowminabs)(mat,v,idx);
4599:   PetscObjectStateIncrease((PetscObject)v);
4600:   return(0);
4601: }

4603: /*@C
4604:    MatGetRowMax - Gets the maximum value (of the real part) of each
4605:         row of the matrix

4607:    Logically Collective on Mat and Vec

4609:    Input Parameters:
4610: .  mat - the matrix

4612:    Output Parameter:
4613: +  v - the vector for storing the maximums
4614: -  idx - the indices of the column found for each row (optional)

4616:    Level: intermediate

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

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

4623:    Concepts: matrices^getting row maximums

4625: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4626: @*/
4627: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4628: {

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

4639:   (*mat->ops->getrowmax)(mat,v,idx);
4640:   PetscObjectStateIncrease((PetscObject)v);
4641:   return(0);
4642: }

4644: /*@C
4645:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4646:         row of the matrix

4648:    Logically Collective on Mat and Vec

4650:    Input Parameters:
4651: .  mat - the matrix

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

4657:    Level: intermediate

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

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

4664:    Concepts: matrices^getting row maximums

4666: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4667: @*/
4668: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4669: {

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

4681:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4682:   PetscObjectStateIncrease((PetscObject)v);
4683:   return(0);
4684: }

4686: /*@
4687:    MatGetRowSum - Gets the sum of each row of the matrix

4689:    Logically or Neighborhood Collective on Mat and Vec

4691:    Input Parameters:
4692: .  mat - the matrix

4694:    Output Parameter:
4695: .  v - the vector for storing the sum of rows

4697:    Level: intermediate

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

4701:    Concepts: matrices^getting row sums

4703: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4704: @*/
4705: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4706: {
4707:   Vec            ones;

4714:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4715:   MatCheckPreallocated(mat,1);
4716:   MatCreateVecs(mat,&ones,NULL);
4717:   VecSet(ones,1.);
4718:   MatMult(mat,ones,v);
4719:   VecDestroy(&ones);
4720:   return(0);
4721: }

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

4726:    Collective on Mat

4728:    Input Parameter:
4729: +  mat - the matrix to transpose
4730: -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX

4732:    Output Parameters:
4733: .  B - the transpose

4735:    Notes:
4736:      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B

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

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

4742:    Level: intermediate

4744:    Concepts: matrices^transposing

4746: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4747: @*/
4748: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4749: {

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

4762:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4763:   (*mat->ops->transpose)(mat,reuse,B);
4764:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4765:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4766:   return(0);
4767: }

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

4773:    Collective on Mat

4775:    Input Parameter:
4776: +  A - the matrix to test
4777: -  B - the matrix to test against, this can equal the first parameter

4779:    Output Parameters:
4780: .  flg - the result

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

4787:    Level: intermediate

4789:    Concepts: matrices^transposing, matrix^symmetry

4791: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4792: @*/
4793: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4794: {
4795:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4801:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4802:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4803:   *flg = PETSC_FALSE;
4804:   if (f && g) {
4805:     if (f == g) {
4806:       (*f)(A,B,tol,flg);
4807:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4808:   } else {
4809:     MatType mattype;
4810:     if (!f) {
4811:       MatGetType(A,&mattype);
4812:     } else {
4813:       MatGetType(B,&mattype);
4814:     }
4815:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4816:   }
4817:   return(0);
4818: }

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

4823:    Collective on Mat

4825:    Input Parameter:
4826: +  mat - the matrix to transpose and complex conjugate
4827: -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose

4829:    Output Parameters:
4830: .  B - the Hermitian

4832:    Level: intermediate

4834:    Concepts: matrices^transposing, complex conjugatex

4836: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4837: @*/
4838: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4839: {

4843:   MatTranspose(mat,reuse,B);
4844: #if defined(PETSC_USE_COMPLEX)
4845:   MatConjugate(*B);
4846: #endif
4847:   return(0);
4848: }

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

4853:    Collective on Mat

4855:    Input Parameter:
4856: +  A - the matrix to test
4857: -  B - the matrix to test against, this can equal the first parameter

4859:    Output Parameters:
4860: .  flg - the result

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

4867:    Level: intermediate

4869:    Concepts: matrices^transposing, matrix^symmetry

4871: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4872: @*/
4873: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4874: {
4875:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4881:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4882:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4883:   if (f && g) {
4884:     if (f==g) {
4885:       (*f)(A,B,tol,flg);
4886:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4887:   }
4888:   return(0);
4889: }

4891: /*@
4892:    MatPermute - Creates a new matrix with rows and columns permuted from the
4893:    original.

4895:    Collective on Mat

4897:    Input Parameters:
4898: +  mat - the matrix to permute
4899: .  row - row permutation, each processor supplies only the permutation for its rows
4900: -  col - column permutation, each processor supplies only the permutation for its columns

4902:    Output Parameters:
4903: .  B - the permuted matrix

4905:    Level: advanced

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

4911:    Concepts: matrices^permuting

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

4915: @*/
4916: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4917: {

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

4931:   (*mat->ops->permute)(mat,row,col,B);
4932:   PetscObjectStateIncrease((PetscObject)*B);
4933:   return(0);
4934: }

4936: /*@
4937:    MatEqual - Compares two matrices.

4939:    Collective on Mat

4941:    Input Parameters:
4942: +  A - the first matrix
4943: -  B - the second matrix

4945:    Output Parameter:
4946: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4948:    Level: intermediate

4950:    Concepts: matrices^equality between
4951: @*/
4952: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4953: {

4963:   MatCheckPreallocated(B,2);
4964:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4965:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4966:   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);
4967:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4968:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4969:   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);
4970:   MatCheckPreallocated(A,1);

4972:   (*A->ops->equal)(A,B,flg);
4973:   return(0);
4974: }

4976: /*@C
4977:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4978:    matrices that are stored as vectors.  Either of the two scaling
4979:    matrices can be NULL.

4981:    Collective on Mat

4983:    Input Parameters:
4984: +  mat - the matrix to be scaled
4985: .  l - the left scaling vector (or NULL)
4986: -  r - the right scaling vector (or NULL)

4988:    Notes:
4989:    MatDiagonalScale() computes A = LAR, where
4990:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4991:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4993:    Level: intermediate

4995:    Concepts: matrices^diagonal scaling
4996:    Concepts: diagonal scaling of matrices

4998: .seealso: MatScale()
4999: @*/
5000: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5001: {

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

5014:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5015:   (*mat->ops->diagonalscale)(mat,l,r);
5016:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5017:   PetscObjectStateIncrease((PetscObject)mat);
5018: #if defined(PETSC_HAVE_CUSP)
5019:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5020:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5021:   }
5022: #elif defined(PETSC_HAVE_VIENNACL)
5023:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5024:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5025:   }
5026: #elif defined(PETSC_HAVE_VECCUDA)
5027:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5028:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5029:   }
5030: #endif
5031:   return(0);
5032: }

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

5037:     Logically Collective on Mat

5039:     Input Parameters:
5040: +   mat - the matrix to be scaled
5041: -   a  - the scaling value

5043:     Output Parameter:
5044: .   mat - the scaled matrix

5046:     Level: intermediate

5048:     Concepts: matrices^scaling all entries

5050: .seealso: MatDiagonalScale()
5051: @*/
5052: PetscErrorCode MatScale(Mat mat,PetscScalar a)
5053: {

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

5065:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5066:   if (a != (PetscScalar)1.0) {
5067:     (*mat->ops->scale)(mat,a);
5068:     PetscObjectStateIncrease((PetscObject)mat);
5069: #if defined(PETSC_HAVE_CUSP)
5070:     if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5071:       mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5072:     }
5073: #elif defined(PETSC_HAVE_VIENNACL)
5074:     if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5075:       mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5076:     }
5077: #elif defined(PETSC_HAVE_VECCUDA)
5078:     if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5079:       mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5080:     }
5081: #endif
5082:   }
5083:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5084:   return(0);
5085: }

5087: /*@
5088:    MatNorm - Calculates various norms of a matrix.

5090:    Collective on Mat

5092:    Input Parameters:
5093: +  mat - the matrix
5094: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

5096:    Output Parameters:
5097: .  nrm - the resulting norm

5099:    Level: intermediate

5101:    Concepts: matrices^norm
5102:    Concepts: norm^of matrix
5103: @*/
5104: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5105: {


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

5118:   (*mat->ops->norm)(mat,type,nrm);
5119:   return(0);
5120: }

5122: /*
5123:      This variable is used to prevent counting of MatAssemblyBegin() that
5124:    are called from within a MatAssemblyEnd().
5125: */
5126: static PetscInt MatAssemblyEnd_InUse = 0;
5127: /*@
5128:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5129:    be called after completing all calls to MatSetValues().

5131:    Collective on Mat

5133:    Input Parameters:
5134: +  mat - the matrix
5135: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5137:    Notes:
5138:    MatSetValues() generally caches the values.  The matrix is ready to
5139:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5140:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5141:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5142:    using the matrix.

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

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

5152:    Level: beginner

5154:    Concepts: matrices^assembling

5156: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5157: @*/
5158: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5159: {

5165:   MatCheckPreallocated(mat,1);
5166:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5167:   if (mat->assembled) {
5168:     mat->was_assembled = PETSC_TRUE;
5169:     mat->assembled     = PETSC_FALSE;
5170:   }
5171:   if (!MatAssemblyEnd_InUse) {
5172:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5173:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5174:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5175:   } else if (mat->ops->assemblybegin) {
5176:     (*mat->ops->assemblybegin)(mat,type);
5177:   }
5178:   return(0);
5179: }

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

5185:    Not Collective

5187:    Input Parameter:
5188: .  mat - the matrix

5190:    Output Parameter:
5191: .  assembled - PETSC_TRUE or PETSC_FALSE

5193:    Level: advanced

5195:    Concepts: matrices^assembled?

5197: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5198: @*/
5199: PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5200: {
5205:   *assembled = mat->assembled;
5206:   return(0);
5207: }

5209: /*@
5210:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5211:    be called after MatAssemblyBegin().

5213:    Collective on Mat

5215:    Input Parameters:
5216: +  mat - the matrix
5217: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5219:    Options Database Keys:
5220: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5221: .  -mat_view ::ascii_info_detail - Prints more detailed info
5222: .  -mat_view - Prints matrix in ASCII format
5223: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5224: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5225: .  -display <name> - Sets display name (default is host)
5226: .  -draw_pause <sec> - Sets number of seconds to pause after display
5227: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 12 Using MATLAB with PETSc )
5228: .  -viewer_socket_machine <machine> - Machine to use for socket
5229: .  -viewer_socket_port <port> - Port number to use for socket
5230: -  -mat_view binary:filename[:append] - Save matrix to file in binary format

5232:    Notes:
5233:    MatSetValues() generally caches the values.  The matrix is ready to
5234:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5235:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5236:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5237:    using the matrix.

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

5243:    Level: beginner

5245: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5246: @*/
5247: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5248: {
5249:   PetscErrorCode  ierr;
5250:   static PetscInt inassm = 0;
5251:   PetscBool       flg    = PETSC_FALSE;


5257:   inassm++;
5258:   MatAssemblyEnd_InUse++;
5259:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5260:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5261:     if (mat->ops->assemblyend) {
5262:       (*mat->ops->assemblyend)(mat,type);
5263:     }
5264:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5265:   } else if (mat->ops->assemblyend) {
5266:     (*mat->ops->assemblyend)(mat,type);
5267:   }

5269:   /* Flush assembly is not a true assembly */
5270:   if (type != MAT_FLUSH_ASSEMBLY) {
5271:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5272:   }
5273:   mat->insertmode = NOT_SET_VALUES;
5274:   MatAssemblyEnd_InUse--;
5275:   PetscObjectStateIncrease((PetscObject)mat);
5276:   if (!mat->symmetric_eternal) {
5277:     mat->symmetric_set              = PETSC_FALSE;
5278:     mat->hermitian_set              = PETSC_FALSE;
5279:     mat->structurally_symmetric_set = PETSC_FALSE;
5280:   }
5281: #if defined(PETSC_HAVE_CUSP)
5282:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5283:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5284:   }
5285: #elif defined(PETSC_HAVE_VIENNACL)
5286:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5287:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5288:   }
5289: #elif defined(PETSC_HAVE_VECCUDA)
5290:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5291:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5292:   }
5293: #endif
5294:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5295:     MatViewFromOptions(mat,NULL,"-mat_view");

5297:     if (mat->checksymmetryonassembly) {
5298:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5299:       if (flg) {
5300:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5301:       } else {
5302:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5303:       }
5304:     }
5305:     if (mat->nullsp && mat->checknullspaceonassembly) {
5306:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5307:     }
5308:   }
5309:   inassm--;
5310:   return(0);
5311: }

5313: /*@
5314:    MatSetOption - Sets a parameter option for a matrix. Some options
5315:    may be specific to certain storage formats.  Some options
5316:    determine how values will be inserted (or added). Sorted,
5317:    row-oriented input will generally assemble the fastest. The default
5318:    is row-oriented.

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

5322:    Input Parameters:
5323: +  mat - the matrix
5324: .  option - the option, one of those listed below (and possibly others),
5325: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5327:   Options Describing Matrix Structure:
5328: +    MAT_SPD - symmetric positive definite
5329: .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5330: .    MAT_HERMITIAN - transpose is the complex conjugation
5331: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5332: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5333:                             you set to be kept with all future use of the matrix
5334:                             including after MatAssemblyBegin/End() which could
5335:                             potentially change the symmetry structure, i.e. you
5336:                             KNOW the matrix will ALWAYS have the property you set.


5339:    Options For Use with MatSetValues():
5340:    Insert a logically dense subblock, which can be
5341: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

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

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

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

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

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

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

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

5395:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5396:    searches during matrix assembly. When this flag is set, the hash table
5397:    is created during the first Matrix Assembly. This hash table is
5398:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5399:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5400:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5401:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5419:    Level: intermediate

5421:    Concepts: matrices^setting options

5423: .seealso:  MatOption, Mat

5425: @*/
5426: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5427: {

5433:   if (op > 0) {
5436:   }

5438:   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);
5439:   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()");

5441:   switch (op) {
5442:   case MAT_NO_OFF_PROC_ENTRIES:
5443:     mat->nooffprocentries = flg;
5444:     return(0);
5445:     break;
5446:   case MAT_SUBSET_OFF_PROC_ENTRIES:
5447:     mat->subsetoffprocentries = flg;
5448:     return(0);
5449:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5450:     mat->nooffproczerorows = flg;
5451:     return(0);
5452:     break;
5453:   case MAT_SPD:
5454:     mat->spd_set = PETSC_TRUE;
5455:     mat->spd     = flg;
5456:     if (flg) {
5457:       mat->symmetric                  = PETSC_TRUE;
5458:       mat->structurally_symmetric     = PETSC_TRUE;
5459:       mat->symmetric_set              = PETSC_TRUE;
5460:       mat->structurally_symmetric_set = PETSC_TRUE;
5461:     }
5462:     break;
5463:   case MAT_SYMMETRIC:
5464:     mat->symmetric = flg;
5465:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5466:     mat->symmetric_set              = PETSC_TRUE;
5467:     mat->structurally_symmetric_set = flg;
5468: #if !defined(PETSC_USE_COMPLEX)
5469:     mat->hermitian     = flg;
5470:     mat->hermitian_set = PETSC_TRUE;
5471: #endif
5472:     break;
5473:   case MAT_HERMITIAN:
5474:     mat->hermitian = flg;
5475:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5476:     mat->hermitian_set              = PETSC_TRUE;
5477:     mat->structurally_symmetric_set = flg;
5478: #if !defined(PETSC_USE_COMPLEX)
5479:     mat->symmetric     = flg;
5480:     mat->symmetric_set = PETSC_TRUE;
5481: #endif
5482:     break;
5483:   case MAT_STRUCTURALLY_SYMMETRIC:
5484:     mat->structurally_symmetric     = flg;
5485:     mat->structurally_symmetric_set = PETSC_TRUE;
5486:     break;
5487:   case MAT_SYMMETRY_ETERNAL:
5488:     mat->symmetric_eternal = flg;
5489:     break;
5490:   case MAT_STRUCTURE_ONLY:
5491:     mat->structure_only = flg;
5492:     break;
5493:   default:
5494:     break;
5495:   }
5496:   if (mat->ops->setoption) {
5497:     (*mat->ops->setoption)(mat,op,flg);
5498:   }
5499:   return(0);
5500: }

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

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

5507:    Input Parameters:
5508: +  mat - the matrix
5509: -  option - the option, this only responds to certain options, check the code for which ones

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

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

5516:    Level: intermediate

5518:    Concepts: matrices^setting options

5520: .seealso:  MatOption, MatSetOption()

5522: @*/
5523: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5524: {

5529:   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);
5530:   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()");

5532:   switch (op) {
5533:   case MAT_NO_OFF_PROC_ENTRIES:
5534:     *flg = mat->nooffprocentries;
5535:     break;
5536:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5537:     *flg = mat->nooffproczerorows;
5538:     break;
5539:   case MAT_SYMMETRIC:
5540:     *flg = mat->symmetric;
5541:     break;
5542:   case MAT_HERMITIAN:
5543:     *flg = mat->hermitian;
5544:     break;
5545:   case MAT_STRUCTURALLY_SYMMETRIC:
5546:     *flg = mat->structurally_symmetric;
5547:     break;
5548:   case MAT_SYMMETRY_ETERNAL:
5549:     *flg = mat->symmetric_eternal;
5550:     break;
5551:   case MAT_SPD:
5552:     *flg = mat->spd;
5553:     break;
5554:   default:
5555:     break;
5556:   }
5557:   return(0);
5558: }

5560: /*@
5561:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5562:    this routine retains the old nonzero structure.

5564:    Logically Collective on Mat

5566:    Input Parameters:
5567: .  mat - the matrix

5569:    Level: intermediate

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

5574:    Concepts: matrices^zeroing

5576: .seealso: MatZeroRows()
5577: @*/
5578: PetscErrorCode MatZeroEntries(Mat mat)
5579: {

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

5590:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5591:   (*mat->ops->zeroentries)(mat);
5592:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5593:   PetscObjectStateIncrease((PetscObject)mat);
5594: #if defined(PETSC_HAVE_CUSP)
5595:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5596:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5597:   }
5598: #elif defined(PETSC_HAVE_VIENNACL)
5599:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5600:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5601:   }
5602: #elif defined(PETSC_HAVE_VECCUDA)
5603:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5604:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5605:   }
5606: #endif
5607:   return(0);
5608: }

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

5614:    Collective on Mat

5616:    Input Parameters:
5617: +  mat - the matrix
5618: .  numRows - the number of rows to remove
5619: .  rows - the global row indices
5620: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5621: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5622: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5641:    Level: intermediate

5643:    Concepts: matrices^zeroing rows

5645: .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5646:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5647: @*/
5648: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5649: {

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

5661:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5662:   MatViewFromOptions(mat,NULL,"-mat_view");
5663:   PetscObjectStateIncrease((PetscObject)mat);
5664: #if defined(PETSC_HAVE_CUSP)
5665:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5666:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5667:   }
5668: #elif defined(PETSC_HAVE_VIENNACL)
5669:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5670:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5671:   }
5672: #elif defined(PETSC_HAVE_VECCUDA)
5673:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5674:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5675:   }
5676: #endif
5677:   return(0);
5678: }

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

5684:    Collective on Mat

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

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

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

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

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

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

5710:    Level: intermediate

5712:    Concepts: matrices^zeroing rows

5714: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5715:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5716: @*/
5717: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5718: {
5720:   PetscInt       numRows;
5721:   const PetscInt *rows;

5728:   ISGetLocalSize(is,&numRows);
5729:   ISGetIndices(is,&rows);
5730:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5731:   ISRestoreIndices(is,&rows);
5732:   return(0);
5733: }

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

5739:    Collective on Mat

5741:    Input Parameters:
5742: +  mat - the matrix
5743: .  numRows - the number of rows to remove
5744: .  rows - the global row indices
5745: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5746: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5747: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

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

5773:    Level: intermediate

5775:    Concepts: matrices^zeroing rows

5777: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5778:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5779: @*/
5780: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5781: {

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

5793:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5794:   MatViewFromOptions(mat,NULL,"-mat_view");
5795:   PetscObjectStateIncrease((PetscObject)mat);
5796: #if defined(PETSC_HAVE_CUSP)
5797:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5798:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5799:   }
5800: #elif defined(PETSC_HAVE_VIENNACL)
5801:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5802:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5803:   }
5804: #elif defined(PETSC_HAVE_VECCUDA)
5805:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5806:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5807:   }
5808: #endif
5809:   return(0);
5810: }

5812: /*@C
5813:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5814:    of a set of rows of a matrix.

5816:    Collective on Mat

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

5825:    Notes:
5826:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5827:    but does not release memory.  For the dense and block diagonal
5828:    formats this does not alter the nonzero structure.

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

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

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

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

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

5849:    Level: intermediate

5851:    Concepts: matrices^zeroing rows

5853: .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5854:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5855: @*/
5856: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5857: {
5858:   PetscInt       numRows;
5859:   const PetscInt *rows;

5866:   ISGetLocalSize(is,&numRows);
5867:   ISGetIndices(is,&rows);
5868:   MatZeroRows(mat,numRows,rows,diag,x,b);
5869:   ISRestoreIndices(is,&rows);
5870:   return(0);
5871: }

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

5877:    Collective on Mat

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

5887:    Notes:
5888:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5889:    but does not release memory.  For the dense and block diagonal
5890:    formats this does not alter the nonzero structure.

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

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

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

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

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

5910:    In Fortran idxm and idxn should be declared as
5911: $     MatStencil idxm(4,m)
5912:    and the values inserted using
5913: $    idxm(MatStencil_i,1) = i
5914: $    idxm(MatStencil_j,1) = j
5915: $    idxm(MatStencil_k,1) = k
5916: $    idxm(MatStencil_c,1) = c
5917:    etc

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

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

5927:    Level: intermediate

5929:    Concepts: matrices^zeroing rows

5931: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5932:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5933: @*/
5934: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5935: {
5936:   PetscInt       dim     = mat->stencil.dim;
5937:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5938:   PetscInt       *dims   = mat->stencil.dims+1;
5939:   PetscInt       *starts = mat->stencil.starts;
5940:   PetscInt       *dxm    = (PetscInt*) rows;
5941:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5949:   PetscMalloc1(numRows, &jdxm);
5950:   for (i = 0; i < numRows; ++i) {
5951:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5952:     for (j = 0; j < 3-sdim; ++j) dxm++;
5953:     /* Local index in X dir */
5954:     tmp = *dxm++ - starts[0];
5955:     /* Loop over remaining dimensions */
5956:     for (j = 0; j < dim-1; ++j) {
5957:       /* If nonlocal, set index to be negative */
5958:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5959:       /* Update local index */
5960:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5961:     }
5962:     /* Skip component slot if necessary */
5963:     if (mat->stencil.noc) dxm++;
5964:     /* Local row number */
5965:     if (tmp >= 0) {
5966:       jdxm[numNewRows++] = tmp;
5967:     }
5968:   }
5969:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5970:   PetscFree(jdxm);
5971:   return(0);
5972: }

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

5978:    Collective on Mat

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

5988:    Notes:
5989:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5990:    but does not release memory.  For the dense and block diagonal
5991:    formats this does not alter the nonzero structure.

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

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

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

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

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

6011:    In Fortran idxm and idxn should be declared as
6012: $     MatStencil idxm(4,m)
6013:    and the values inserted using
6014: $    idxm(MatStencil_i,1) = i
6015: $    idxm(MatStencil_j,1) = j
6016: $    idxm(MatStencil_k,1) = k
6017: $    idxm(MatStencil_c,1) = c
6018:    etc

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

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

6028:    Level: intermediate

6030:    Concepts: matrices^zeroing rows

6032: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6033:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6034: @*/
6035: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6036: {
6037:   PetscInt       dim     = mat->stencil.dim;
6038:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6039:   PetscInt       *dims   = mat->stencil.dims+1;
6040:   PetscInt       *starts = mat->stencil.starts;
6041:   PetscInt       *dxm    = (PetscInt*) rows;
6042:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


6050:   PetscMalloc1(numRows, &jdxm);
6051:   for (i = 0; i < numRows; ++i) {
6052:     /* Skip unused dimensions (they are ordered k, j, i, c) */
6053:     for (j = 0; j < 3-sdim; ++j) dxm++;
6054:     /* Local index in X dir */
6055:     tmp = *dxm++ - starts[0];
6056:     /* Loop over remaining dimensions */
6057:     for (j = 0; j < dim-1; ++j) {
6058:       /* If nonlocal, set index to be negative */
6059:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6060:       /* Update local index */
6061:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6062:     }
6063:     /* Skip component slot if necessary */
6064:     if (mat->stencil.noc) dxm++;
6065:     /* Local row number */
6066:     if (tmp >= 0) {
6067:       jdxm[numNewRows++] = tmp;
6068:     }
6069:   }
6070:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
6071:   PetscFree(jdxm);
6072:   return(0);
6073: }

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

6079:    Collective on Mat

6081:    Input Parameters:
6082: +  mat - the matrix
6083: .  numRows - the number of rows to remove
6084: .  rows - the global row indices
6085: .  diag - value put in all diagonals of eliminated rows
6086: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6087: -  b - optional vector of right hand side, that will be adjusted by provided solution

6089:    Notes:
6090:    Before calling MatZeroRowsLocal(), the user must first set the
6091:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6093:    For the AIJ matrix formats this removes the old nonzero structure,
6094:    but does not release memory.  For the dense and block diagonal
6095:    formats this does not alter the nonzero structure.

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

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

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

6108:    Level: intermediate

6110:    Concepts: matrices^zeroing

6112: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6113:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6114: @*/
6115: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6116: {

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

6127:   if (mat->ops->zerorowslocal) {
6128:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6129:   } else {
6130:     IS             is, newis;
6131:     const PetscInt *newRows;

6133:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6134:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6135:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6136:     ISGetIndices(newis,&newRows);
6137:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6138:     ISRestoreIndices(newis,&newRows);
6139:     ISDestroy(&newis);
6140:     ISDestroy(&is);
6141:   }
6142:   PetscObjectStateIncrease((PetscObject)mat);
6143: #if defined(PETSC_HAVE_CUSP)
6144:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6145:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6146:   }
6147: #elif defined(PETSC_HAVE_VIENNACL)
6148:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6149:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6150:   }
6151: #elif defined(PETSC_HAVE_VECCUDA)
6152:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6153:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6154:   }
6155: #endif
6156:   return(0);
6157: }

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

6163:    Collective on Mat

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

6172:    Notes:
6173:    Before calling MatZeroRowsLocalIS(), the user must first set the
6174:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6176:    For the AIJ matrix formats this removes the old nonzero structure,
6177:    but does not release memory.  For the dense and block diagonal
6178:    formats this does not alter the nonzero structure.

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

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

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

6191:    Level: intermediate

6193:    Concepts: matrices^zeroing

6195: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6196:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6197: @*/
6198: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6199: {
6201:   PetscInt       numRows;
6202:   const PetscInt *rows;

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

6212:   ISGetLocalSize(is,&numRows);
6213:   ISGetIndices(is,&rows);
6214:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6215:   ISRestoreIndices(is,&rows);
6216:   return(0);
6217: }

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

6223:    Collective on Mat

6225:    Input Parameters:
6226: +  mat - the matrix
6227: .  numRows - the number of rows to remove
6228: .  rows - the global row indices
6229: .  diag - value put in all diagonals of eliminated rows
6230: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6231: -  b - optional vector of right hand side, that will be adjusted by provided solution

6233:    Notes:
6234:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6235:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6241:    Level: intermediate

6243:    Concepts: matrices^zeroing

6245: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6246:           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6247: @*/
6248: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6249: {
6251:   IS             is, newis;
6252:   const PetscInt *newRows;

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

6262:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6263:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6264:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6265:   ISGetIndices(newis,&newRows);
6266:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6267:   ISRestoreIndices(newis,&newRows);
6268:   ISDestroy(&newis);
6269:   ISDestroy(&is);
6270:   PetscObjectStateIncrease((PetscObject)mat);
6271: #if defined(PETSC_HAVE_CUSP)
6272:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6273:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6274:   }
6275: #elif defined(PETSC_HAVE_VIENNACL)
6276:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6277:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6278:   }
6279: #elif defined(PETSC_HAVE_VECCUDA)
6280:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6281:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6282:   }
6283: #endif
6284:   return(0);
6285: }

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

6291:    Collective on Mat

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

6300:    Notes:
6301:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6302:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6308:    Level: intermediate

6310:    Concepts: matrices^zeroing

6312: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6313:           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6314: @*/
6315: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6316: {
6318:   PetscInt       numRows;
6319:   const PetscInt *rows;

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

6329:   ISGetLocalSize(is,&numRows);
6330:   ISGetIndices(is,&rows);
6331:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6332:   ISRestoreIndices(is,&rows);
6333:   return(0);
6334: }

6336: /*@C
6337:    MatGetSize - Returns the numbers of rows and columns in a matrix.

6339:    Not Collective

6341:    Input Parameter:
6342: .  mat - the matrix

6344:    Output Parameters:
6345: +  m - the number of global rows
6346: -  n - the number of global columns

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

6350:    Level: beginner

6352:    Concepts: matrices^size

6354: .seealso: MatGetLocalSize()
6355: @*/
6356: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6357: {
6360:   if (m) *m = mat->rmap->N;
6361:   if (n) *n = mat->cmap->N;
6362:   return(0);
6363: }

6365: /*@C
6366:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6367:    stored locally.  This information may be implementation dependent, so
6368:    use with care.

6370:    Not Collective

6372:    Input Parameters:
6373: .  mat - the matrix

6375:    Output Parameters:
6376: +  m - the number of local rows
6377: -  n - the number of local columns

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

6381:    Level: beginner

6383:    Concepts: matrices^local size

6385: .seealso: MatGetSize()
6386: @*/
6387: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6388: {
6393:   if (m) *m = mat->rmap->n;
6394:   if (n) *n = mat->cmap->n;
6395:   return(0);
6396: }

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

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

6404:    Input Parameters:
6405: .  mat - the matrix

6407:    Output Parameters:
6408: +  m - the global index of the first local column
6409: -  n - one more than the global index of the last local column

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

6413:    Level: developer

6415:    Concepts: matrices^column ownership

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

6419: @*/
6420: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6421: {
6427:   MatCheckPreallocated(mat,1);
6428:   if (m) *m = mat->cmap->rstart;
6429:   if (n) *n = mat->cmap->rend;
6430:   return(0);
6431: }

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

6439:    Not Collective

6441:    Input Parameters:
6442: .  mat - the matrix

6444:    Output Parameters:
6445: +  m - the global index of the first local row
6446: -  n - one more than the global index of the last local row

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

6453:    Level: beginner

6455:    Concepts: matrices^row ownership

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

6459: @*/
6460: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6461: {
6467:   MatCheckPreallocated(mat,1);
6468:   if (m) *m = mat->rmap->rstart;
6469:   if (n) *n = mat->rmap->rend;
6470:   return(0);
6471: }

6473: /*@C
6474:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6475:    each process

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

6479:    Input Parameters:
6480: .  mat - the matrix

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

6485:    Level: beginner

6487:    Concepts: matrices^row ownership

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

6491: @*/
6492: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6493: {

6499:   MatCheckPreallocated(mat,1);
6500:   PetscLayoutGetRanges(mat->rmap,ranges);
6501:   return(0);
6502: }

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

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

6510:    Input Parameters:
6511: .  mat - the matrix

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

6516:    Level: beginner

6518:    Concepts: matrices^column ownership

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

6522: @*/
6523: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6524: {

6530:   MatCheckPreallocated(mat,1);
6531:   PetscLayoutGetRanges(mat->cmap,ranges);
6532:   return(0);
6533: }

6535: /*@C
6536:    MatGetOwnershipIS - Get row and column ownership as index sets

6538:    Not Collective

6540:    Input Arguments:
6541: .  A - matrix of type Elemental

6543:    Output Arguments:
6544: +  rows - rows in which this process owns elements
6545: .  cols - columns in which this process owns elements

6547:    Level: intermediate

6549: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6550: @*/
6551: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6552: {
6553:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6556:   MatCheckPreallocated(A,1);
6557:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6558:   if (f) {
6559:     (*f)(A,rows,cols);
6560:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6561:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6562:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6563:   }
6564:   return(0);
6565: }

6567: /*@C
6568:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6569:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6570:    to complete the factorization.

6572:    Collective on Mat

6574:    Input Parameters:
6575: +  mat - the matrix
6576: .  row - row permutation
6577: .  column - column permutation
6578: -  info - structure containing
6579: $      levels - number of levels of fill.
6580: $      expected fill - as ratio of original fill.
6581: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6582:                 missing diagonal entries)

6584:    Output Parameters:
6585: .  fact - new matrix that has been symbolically factored

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

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

6593:    Level: developer

6595:   Concepts: matrices^symbolic LU factorization
6596:   Concepts: matrices^factorization
6597:   Concepts: LU^symbolic factorization

6599: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6600:           MatGetOrdering(), MatFactorInfo

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

6605: @*/
6606: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6607: {

6617:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6618:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6619:   if (!(fact)->ops->ilufactorsymbolic) {
6620:     const MatSolverPackage spackage;
6621:     MatFactorGetSolverPackage(fact,&spackage);
6622:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6623:   }
6624:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6625:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6626:   MatCheckPreallocated(mat,2);

6628:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6629:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6630:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6631:   return(0);
6632: }

6634: /*@C
6635:    MatICCFactorSymbolic - Performs symbolic incomplete
6636:    Cholesky factorization for a symmetric matrix.  Use
6637:    MatCholeskyFactorNumeric() to complete the factorization.

6639:    Collective on Mat

6641:    Input Parameters:
6642: +  mat - the matrix
6643: .  perm - row and column permutation
6644: -  info - structure containing
6645: $      levels - number of levels of fill.
6646: $      expected fill - as ratio of original fill.

6648:    Output Parameter:
6649: .  fact - the factored matrix

6651:    Notes:
6652:    Most users should employ the KSP interface for linear solvers
6653:    instead of working directly with matrix algebra routines such as this.
6654:    See, e.g., KSPCreate().

6656:    Level: developer

6658:   Concepts: matrices^symbolic incomplete Cholesky factorization
6659:   Concepts: matrices^factorization
6660:   Concepts: Cholsky^symbolic factorization

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

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

6667: @*/
6668: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6669: {

6678:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6679:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6680:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6681:   if (!(fact)->ops->iccfactorsymbolic) {
6682:     const MatSolverPackage spackage;
6683:     MatFactorGetSolverPackage(fact,&spackage);
6684:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6685:   }
6686:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6687:   MatCheckPreallocated(mat,2);

6689:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6690:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6691:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6692:   return(0);
6693: }

6695: /*@C
6696:    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6697:    points to an array of valid matrices, they may be reused to store the new
6698:    submatrices.

6700:    Collective on Mat

6702:    Input Parameters:
6703: +  mat - the matrix
6704: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6705: .  irow, icol - index sets of rows and columns to extract
6706: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6708:    Output Parameter:
6709: .  submat - the array of submatrices

6711:    Notes:
6712:    MatCreateSubMatrices() can extract ONLY sequential submatrices
6713:    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6714:    to extract a parallel submatrix.

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

6719:    The index sets may not have duplicate entries.

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

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

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

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

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

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

6743:    Level: advanced

6745:    Concepts: matrices^accessing submatrices
6746:    Concepts: submatrices

6748: .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6749: @*/
6750: PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6751: {
6753:   PetscInt       i;
6754:   PetscBool      eq;

6759:   if (n) {
6764:   }
6766:   if (n && scall == MAT_REUSE_MATRIX) {
6769:   }
6770:   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6771:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6772:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6773:   MatCheckPreallocated(mat,1);

6775:   PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6776:   (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);
6777:   PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6778:   for (i=0; i<n; i++) {
6779:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6780:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6781:       ISEqual(irow[i],icol[i],&eq);
6782:       if (eq) {
6783:         if (mat->symmetric) {
6784:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6785:         } else if (mat->hermitian) {
6786:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6787:         } else if (mat->structurally_symmetric) {
6788:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6789:         }
6790:       }
6791:     }
6792:   }
6793:   return(0);
6794: }

6796: /*@C
6797:    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).

6799:    Collective on Mat

6801:    Input Parameters:
6802: +  mat - the matrix
6803: .  n   - the number of submatrixes to be extracted
6804: .  irow, icol - index sets of rows and columns to extract
6805: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6807:    Output Parameter:
6808: .  submat - the array of submatrices

6810:    Level: advanced

6812:    Concepts: matrices^accessing submatrices
6813:    Concepts: submatrices

6815: .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6816: @*/
6817: PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6818: {
6820:   PetscInt       i;
6821:   PetscBool      eq;

6826:   if (n) {
6831:   }
6833:   if (n && scall == MAT_REUSE_MATRIX) {
6836:   }
6837:   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6838:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6839:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6840:   MatCheckPreallocated(mat,1);

6842:   PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6843:   (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6844:   PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6845:   for (i=0; i<n; i++) {
6846:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6847:       ISEqual(irow[i],icol[i],&eq);
6848:       if (eq) {
6849:         if (mat->symmetric) {
6850:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6851:         } else if (mat->hermitian) {
6852:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6853:         } else if (mat->structurally_symmetric) {
6854:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6855:         }
6856:       }
6857:     }
6858:   }
6859:   return(0);
6860: }

6862: /*@C
6863:    MatDestroyMatrices - Destroys an array of matrices.

6865:    Collective on Mat

6867:    Input Parameters:
6868: +  n - the number of local matrices
6869: -  mat - the matrices (note that this is a pointer to the array of matrices)

6871:    Level: advanced

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

6876: .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6877: @*/
6878: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6879: {
6881:   PetscInt       i;

6884:   if (!*mat) return(0);
6885:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);

6888:   for (i=0; i<n; i++) {
6889:     MatDestroy(&(*mat)[i]);
6890:   }

6892:   /* memory is allocated even if n = 0 */
6893:   PetscFree(*mat);
6894:   return(0);
6895: }

6897: /*@C
6898:    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().

6900:    Collective on Mat

6902:    Input Parameters:
6903: +  n - the number of local matrices
6904: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6905:                        sequence of MatCreateSubMatrices())

6907:    Level: advanced

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

6912: .seealso: MatCreateSubMatrices()
6913: @*/
6914: PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6915: {
6917:   Mat            mat0;

6920:   if (!*mat) return(0);
6921:   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6922:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);

6925:   mat0 = (*mat)[0];
6926:   if (mat0 && mat0->ops->destroysubmatrices) {
6927:     (mat0->ops->destroysubmatrices)(n,mat);
6928:   } else {
6929:     MatDestroyMatrices(n,mat);
6930:   }
6931:   return(0);
6932: }

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

6937:    Collective on Mat

6939:    Input Parameters:
6940: .  mat - the matrix

6942:    Output Parameter:
6943: .  matstruct - the sequential matrix with the nonzero structure of mat

6945:   Level: intermediate

6947: .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6948: @*/
6949: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6950: {


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

6961:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6962:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6963:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6964:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6965:   return(0);
6966: }

6968: /*@C
6969:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6971:    Collective on Mat

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

6977:    Level: advanced

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

6981: .seealso: MatGetSeqNonzeroStructure()
6982: @*/
6983: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6984: {

6989:   MatDestroy(mat);
6990:   return(0);
6991: }

6993: /*@
6994:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6995:    replaces the index sets by larger ones that represent submatrices with
6996:    additional overlap.

6998:    Collective on Mat

7000:    Input Parameters:
7001: +  mat - the matrix
7002: .  n   - the number of index sets
7003: .  is  - the array of index sets (these index sets will changed during the call)
7004: -  ov  - the additional overlap requested

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

7009:    Level: developer

7011:    Concepts: overlap
7012:    Concepts: ASM^computing overlap

7014: .seealso: MatCreateSubMatrices()
7015: @*/
7016: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7017: {

7023:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7024:   if (n) {
7027:   }
7028:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7029:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7030:   MatCheckPreallocated(mat,1);

7032:   if (!ov) return(0);
7033:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7034:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
7035:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
7036:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
7037:   return(0);
7038: }


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

7043: /*@
7044:    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7045:    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7046:    additional overlap.

7048:    Collective on Mat

7050:    Input Parameters:
7051: +  mat - the matrix
7052: .  n   - the number of index sets
7053: .  is  - the array of index sets (these index sets will changed during the call)
7054: -  ov  - the additional overlap requested

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

7059:    Level: developer

7061:    Concepts: overlap
7062:    Concepts: ASM^computing overlap

7064: .seealso: MatCreateSubMatrices()
7065: @*/
7066: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7067: {
7068:   PetscInt       i;

7074:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7075:   if (n) {
7078:   }
7079:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7080:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7081:   MatCheckPreallocated(mat,1);
7082:   if (!ov) return(0);
7083:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
7084:   for(i=0; i<n; i++){
7085:          MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
7086:   }
7087:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
7088:   return(0);
7089: }




7094: /*@
7095:    MatGetBlockSize - Returns the matrix block size.

7097:    Not Collective

7099:    Input Parameter:
7100: .  mat - the matrix

7102:    Output Parameter:
7103: .  bs - block size

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

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

7110:    Level: intermediate

7112:    Concepts: matrices^block size

7114: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7115: @*/
7116: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7117: {
7121:   *bs = PetscAbs(mat->rmap->bs);
7122:   return(0);
7123: }

7125: /*@
7126:    MatGetBlockSizes - Returns the matrix block row and column sizes.

7128:    Not Collective

7130:    Input Parameter:
7131: .  mat - the matrix

7133:    Output Parameter:
7134: .  rbs - row block size
7135: .  cbs - column block size

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

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

7143:    Level: intermediate

7145:    Concepts: matrices^block size

7147: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7148: @*/
7149: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7150: {
7155:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7156:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7157:   return(0);
7158: }

7160: /*@
7161:    MatSetBlockSize - Sets the matrix block size.

7163:    Logically Collective on Mat

7165:    Input Parameters:
7166: +  mat - the matrix
7167: -  bs - block size

7169:    Notes:
7170:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7171:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.

7173:     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7174:     is compatible with the matrix local sizes.

7176:    Level: intermediate

7178:    Concepts: matrices^block size

7180: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7181: @*/
7182: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7183: {

7189:   MatSetBlockSizes(mat,bs,bs);
7190:   return(0);
7191: }

7193: /*@
7194:    MatSetBlockSizes - Sets the matrix block row and column sizes.

7196:    Logically Collective on Mat

7198:    Input Parameters:
7199: +  mat - the matrix
7200: -  rbs - row block size
7201: -  cbs - column block size

7203:    Notes:
7204:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7205:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7206:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

7208:     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7209:     are compatible with the matrix local sizes.

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

7213:    Level: intermediate

7215:    Concepts: matrices^block size

7217: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7218: @*/
7219: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7220: {

7227:   if (mat->ops->setblocksizes) {
7228:     (*mat->ops->setblocksizes)(mat,rbs,cbs);
7229:   }
7230:   if (mat->rmap->refcnt) {
7231:     ISLocalToGlobalMapping l2g = NULL;
7232:     PetscLayout            nmap = NULL;

7234:     PetscLayoutDuplicate(mat->rmap,&nmap);
7235:     if (mat->rmap->mapping) {
7236:       ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);
7237:     }
7238:     PetscLayoutDestroy(&mat->rmap);
7239:     mat->rmap = nmap;
7240:     mat->rmap->mapping = l2g;
7241:   }
7242:   if (mat->cmap->refcnt) {
7243:     ISLocalToGlobalMapping l2g = NULL;
7244:     PetscLayout            nmap = NULL;

7246:     PetscLayoutDuplicate(mat->cmap,&nmap);
7247:     if (mat->cmap->mapping) {
7248:       ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);
7249:     }
7250:     PetscLayoutDestroy(&mat->cmap);
7251:     mat->cmap = nmap;
7252:     mat->cmap->mapping = l2g;
7253:   }
7254:   PetscLayoutSetBlockSize(mat->rmap,rbs);
7255:   PetscLayoutSetBlockSize(mat->cmap,cbs);
7256:   return(0);
7257: }

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

7262:    Logically Collective on Mat

7264:    Input Parameters:
7265: +  mat - the matrix
7266: .  fromRow - matrix from which to copy row block size
7267: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

7269:    Level: developer

7271:    Concepts: matrices^block size

7273: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7274: @*/
7275: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7276: {

7283:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7284:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7285:   return(0);
7286: }

7288: /*@
7289:    MatResidual - Default routine to calculate the residual.

7291:    Collective on Mat and Vec

7293:    Input Parameters:
7294: +  mat - the matrix
7295: .  b   - the right-hand-side
7296: -  x   - the approximate solution

7298:    Output Parameter:
7299: .  r - location to store the residual

7301:    Level: developer

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

7305: .seealso: PCMGSetResidual()
7306: @*/
7307: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7308: {

7317:   MatCheckPreallocated(mat,1);
7318:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7319:   if (!mat->ops->residual) {
7320:     MatMult(mat,x,r);
7321:     VecAYPX(r,-1.0,b);
7322:   } else {
7323:     (*mat->ops->residual)(mat,b,x,r);
7324:   }
7325:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7326:   return(0);
7327: }

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

7332:    Collective on Mat

7334:     Input Parameters:
7335: +   mat - the matrix
7336: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7337: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7338: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7339:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7340:                  always used.

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

7349:     Level: developer

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

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

7355:     Fortran Node

7357:            In Fortran use
7358: $           PetscInt ia(1), ja(1)
7359: $           PetscOffset iia, jja
7360: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7361: $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7362: $
7363: $          or
7364: $
7365: $           PetscInt, pointer :: ia(:),ja(:)
7366: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7367: $      Acess the ith and jth entries via ia(i) and ja(j)



7371: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7372: @*/
7373: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7374: {

7384:   MatCheckPreallocated(mat,1);
7385:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7386:   else {
7387:     *done = PETSC_TRUE;
7388:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7389:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7390:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7391:   }
7392:   return(0);
7393: }

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

7398:     Collective on Mat

7400:     Input Parameters:
7401: +   mat - the matrix
7402: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7403: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7404:                 symmetrized
7405: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7406:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7407:                  always used.
7408: .   n - number of columns in the (possibly compressed) matrix
7409: .   ia - the column pointers
7410: -   ja - the row indices

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

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

7420:     Level: developer

7422: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7423: @*/
7424: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7425: {

7435:   MatCheckPreallocated(mat,1);
7436:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7437:   else {
7438:     *done = PETSC_TRUE;
7439:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7440:   }
7441:   return(0);
7442: }

7444: /*@C
7445:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7446:     MatGetRowIJ().

7448:     Collective on Mat

7450:     Input Parameters:
7451: +   mat - the matrix
7452: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7453: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7454:                 symmetrized
7455: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7456:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7457:                  always used.
7458: .   n - size of (possibly compressed) matrix
7459: .   ia - the row pointers
7460: -   ja - the column indices

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

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

7470:     Level: developer

7472: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7473: @*/
7474: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7475: {

7484:   MatCheckPreallocated(mat,1);

7486:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7487:   else {
7488:     *done = PETSC_TRUE;
7489:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7490:     if (n)  *n = 0;
7491:     if (ia) *ia = NULL;
7492:     if (ja) *ja = NULL;
7493:   }
7494:   return(0);
7495: }

7497: /*@C
7498:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7499:     MatGetColumnIJ().

7501:     Collective on Mat

7503:     Input Parameters:
7504: +   mat - the matrix
7505: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7506: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7507:                 symmetrized
7508: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7509:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7510:                  always used.

7512:     Output Parameters:
7513: +   n - size of (possibly compressed) matrix
7514: .   ia - the column pointers
7515: .   ja - the row indices
7516: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7518:     Level: developer

7520: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7521: @*/
7522: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7523: {

7532:   MatCheckPreallocated(mat,1);

7534:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7535:   else {
7536:     *done = PETSC_TRUE;
7537:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7538:     if (n)  *n = 0;
7539:     if (ia) *ia = NULL;
7540:     if (ja) *ja = NULL;
7541:   }
7542:   return(0);
7543: }

7545: /*@C
7546:     MatColoringPatch -Used inside matrix coloring routines that
7547:     use MatGetRowIJ() and/or MatGetColumnIJ().

7549:     Collective on Mat

7551:     Input Parameters:
7552: +   mat - the matrix
7553: .   ncolors - max color value
7554: .   n   - number of entries in colorarray
7555: -   colorarray - array indicating color for each column

7557:     Output Parameters:
7558: .   iscoloring - coloring generated using colorarray information

7560:     Level: developer

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

7564: @*/
7565: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7566: {

7574:   MatCheckPreallocated(mat,1);

7576:   if (!mat->ops->coloringpatch) {
7577:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7578:   } else {
7579:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7580:   }
7581:   return(0);
7582: }


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

7588:    Logically Collective on Mat

7590:    Input Parameter:
7591: .  mat - the factored matrix to be reset

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

7600:    Note that one can specify in-place ILU(0) factorization by calling
7601: .vb
7602:      PCType(pc,PCILU);
7603:      PCFactorSeUseInPlace(pc);
7604: .ve
7605:    or by using the options -pc_type ilu -pc_factor_in_place

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

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

7616:    Level: developer

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

7620:    Concepts: matrices^unfactored

7622: @*/
7623: PetscErrorCode MatSetUnfactored(Mat mat)
7624: {

7630:   MatCheckPreallocated(mat,1);
7631:   mat->factortype = MAT_FACTOR_NONE;
7632:   if (!mat->ops->setunfactored) return(0);
7633:   (*mat->ops->setunfactored)(mat);
7634:   return(0);
7635: }

7637: /*MC
7638:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7640:     Synopsis:
7641:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7643:     Not collective

7645:     Input Parameter:
7646: .   x - matrix

7648:     Output Parameters:
7649: +   xx_v - the Fortran90 pointer to the array
7650: -   ierr - error code

7652:     Example of Usage:
7653: .vb
7654:       PetscScalar, pointer xx_v(:,:)
7655:       ....
7656:       call MatDenseGetArrayF90(x,xx_v,ierr)
7657:       a = xx_v(3)
7658:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7659: .ve

7661:     Level: advanced

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

7665:     Concepts: matrices^accessing array

7667: M*/

7669: /*MC
7670:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7671:     accessed with MatDenseGetArrayF90().

7673:     Synopsis:
7674:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7676:     Not collective

7678:     Input Parameters:
7679: +   x - matrix
7680: -   xx_v - the Fortran90 pointer to the array

7682:     Output Parameter:
7683: .   ierr - error code

7685:     Example of Usage:
7686: .vb
7687:        PetscScalar, pointer xx_v(:,:)
7688:        ....
7689:        call MatDenseGetArrayF90(x,xx_v,ierr)
7690:        a = xx_v(3)
7691:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7692: .ve

7694:     Level: advanced

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

7698: M*/


7701: /*MC
7702:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7704:     Synopsis:
7705:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7707:     Not collective

7709:     Input Parameter:
7710: .   x - matrix

7712:     Output Parameters:
7713: +   xx_v - the Fortran90 pointer to the array
7714: -   ierr - error code

7716:     Example of Usage:
7717: .vb
7718:       PetscScalar, pointer xx_v(:)
7719:       ....
7720:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7721:       a = xx_v(3)
7722:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7723: .ve

7725:     Level: advanced

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

7729:     Concepts: matrices^accessing array

7731: M*/

7733: /*MC
7734:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7735:     accessed with MatSeqAIJGetArrayF90().

7737:     Synopsis:
7738:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7740:     Not collective

7742:     Input Parameters:
7743: +   x - matrix
7744: -   xx_v - the Fortran90 pointer to the array

7746:     Output Parameter:
7747: .   ierr - error code

7749:     Example of Usage:
7750: .vb
7751:        PetscScalar, pointer xx_v(:)
7752:        ....
7753:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7754:        a = xx_v(3)
7755:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7756: .ve

7758:     Level: advanced

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

7762: M*/


7765: /*@
7766:     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7767:                       as the original matrix.

7769:     Collective on Mat

7771:     Input Parameters:
7772: +   mat - the original matrix
7773: .   isrow - parallel IS containing the rows this processor should obtain
7774: .   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.
7775: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7777:     Output Parameter:
7778: .   newmat - the new submatrix, of the same type as the old

7780:     Level: advanced

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

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

7788:     The index sets may not have duplicate entries.

7790:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7791:    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7792:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7793:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7794:    you are finished using it.

7796:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7797:     the input matrix.

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

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

7807: .vb
7808:             1  2  0  |  0  3  0  |  0  4
7809:     Proc0   0  5  6  |  7  0  0  |  8  0
7810:             9  0 10  | 11  0  0  | 12  0
7811:     -------------------------------------
7812:            13  0 14  | 15 16 17  |  0  0
7813:     Proc1   0 18  0  | 19 20 21  |  0  0
7814:             0  0  0  | 22 23  0  | 24  0
7815:     -------------------------------------
7816:     Proc2  25 26 27  |  0  0 28  | 29  0
7817:            30  0  0  | 31 32 33  |  0 34
7818: .ve

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

7822: .vb
7823:             2  0  |  0  3  0  |  0
7824:     Proc0   5  6  |  7  0  0  |  8
7825:     -------------------------------
7826:     Proc1  18  0  | 19 20 21  |  0
7827:     -------------------------------
7828:     Proc2  26 27  |  0  0 28  | 29
7829:             0  0  | 31 32 33  |  0
7830: .ve


7833:     Concepts: matrices^submatrices

7835: .seealso: MatCreateSubMatrices()
7836: @*/
7837: PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7838: {
7840:   PetscMPIInt    size;
7841:   Mat            *local;
7842:   IS             iscoltmp;

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

7854:   MatCheckPreallocated(mat,1);
7855:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7857:   if (!iscol || isrow == iscol) {
7858:     PetscBool   stride;
7859:     PetscMPIInt grabentirematrix = 0,grab;
7860:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7861:     if (stride) {
7862:       PetscInt first,step,n,rstart,rend;
7863:       ISStrideGetInfo(isrow,&first,&step);
7864:       if (step == 1) {
7865:         MatGetOwnershipRange(mat,&rstart,&rend);
7866:         if (rstart == first) {
7867:           ISGetLocalSize(isrow,&n);
7868:           if (n == rend-rstart) {
7869:             grabentirematrix = 1;
7870:           }
7871:         }
7872:       }
7873:     }
7874:     MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7875:     if (grab) {
7876:       PetscInfo(mat,"Getting entire matrix as submatrix\n");
7877:       if (cll == MAT_INITIAL_MATRIX) {
7878:         *newmat = mat;
7879:         PetscObjectReference((PetscObject)mat);
7880:       }
7881:       return(0);
7882:     }
7883:   }

7885:   if (!iscol) {
7886:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7887:   } else {
7888:     iscoltmp = iscol;
7889:   }

7891:   /* if original matrix is on just one processor then use submatrix generated */
7892:   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7893:     MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7894:     if (!iscol) {ISDestroy(&iscoltmp);}
7895:     return(0);
7896:   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7897:     MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7898:     *newmat = *local;
7899:     PetscFree(local);
7900:     if (!iscol) {ISDestroy(&iscoltmp);}
7901:     return(0);
7902:   } else if (!mat->ops->createsubmatrix) {
7903:     /* Create a new matrix type that implements the operation using the full matrix */
7904:     PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7905:     switch (cll) {
7906:     case MAT_INITIAL_MATRIX:
7907:       MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);
7908:       break;
7909:     case MAT_REUSE_MATRIX:
7910:       MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);
7911:       break;
7912:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7913:     }
7914:     PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);
7915:     if (!iscol) {ISDestroy(&iscoltmp);}
7916:     return(0);
7917:   }

7919:   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7920:   PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7921:   (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7922:   PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);
7923:   if (!iscol) {ISDestroy(&iscoltmp);}
7924:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7925:   return(0);
7926: }

7928: /*@
7929:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7930:    used during the assembly process to store values that belong to
7931:    other processors.

7933:    Not Collective

7935:    Input Parameters:
7936: +  mat   - the matrix
7937: .  size  - the initial size of the stash.
7938: -  bsize - the initial size of the block-stash(if used).

7940:    Options Database Keys:
7941: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7942: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7944:    Level: intermediate

7946:    Notes:
7947:      The block-stash is used for values set with MatSetValuesBlocked() while
7948:      the stash is used for values set with MatSetValues()

7950:      Run with the option -info and look for output of the form
7951:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7952:      to determine the appropriate value, MM, to use for size and
7953:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7954:      to determine the value, BMM to use for bsize

7956:    Concepts: stash^setting matrix size
7957:    Concepts: matrices^stash

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

7961: @*/
7962: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7963: {

7969:   MatStashSetInitialSize_Private(&mat->stash,size);
7970:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7971:   return(0);
7972: }

7974: /*@
7975:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7976:      the matrix

7978:    Neighbor-wise Collective on Mat

7980:    Input Parameters:
7981: +  mat   - the matrix
7982: .  x,y - the vectors
7983: -  w - where the result is stored

7985:    Level: intermediate

7987:    Notes:
7988:     w may be the same vector as y.

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

7993:     Concepts: interpolation

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

7997: @*/
7998: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7999: {
8001:   PetscInt       M,N,Ny;

8009:   MatCheckPreallocated(A,1);
8010:   MatGetSize(A,&M,&N);
8011:   VecGetSize(y,&Ny);
8012:   if (M == Ny) {
8013:     MatMultAdd(A,x,y,w);
8014:   } else {
8015:     MatMultTransposeAdd(A,x,y,w);
8016:   }
8017:   return(0);
8018: }

8020: /*@
8021:    MatInterpolate - y = A*x or A'*x depending on the shape of
8022:      the matrix

8024:    Neighbor-wise Collective on Mat

8026:    Input Parameters:
8027: +  mat   - the matrix
8028: -  x,y - the vectors

8030:    Level: intermediate

8032:    Notes:
8033:     This allows one to use either the restriction or interpolation (its transpose)
8034:     matrix to do the interpolation

8036:    Concepts: matrices^interpolation

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

8040: @*/
8041: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8042: {
8044:   PetscInt       M,N,Ny;

8051:   MatCheckPreallocated(A,1);
8052:   MatGetSize(A,&M,&N);
8053:   VecGetSize(y,&Ny);
8054:   if (M == Ny) {
8055:     MatMult(A,x,y);
8056:   } else {
8057:     MatMultTranspose(A,x,y);
8058:   }
8059:   return(0);
8060: }

8062: /*@
8063:    MatRestrict - y = A*x or A'*x

8065:    Neighbor-wise Collective on Mat

8067:    Input Parameters:
8068: +  mat   - the matrix
8069: -  x,y - the vectors

8071:    Level: intermediate

8073:    Notes:
8074:     This allows one to use either the restriction or interpolation (its transpose)
8075:     matrix to do the restriction

8077:    Concepts: matrices^restriction

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

8081: @*/
8082: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8083: {
8085:   PetscInt       M,N,Ny;

8092:   MatCheckPreallocated(A,1);

8094:   MatGetSize(A,&M,&N);
8095:   VecGetSize(y,&Ny);
8096:   if (M == Ny) {
8097:     MatMult(A,x,y);
8098:   } else {
8099:     MatMultTranspose(A,x,y);
8100:   }
8101:   return(0);
8102: }

8104: /*@
8105:    MatGetNullSpace - retrieves the null space to a matrix.

8107:    Logically Collective on Mat and MatNullSpace

8109:    Input Parameters:
8110: +  mat - the matrix
8111: -  nullsp - the null space object

8113:    Level: developer

8115:    Concepts: null space^attaching to matrix

8117: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8118: @*/
8119: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8120: {
8125:   *nullsp = mat->nullsp;
8126:   return(0);
8127: }

8129: /*@
8130:    MatSetNullSpace - attaches a null space to a matrix.

8132:    Logically Collective on Mat and MatNullSpace

8134:    Input Parameters:
8135: +  mat - the matrix
8136: -  nullsp - the null space object

8138:    Level: advanced

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

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

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


8149:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8150:    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).
8151:    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
8152:    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
8153:    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).

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

8157:     If the matrix is known to be symmetric because it is an SBAIJ matrix or one as called MatSetOption(mat,MAT_SYMMETRIC or MAT_SYMMETRIC_ETERNAL,PETSC_TRUE); this
8158:     routine also automatically calls MatSetTransposeNullSpace().

8160:    Concepts: null space^attaching to matrix

8162: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8163: @*/
8164: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8165: {

8172:   MatCheckPreallocated(mat,1);
8173:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8174:   MatNullSpaceDestroy(&mat->nullsp);
8175:   mat->nullsp = nullsp;
8176:   if (mat->symmetric_set && mat->symmetric) {
8177:     MatSetTransposeNullSpace(mat,nullsp);
8178:   }
8179:   return(0);
8180: }

8182: /*@
8183:    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.

8185:    Logically Collective on Mat and MatNullSpace

8187:    Input Parameters:
8188: +  mat - the matrix
8189: -  nullsp - the null space object

8191:    Level: developer

8193:    Concepts: null space^attaching to matrix

8195: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8196: @*/
8197: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8198: {
8203:   *nullsp = mat->transnullsp;
8204:   return(0);
8205: }

8207: /*@
8208:    MatSetTransposeNullSpace - attaches a null space to a matrix.

8210:    Logically Collective on Mat and MatNullSpace

8212:    Input Parameters:
8213: +  mat - the matrix
8214: -  nullsp - the null space object

8216:    Level: advanced

8218:    Notes:
8219:       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.
8220:       You must also call MatSetNullSpace()


8223:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8224:    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).
8225:    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
8226:    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
8227:    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).

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

8231:    Concepts: null space^attaching to matrix

8233: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8234: @*/
8235: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8236: {

8243:   MatCheckPreallocated(mat,1);
8244:   PetscObjectReference((PetscObject)nullsp);
8245:   MatNullSpaceDestroy(&mat->transnullsp);
8246:   mat->transnullsp = nullsp;
8247:   return(0);
8248: }

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

8254:    Logically Collective on Mat and MatNullSpace

8256:    Input Parameters:
8257: +  mat - the matrix
8258: -  nullsp - the null space object

8260:    Level: advanced

8262:    Notes:
8263:       Overwrites any previous near null space that may have been attached

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

8267:    Concepts: null space^attaching to matrix

8269: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8270: @*/
8271: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8272: {

8279:   MatCheckPreallocated(mat,1);
8280:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8281:   MatNullSpaceDestroy(&mat->nearnullsp);
8282:   mat->nearnullsp = nullsp;
8283:   return(0);
8284: }

8286: /*@
8287:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

8289:    Not Collective

8291:    Input Parameters:
8292: .  mat - the matrix

8294:    Output Parameters:
8295: .  nullsp - the null space object, NULL if not set

8297:    Level: developer

8299:    Concepts: null space^attaching to matrix

8301: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8302: @*/
8303: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8304: {
8309:   MatCheckPreallocated(mat,1);
8310:   *nullsp = mat->nearnullsp;
8311:   return(0);
8312: }

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

8317:    Collective on Mat

8319:    Input Parameters:
8320: +  mat - the matrix
8321: .  row - row/column permutation
8322: .  fill - expected fill factor >= 1.0
8323: -  level - level of fill, for ICC(k)

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

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

8333:    Level: developer

8335:    Concepts: matrices^incomplete Cholesky factorization
8336:    Concepts: Cholesky factorization

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

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

8343: @*/
8344: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8345: {

8353:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8354:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8355:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8356:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8357:   MatCheckPreallocated(mat,1);
8358:   (*mat->ops->iccfactor)(mat,row,info);
8359:   PetscObjectStateIncrease((PetscObject)mat);
8360:   return(0);
8361: }

8363: /*@
8364:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8365:          ghosted ones.

8367:    Not Collective

8369:    Input Parameters:
8370: +  mat - the matrix
8371: -  diag = the diagonal values, including ghost ones

8373:    Level: developer

8375:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

8377: .seealso: MatDiagonalScale()
8378: @*/
8379: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8380: {
8382:   PetscMPIInt    size;


8389:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8390:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8391:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8392:   if (size == 1) {
8393:     PetscInt n,m;
8394:     VecGetSize(diag,&n);
8395:     MatGetSize(mat,0,&m);
8396:     if (m == n) {
8397:       MatDiagonalScale(mat,0,diag);
8398:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8399:   } else {
8400:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8401:   }
8402:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8403:   PetscObjectStateIncrease((PetscObject)mat);
8404:   return(0);
8405: }

8407: /*@
8408:    MatGetInertia - Gets the inertia from a factored matrix

8410:    Collective on Mat

8412:    Input Parameter:
8413: .  mat - the matrix

8415:    Output Parameters:
8416: +   nneg - number of negative eigenvalues
8417: .   nzero - number of zero eigenvalues
8418: -   npos - number of positive eigenvalues

8420:    Level: advanced

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


8425: @*/
8426: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8427: {

8433:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8434:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8435:   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8436:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8437:   return(0);
8438: }

8440: /* ----------------------------------------------------------------*/
8441: /*@C
8442:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

8444:    Neighbor-wise Collective on Mat and Vecs

8446:    Input Parameters:
8447: +  mat - the factored matrix
8448: -  b - the right-hand-side vectors

8450:    Output Parameter:
8451: .  x - the result vectors

8453:    Notes:
8454:    The vectors b and x cannot be the same.  I.e., one cannot
8455:    call MatSolves(A,x,x).

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

8462:    Level: developer

8464:    Concepts: matrices^triangular solves

8466: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8467: @*/
8468: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8469: {

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

8479:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8480:   MatCheckPreallocated(mat,1);
8481:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8482:   (*mat->ops->solves)(mat,b,x);
8483:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8484:   return(0);
8485: }

8487: /*@
8488:    MatIsSymmetric - Test whether a matrix is symmetric

8490:    Collective on Mat

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

8496:    Output Parameters:
8497: .  flg - the result

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

8501:    Level: intermediate

8503:    Concepts: matrix^symmetry

8505: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8506: @*/
8507: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8508: {


8515:   if (!A->symmetric_set) {
8516:     if (!A->ops->issymmetric) {
8517:       MatType mattype;
8518:       MatGetType(A,&mattype);
8519:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8520:     }
8521:     (*A->ops->issymmetric)(A,tol,flg);
8522:     if (!tol) {
8523:       A->symmetric_set = PETSC_TRUE;
8524:       A->symmetric     = *flg;
8525:       if (A->symmetric) {
8526:         A->structurally_symmetric_set = PETSC_TRUE;
8527:         A->structurally_symmetric     = PETSC_TRUE;
8528:       }
8529:     }
8530:   } else if (A->symmetric) {
8531:     *flg = PETSC_TRUE;
8532:   } else if (!tol) {
8533:     *flg = PETSC_FALSE;
8534:   } else {
8535:     if (!A->ops->issymmetric) {
8536:       MatType mattype;
8537:       MatGetType(A,&mattype);
8538:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8539:     }
8540:     (*A->ops->issymmetric)(A,tol,flg);
8541:   }
8542:   return(0);
8543: }

8545: /*@
8546:    MatIsHermitian - Test whether a matrix is Hermitian

8548:    Collective on Mat

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

8554:    Output Parameters:
8555: .  flg - the result

8557:    Level: intermediate

8559:    Concepts: matrix^symmetry

8561: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8562:           MatIsSymmetricKnown(), MatIsSymmetric()
8563: @*/
8564: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8565: {


8572:   if (!A->hermitian_set) {
8573:     if (!A->ops->ishermitian) {
8574:       MatType mattype;
8575:       MatGetType(A,&mattype);
8576:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8577:     }
8578:     (*A->ops->ishermitian)(A,tol,flg);
8579:     if (!tol) {
8580:       A->hermitian_set = PETSC_TRUE;
8581:       A->hermitian     = *flg;
8582:       if (A->hermitian) {
8583:         A->structurally_symmetric_set = PETSC_TRUE;
8584:         A->structurally_symmetric     = PETSC_TRUE;
8585:       }
8586:     }
8587:   } else if (A->hermitian) {
8588:     *flg = PETSC_TRUE;
8589:   } else if (!tol) {
8590:     *flg = PETSC_FALSE;
8591:   } else {
8592:     if (!A->ops->ishermitian) {
8593:       MatType mattype;
8594:       MatGetType(A,&mattype);
8595:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8596:     }
8597:     (*A->ops->ishermitian)(A,tol,flg);
8598:   }
8599:   return(0);
8600: }

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

8605:    Not Collective

8607:    Input Parameter:
8608: .  A - the matrix to check

8610:    Output Parameters:
8611: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8612: -  flg - the result

8614:    Level: advanced

8616:    Concepts: matrix^symmetry

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

8621: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8622: @*/
8623: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8624: {
8629:   if (A->symmetric_set) {
8630:     *set = PETSC_TRUE;
8631:     *flg = A->symmetric;
8632:   } else {
8633:     *set = PETSC_FALSE;
8634:   }
8635:   return(0);
8636: }

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

8641:    Not Collective

8643:    Input Parameter:
8644: .  A - the matrix to check

8646:    Output Parameters:
8647: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8648: -  flg - the result

8650:    Level: advanced

8652:    Concepts: matrix^symmetry

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

8657: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8658: @*/
8659: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8660: {
8665:   if (A->hermitian_set) {
8666:     *set = PETSC_TRUE;
8667:     *flg = A->hermitian;
8668:   } else {
8669:     *set = PETSC_FALSE;
8670:   }
8671:   return(0);
8672: }

8674: /*@
8675:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8677:    Collective on Mat

8679:    Input Parameter:
8680: .  A - the matrix to test

8682:    Output Parameters:
8683: .  flg - the result

8685:    Level: intermediate

8687:    Concepts: matrix^symmetry

8689: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8690: @*/
8691: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8692: {

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

8702:     A->structurally_symmetric_set = PETSC_TRUE;
8703:   }
8704:   *flg = A->structurally_symmetric;
8705:   return(0);
8706: }

8708: /*@
8709:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8710:        to be communicated to other processors during the MatAssemblyBegin/End() process

8712:     Not collective

8714:    Input Parameter:
8715: .   vec - the vector

8717:    Output Parameters:
8718: +   nstash   - the size of the stash
8719: .   reallocs - the number of additional mallocs incurred.
8720: .   bnstash   - the size of the block stash
8721: -   breallocs - the number of additional mallocs incurred.in the block stash

8723:    Level: advanced

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

8727: @*/
8728: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8729: {

8733:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8734:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8735:   return(0);
8736: }

8738: /*@C
8739:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8740:      parallel layout

8742:    Collective on Mat

8744:    Input Parameter:
8745: .  mat - the matrix

8747:    Output Parameter:
8748: +   right - (optional) vector that the matrix can be multiplied against
8749: -   left - (optional) vector that the matrix vector product can be stored in

8751:    Notes:
8752:     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().

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

8756:   Level: advanced

8758: .seealso: MatCreate(), VecDestroy()
8759: @*/
8760: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8761: {

8767:   if (mat->ops->getvecs) {
8768:     (*mat->ops->getvecs)(mat,right,left);
8769:   } else {
8770:     PetscInt rbs,cbs;
8771:     MatGetBlockSizes(mat,&rbs,&cbs);
8772:     if (right) {
8773:       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8774:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8775:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8776:       VecSetBlockSize(*right,cbs);
8777:       VecSetType(*right,VECSTANDARD);
8778:       PetscLayoutReference(mat->cmap,&(*right)->map);
8779:     }
8780:     if (left) {
8781:       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8782:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8783:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8784:       VecSetBlockSize(*left,rbs);
8785:       VecSetType(*left,VECSTANDARD);
8786:       PetscLayoutReference(mat->rmap,&(*left)->map);
8787:     }
8788:   }
8789:   return(0);
8790: }

8792: /*@C
8793:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8794:      with default values.

8796:    Not Collective

8798:    Input Parameters:
8799: .    info - the MatFactorInfo data structure


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

8805:    Level: developer

8807: .seealso: MatFactorInfo

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

8812: @*/

8814: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8815: {

8819:   PetscMemzero(info,sizeof(MatFactorInfo));
8820:   return(0);
8821: }

8823: /*@
8824:    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed

8826:    Collective on Mat

8828:    Input Parameters:
8829: +  mat - the factored matrix
8830: -  is - the index set defining the Schur indices (0-based)

8832:    Notes:  Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.

8834:    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.

8836:    Level: developer

8838:    Concepts:

8840: .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8841:           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()

8843: @*/
8844: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8845: {
8846:   PetscErrorCode ierr,(*f)(Mat,IS);

8854:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8855:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8856:   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");
8857:   if (mat->schur) {
8858:     MatDestroy(&mat->schur);
8859:   }
8860:   (*f)(mat,is);
8861:   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8862:   MatFactorSetUpInPlaceSchur_Private(mat);
8863:   return(0);
8864: }

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

8869:    Logically Collective on Mat

8871:    Input Parameters:
8872: +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8873: .  S - location where to return the Schur complement, can be NULL
8874: -  status - the status of the Schur complement matrix, can be NULL

8876:    Notes:
8877:    You must call MatFactorSetSchurIS() before calling this routine.

8879:    The routine provides a copy of the Schur matrix stored within the solver data structures.
8880:    The caller must destroy the object when it is no longer needed.
8881:    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.

8883:    Use MatFactorGetSchurComplement() to get access to the Schur complement matrix inside the factored matrix instead of making a copy of it (which this function does)

8885:    Developer Notes: The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
8886:    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.

8888:    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.

8890:    Level: advanced

8892:    References:

8894: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8895: @*/
8896: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8897: {

8904:   if (S) {
8905:     PetscErrorCode (*f)(Mat,Mat*);

8907:     PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);
8908:     if (f) {
8909:       (*f)(F,S);
8910:     } else {
8911:       MatDuplicate(F->schur,MAT_COPY_VALUES,S);
8912:     }
8913:   }
8914:   if (status) *status = F->schur_status;
8915:   return(0);
8916: }

8918: /*@
8919:   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix

8921:    Logically Collective on Mat

8923:    Input Parameters:
8924: +  F - the factored matrix obtained by calling MatGetFactor()
8925: .  *S - location where to return the Schur complement, can be NULL
8926: -  status - the status of the Schur complement matrix, can be NULL

8928:    Notes:
8929:    You must call MatFactorSetSchurIS() before calling this routine.

8931:    Schur complement mode is currently implemented for sequential matrices.
8932:    The routine returns a the Schur Complement stored within the data strutures of the solver.
8933:    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8934:    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.

8936:    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix

8938:    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.

8940:    Level: advanced

8942:    References:

8944: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8945: @*/
8946: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8947: {
8952:   if (S) *S = F->schur;
8953:   if (status) *status = F->schur_status;
8954:   return(0);
8955: }

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

8960:    Logically Collective on Mat

8962:    Input Parameters:
8963: +  F - the factored matrix obtained by calling MatGetFactor()
8964: .  *S - location where the Schur complement is stored
8965: -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)

8967:    Notes:

8969:    Level: advanced

8971:    References:

8973: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8974: @*/
8975: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8976: {

8981:   if (S) {
8983:     *S = NULL;
8984:   }
8985:   F->schur_status = status;
8986:   MatFactorUpdateSchurStatus_Private(F);
8987:   return(0);
8988: }

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

8993:    Logically Collective on Mat

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

9000:    Notes:
9001:    The sizes of the vectors should match the size of the Schur complement

9003:    Must be called after MatFactorSetSchurIS()

9005:    Level: advanced

9007:    References:

9009: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9010: @*/
9011: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9012: {

9024:   MatFactorFactorizeSchurComplement(F);
9025:   switch (F->schur_status) {
9026:   case MAT_FACTOR_SCHUR_FACTORED:
9027:     MatSolveTranspose(F->schur,rhs,sol);
9028:     break;
9029:   case MAT_FACTOR_SCHUR_INVERTED:
9030:     MatMultTranspose(F->schur,rhs,sol);
9031:     break;
9032:   default:
9033:     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9034:     break;
9035:   }
9036:   return(0);
9037: }

9039: /*@
9040:   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step

9042:    Logically Collective on Mat

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

9049:    Notes:
9050:    The sizes of the vectors should match the size of the Schur complement

9052:    Must be called after MatFactorSetSchurIS()

9054:    Level: advanced

9056:    References:

9058: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9059: @*/
9060: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9061: {

9073:   MatFactorFactorizeSchurComplement(F);
9074:   switch (F->schur_status) {
9075:   case MAT_FACTOR_SCHUR_FACTORED:
9076:     MatSolve(F->schur,rhs,sol);
9077:     break;
9078:   case MAT_FACTOR_SCHUR_INVERTED:
9079:     MatMult(F->schur,rhs,sol);
9080:     break;
9081:   default:
9082:     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9083:     break;
9084:   }
9085:   return(0);
9086: }

9088: /*@
9089:   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step

9091:    Logically Collective on Mat

9093:    Input Parameters:
9094: +  F - the factored matrix obtained by calling MatGetFactor()

9096:    Notes: Must be called after MatFactorSetSchurIS().

9098:    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.

9100:    Level: advanced

9102:    References:

9104: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9105: @*/
9106: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9107: {

9113:   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) return(0);
9114:   MatFactorFactorizeSchurComplement(F);
9115:   MatFactorInvertSchurComplement_Private(F);
9116:   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9117:   return(0);
9118: }

9120: /*@
9121:   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step

9123:    Logically Collective on Mat

9125:    Input Parameters:
9126: +  F - the factored matrix obtained by calling MatGetFactor()

9128:    Notes: Must be called after MatFactorSetSchurIS().

9130:    Level: advanced

9132:    References:

9134: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9135: @*/
9136: PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9137: {

9143:   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) return(0);
9144:   MatFactorFactorizeSchurComplement_Private(F);
9145:   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9146:   return(0);
9147: }

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

9152:    Neighbor-wise Collective on Mat

9154:    Input Parameters:
9155: +  A - the matrix
9156: .  P - the projection matrix
9157: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9158: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9159:           if the result is a dense matrix this is irrelevent

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

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

9167:    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9168:    which inherit from AIJ.

9170:    Level: intermediate

9172: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9173: @*/
9174: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9175: {
9177:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9178:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9179:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9184:   MatCheckPreallocated(A,1);
9185:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9186:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9187:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9190:   MatCheckPreallocated(P,2);
9191:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9192:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

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

9199:   if (scall == MAT_REUSE_MATRIX) {

9203:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9204:     PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9205:     (*(*C)->ops->ptapnumeric)(A,P,*C);
9206:     PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9207:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9208:     return(0);
9209:   }

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

9214:   fA = A->ops->ptap;
9215:   fP = P->ops->ptap;
9216:   if (fP == fA) {
9217:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9218:     ptap = fA;
9219:   } else {
9220:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9221:     char ptapname[256];
9222:     PetscStrcpy(ptapname,"MatPtAP_");
9223:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
9224:     PetscStrcat(ptapname,"_");
9225:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
9226:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9227:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9228:     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);
9229:   }

9231:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9232:   (*ptap)(A,P,scall,fill,C);
9233:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9234:   return(0);
9235: }

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

9240:    Neighbor-wise Collective on Mat

9242:    Input Parameters:
9243: +  A - the matrix
9244: -  P - the projection matrix

9246:    Output Parameters:
9247: .  C - the product matrix

9249:    Notes:
9250:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9251:    the user using MatDeatroy().

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

9256:    Level: intermediate

9258: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9259: @*/
9260: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9261: {

9267:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9268:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9271:   MatCheckPreallocated(P,2);
9272:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9273:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9276:   MatCheckPreallocated(C,3);
9277:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9278:   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);
9279:   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);
9280:   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);
9281:   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);
9282:   MatCheckPreallocated(A,1);

9284:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9285:   (*C->ops->ptapnumeric)(A,P,C);
9286:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9287:   return(0);
9288: }

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

9293:    Neighbor-wise Collective on Mat

9295:    Input Parameters:
9296: +  A - the matrix
9297: -  P - the projection matrix

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

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

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

9309:    Level: intermediate

9311: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9312: @*/
9313: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9314: {

9320:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9321:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9322:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9325:   MatCheckPreallocated(P,2);
9326:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9327:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9330:   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);
9331:   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);
9332:   MatCheckPreallocated(A,1);
9333:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9334:   (*A->ops->ptapsymbolic)(A,P,fill,C);
9335:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

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

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

9344:    Neighbor-wise Collective on Mat

9346:    Input Parameters:
9347: +  A - the matrix
9348: .  R - the projection matrix
9349: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9350: -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9351:           if the result is a dense matrix this is irrelevent

9353:    Output Parameters:
9354: .  C - the product matrix

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

9359:    This routine is currently only implemented for pairs of AIJ matrices and classes
9360:    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9361:    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9362:    We recommend using MatPtAP().

9364:    Level: intermediate

9366: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9367: @*/
9368: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9369: {

9375:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9376:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9377:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9380:   MatCheckPreallocated(R,2);
9381:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9382:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9384:   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);

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

9390:   if (!A->ops->rart) {
9391:     Mat Rt;
9392:     MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);
9393:     MatMatMatMult(R,A,Rt,scall,fill,C);
9394:     MatDestroy(&Rt);
9395:   }
9396:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
9397:   (*A->ops->rart)(A,R,scall,fill,C);
9398:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
9399:   return(0);
9400: }

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

9405:    Neighbor-wise Collective on Mat

9407:    Input Parameters:
9408: +  A - the matrix
9409: -  R - the projection matrix

9411:    Output Parameters:
9412: .  C - the product matrix

9414:    Notes:
9415:    C must have been created by calling MatRARtSymbolic and must be destroyed by
9416:    the user using MatDestroy().

9418:    This routine is currently only implemented for pairs of AIJ matrices and classes
9419:    which inherit from AIJ.  C will be of