Actual source code: matrix.c

petsc-3.8.4 2018-03-24
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:   PetscMPIInt       size;
946: #if defined(PETSC_HAVE_SAWS)
947:   PetscBool         issaws;
948: #endif

953:   if (!viewer) {
954:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
955:   }
958:   MatCheckPreallocated(mat,1);
959:   PetscViewerGetFormat(viewer,&format);
960:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
961:   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) return(0);
962:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
963:   if (ibinary) {
964:     PetscBool mpiio;
965:     PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
966:     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
967:   }

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

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

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

1036: #if defined(PETSC_USE_DEBUG)
1037: #include <../src/sys/totalview/tv_data_display.h>
1038: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1039: {
1040:   TV_add_row("Local rows", "int", &mat->rmap->n);
1041:   TV_add_row("Local columns", "int", &mat->cmap->n);
1042:   TV_add_row("Global rows", "int", &mat->rmap->N);
1043:   TV_add_row("Global columns", "int", &mat->cmap->N);
1044:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1045:   return TV_format_OK;
1046: }
1047: #endif

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

1055:    Collective on PetscViewer

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

1062:    Options Database Keys:
1063:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1064:    block size
1065: .    -matload_block_size <bs>

1067:    Level: beginner

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

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

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

1082:    In parallel, each processor can load a subset of rows (or the
1083:    entire matrix).  This routine is especially useful when a large
1084:    matrix is stored on disk and only part of it is desired on each
1085:    processor.  For example, a parallel solver may access only some of
1086:    the rows from each processor.  The algorithm used here reads
1087:    relatively small blocks of data rather than reading the entire
1088:    matrix and then subsetting it.

1090:    Notes for advanced users:
1091:    Most users should not need to know the details of the binary storage
1092:    format, since MatLoad() and MatView() completely hide these details.
1093:    But for anyone who's interested, the standard binary matrix storage
1094:    format is

1096: $    int    MAT_FILE_CLASSID
1097: $    int    number of rows
1098: $    int    number of columns
1099: $    int    total number of nonzeros
1100: $    int    *number nonzeros in each row
1101: $    int    *column indices of all nonzeros (starting index is zero)
1102: $    PetscScalar *values of all nonzeros

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

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

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

1114:  @*/
1115: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1116: {
1118:   PetscBool      isbinary,flg;

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

1126:   if (!((PetscObject)newmat)->type_name) {
1127:     MatSetType(newmat,MATAIJ);
1128:   }

1130:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1131:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1132:   (*newmat->ops->load)(newmat,viewer);
1133:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

1135:   flg  = PETSC_FALSE;
1136:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1137:   if (flg) {
1138:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1139:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1140:   }
1141:   flg  = PETSC_FALSE;
1142:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1143:   if (flg) {
1144:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1145:   }
1146:   return(0);
1147: }

1149: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1150: {
1152:   Mat_Redundant  *redund = *redundant;
1153:   PetscInt       i;

1156:   if (redund){
1157:     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1158:       ISDestroy(&redund->isrow);
1159:       ISDestroy(&redund->iscol);
1160:       MatDestroySubMatrices(1,&redund->matseq);
1161:     } else {
1162:       PetscFree2(redund->send_rank,redund->recv_rank);
1163:       PetscFree(redund->sbuf_j);
1164:       PetscFree(redund->sbuf_a);
1165:       for (i=0; i<redund->nrecvs; i++) {
1166:         PetscFree(redund->rbuf_j[i]);
1167:         PetscFree(redund->rbuf_a[i]);
1168:       }
1169:       PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1170:     }

1172:     if (redund->subcomm) {
1173:       PetscCommDestroy(&redund->subcomm);
1174:     }
1175:     PetscFree(redund);
1176:   }
1177:   return(0);
1178: }

1180: /*@
1181:    MatDestroy - Frees space taken by a matrix.

1183:    Collective on Mat

1185:    Input Parameter:
1186: .  A - the matrix

1188:    Level: beginner

1190: @*/
1191: PetscErrorCode MatDestroy(Mat *A)
1192: {

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

1200:   /* if memory was published with SAWs then destroy it */
1201:   PetscObjectSAWsViewOff((PetscObject)*A);
1202:   if ((*A)->ops->destroy) {
1203:     (*(*A)->ops->destroy)(*A);
1204:   }

1206:   PetscFree((*A)->solvertype);
1207:   MatDestroy_Redundant(&(*A)->redundant);
1208:   MatNullSpaceDestroy(&(*A)->nullsp);
1209:   MatNullSpaceDestroy(&(*A)->transnullsp);
1210:   MatNullSpaceDestroy(&(*A)->nearnullsp);
1211:   MatDestroy(&(*A)->schur);
1212:   PetscLayoutDestroy(&(*A)->rmap);
1213:   PetscLayoutDestroy(&(*A)->cmap);
1214:   PetscHeaderDestroy(A);
1215:   return(0);
1216: }

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

1223:    Not Collective

1225:    Input Parameters:
1226: +  mat - the matrix
1227: .  v - a logically two-dimensional array of values
1228: .  m, idxm - the number of rows and their global indices
1229: .  n, idxn - the number of columns and their global indices
1230: -  addv - either ADD_VALUES or INSERT_VALUES, where
1231:    ADD_VALUES adds values to any existing entries, and
1232:    INSERT_VALUES replaces existing entries with new values

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

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

1240:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1241:    options cannot be mixed without intervening calls to the assembly
1242:    routines.

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

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

1252:    Efficiency Alert:
1253:    The routine MatSetValuesBlocked() may offer much better efficiency
1254:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1256:    Level: beginner

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

1261:    Concepts: matrices^putting entries in

1263: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1264:           InsertMode, INSERT_VALUES, ADD_VALUES
1265: @*/
1266: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1267: {
1269: #if defined(PETSC_USE_DEBUG)
1270:   PetscInt       i,j;
1271: #endif

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

1289:   for (i=0; i<m; i++) {
1290:     for (j=0; j<n; j++) {
1291:       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1292: #if defined(PETSC_USE_COMPLEX)
1293:         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]);
1294: #else
1295:         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1296: #endif
1297:     }
1298:   }
1299: #endif

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


1325: /*@
1326:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1327:         values into a matrix

1329:    Not Collective

1331:    Input Parameters:
1332: +  mat - the matrix
1333: .  row - the (block) row to set
1334: -  v - a logically two-dimensional array of values

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

1339:    All the nonzeros in the row must be provided

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

1343:    The row must belong to this process

1345:    Level: intermediate

1347:    Concepts: matrices^putting entries in

1349: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1350:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1351: @*/
1352: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1353: {
1355:   PetscInt       globalrow;

1361:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1362:   MatSetValuesRow(mat,globalrow,v);
1363: #if defined(PETSC_HAVE_CUSP)
1364:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1365:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1366:   }
1367: #elif defined(PETSC_HAVE_VIENNACL)
1368:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1369:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1370:   }
1371: #elif defined(PETSC_HAVE_VECCUDA)
1372:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1373:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1374:   }
1375: #endif
1376:   return(0);
1377: }

1379: /*@
1380:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1381:         values into a matrix

1383:    Not Collective

1385:    Input Parameters:
1386: +  mat - the matrix
1387: .  row - the (block) row to set
1388: -  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

1390:    Notes:
1391:    The values, v, are column-oriented for the block version.

1393:    All the nonzeros in the row must be provided

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

1397:    The row must belong to this process

1399:    Level: advanced

1401:    Concepts: matrices^putting entries in

1403: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1404:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1405: @*/
1406: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1407: {

1413:   MatCheckPreallocated(mat,1);
1415: #if defined(PETSC_USE_DEBUG)
1416:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1417:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1418: #endif
1419:   mat->insertmode = INSERT_VALUES;

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

1445: /*@
1446:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1447:      Using structured grid indexing

1449:    Not Collective

1451:    Input Parameters:
1452: +  mat - the matrix
1453: .  m - number of rows being entered
1454: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1455: .  n - number of columns being entered
1456: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1457: .  v - a logically two-dimensional array of values
1458: -  addv - either ADD_VALUES or INSERT_VALUES, where
1459:    ADD_VALUES adds values to any existing entries, and
1460:    INSERT_VALUES replaces existing entries with new values

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

1465:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1466:    options cannot be mixed without intervening calls to the assembly
1467:    routines.

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

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

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

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

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

1485:    In Fortran idxm and idxn should be declared as
1486: $     MatStencil idxm(4,m),idxn(4,n)
1487:    and the values inserted using
1488: $    idxm(MatStencil_i,1) = i
1489: $    idxm(MatStencil_j,1) = j
1490: $    idxm(MatStencil_k,1) = k
1491: $    idxm(MatStencil_c,1) = c
1492:    etc

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

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

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

1505:    Efficiency Alert:
1506:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1507:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1509:    Level: beginner

1511:    Concepts: matrices^putting entries in

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

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

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

1562: /*@
1563:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1564:      Using structured grid indexing

1566:    Not Collective

1568:    Input Parameters:
1569: +  mat - the matrix
1570: .  m - number of rows being entered
1571: .  idxm - grid coordinates for matrix rows being entered
1572: .  n - number of columns being entered
1573: .  idxn - grid coordinates for matrix columns being entered
1574: .  v - a logically two-dimensional array of values
1575: -  addv - either ADD_VALUES or INSERT_VALUES, where
1576:    ADD_VALUES adds values to any existing entries, and
1577:    INSERT_VALUES replaces existing entries with new values

1579:    Notes:
1580:    By default the values, v, are row-oriented and unsorted.
1581:    See MatSetOption() for other options.

1583:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1584:    options cannot be mixed without intervening calls to the assembly
1585:    routines.

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

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

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

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

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

1603:    In Fortran idxm and idxn should be declared as
1604: $     MatStencil idxm(4,m),idxn(4,n)
1605:    and the values inserted using
1606: $    idxm(MatStencil_i,1) = i
1607: $    idxm(MatStencil_j,1) = j
1608: $    idxm(MatStencil_k,1) = k
1609:    etc

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

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

1619:    Level: beginner

1621:    Concepts: matrices^putting entries in

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

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

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

1686: /*@
1687:    MatSetStencil - Sets the grid information for setting values into a matrix via
1688:         MatSetValuesStencil()

1690:    Not Collective

1692:    Input Parameters:
1693: +  mat - the matrix
1694: .  dim - dimension of the grid 1, 2, or 3
1695: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1696: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1697: -  dof - number of degrees of freedom per node


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

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

1706:    Level: beginner

1708:    Concepts: matrices^putting entries in

1710: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1711:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1712: @*/
1713: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1714: {
1715:   PetscInt i;


1722:   mat->stencil.dim = dim + (dof > 1);
1723:   for (i=0; i<dim; i++) {
1724:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1725:     mat->stencil.starts[i] = starts[dim-i-1];
1726:   }
1727:   mat->stencil.dims[dim]   = dof;
1728:   mat->stencil.starts[dim] = 0;
1729:   mat->stencil.noc         = (PetscBool)(dof == 1);
1730:   return(0);
1731: }

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

1736:    Not Collective

1738:    Input Parameters:
1739: +  mat - the matrix
1740: .  v - a logically two-dimensional array of values
1741: .  m, idxm - the number of block rows and their global block indices
1742: .  n, idxn - the number of block columns and their global block indices
1743: -  addv - either ADD_VALUES or INSERT_VALUES, where
1744:    ADD_VALUES adds values to any existing entries, and
1745:    INSERT_VALUES replaces existing entries with new values

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

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

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

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

1763:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1764:    options cannot be mixed without intervening calls to the assembly
1765:    routines.

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

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

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

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

1796:    Level: intermediate

1798:    Concepts: matrices^putting entries in blocked

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

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

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

1870: /*@
1871:    MatGetValues - Gets a block of values from a matrix.

1873:    Not Collective; currently only returns a local block

1875:    Input Parameters:
1876: +  mat - the matrix
1877: .  v - a logically two-dimensional array for storing the values
1878: .  m, idxm - the number of rows and their global indices
1879: -  n, idxn - the number of columns and their global indices

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

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

1889:    MatGetValues() requires that the matrix has been assembled
1890:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1891:    MatSetValues() and MatGetValues() CANNOT be made in succession
1892:    without intermediate matrix assembly.

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

1897:    Level: advanced

1899:    Concepts: matrices^accessing values

1901: .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1902: @*/
1903: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1904: {

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

1919:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1920:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1921:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1922:   return(0);
1923: }

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

1929:   Not Collective

1931:   Input Parameters:
1932: + mat - the matrix
1933: . nb - the number of blocks
1934: . bs - the number of rows (and columns) in each block
1935: . rows - a concatenation of the rows for each block
1936: - v - a concatenation of logically two-dimensional arrays of values

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

1941:   Level: advanced

1943:   Concepts: matrices^putting entries in

1945: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1946:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1947: @*/
1948: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1949: {

1957: #if defined(PETSC_USE_DEBUG)
1958:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1959: #endif

1961:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1962:   if (mat->ops->setvaluesbatch) {
1963:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1964:   } else {
1965:     PetscInt b;
1966:     for (b = 0; b < nb; ++b) {
1967:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1968:     }
1969:   }
1970:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1971:   return(0);
1972: }

1974: /*@
1975:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1976:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1977:    using a local (per-processor) numbering.

1979:    Not Collective

1981:    Input Parameters:
1982: +  x - the matrix
1983: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1984: - cmapping - column mapping

1986:    Level: intermediate

1988:    Concepts: matrices^local to global mapping
1989:    Concepts: local to global mapping^for matrices

1991: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1992: @*/
1993: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1994: {


2003:   if (x->ops->setlocaltoglobalmapping) {
2004:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
2005:   } else {
2006:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
2007:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
2008:   }
2009:   return(0);
2010: }


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

2016:    Not Collective

2018:    Input Parameters:
2019: .  A - the matrix

2021:    Output Parameters:
2022: + rmapping - row mapping
2023: - cmapping - column mapping

2025:    Level: advanced

2027:    Concepts: matrices^local to global mapping
2028:    Concepts: local to global mapping^for matrices

2030: .seealso:  MatSetValuesLocal()
2031: @*/
2032: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2033: {
2039:   if (rmapping) *rmapping = A->rmap->mapping;
2040:   if (cmapping) *cmapping = A->cmap->mapping;
2041:   return(0);
2042: }

2044: /*@
2045:    MatGetLayouts - Gets the PetscLayout objects for rows and columns

2047:    Not Collective

2049:    Input Parameters:
2050: .  A - the matrix

2052:    Output Parameters:
2053: + rmap - row layout
2054: - cmap - column layout

2056:    Level: advanced

2058: .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2059: @*/
2060: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2061: {
2067:   if (rmap) *rmap = A->rmap;
2068:   if (cmap) *cmap = A->cmap;
2069:   return(0);
2070: }

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

2076:    Not Collective

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

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

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

2093:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2094:    options cannot be mixed without intervening calls to the assembly
2095:    routines.

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

2100:    Level: intermediate

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

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

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

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

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

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

2172:    Not Collective

2174:    Input Parameters:
2175: +  x - the matrix
2176: .  nrow, irow - number of rows and their local indices
2177: .  ncol, icol - number of columns and their local indices
2178: .  y -  a logically two-dimensional array of values
2179: -  addv - either INSERT_VALUES or ADD_VALUES, where
2180:    ADD_VALUES adds values to any existing entries, and
2181:    INSERT_VALUES replaces existing entries with new values

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

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

2190:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2191:    options cannot be mixed without intervening calls to the assembly
2192:    routines.

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

2197:    Level: intermediate

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

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

2204: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2205:            MatSetValuesLocal(),  MatSetValuesBlocked()
2206: @*/
2207: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2208: {

2214:   MatCheckPreallocated(mat,1);
2215:   if (!nrow || !ncol) return(0); /* no values to insert */
2219:   if (mat->insertmode == NOT_SET_VALUES) {
2220:     mat->insertmode = addv;
2221:   }
2222: #if defined(PETSC_USE_DEBUG)
2223:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2224:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2225:   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);
2226: #endif

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

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

2268:    Collective on Mat and Vec

2270:    Input Parameters:
2271: +  mat - the matrix
2272: -  x   - the vector to be multiplied

2274:    Output Parameters:
2275: .  y - the result

2277:    Notes:
2278:    The vectors x and y cannot be the same.  I.e., one cannot
2279:    call MatMult(A,y,y).

2281:    Level: developer

2283:    Concepts: matrix-vector product

2285: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2286: @*/
2287: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2288: {


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

2302:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2303:   (*mat->ops->multdiagonalblock)(mat,x,y);
2304:   PetscObjectStateIncrease((PetscObject)y);
2305:   return(0);
2306: }

2308: /* --------------------------------------------------------*/
2309: /*@
2310:    MatMult - Computes the matrix-vector product, y = Ax.

2312:    Neighbor-wise Collective on Mat and Vec

2314:    Input Parameters:
2315: +  mat - the matrix
2316: -  x   - the vector to be multiplied

2318:    Output Parameters:
2319: .  y - the result

2321:    Notes:
2322:    The vectors x and y cannot be the same.  I.e., one cannot
2323:    call MatMult(A,y,y).

2325:    Level: beginner

2327:    Concepts: matrix-vector product

2329: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2330: @*/
2331: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2332: {

2340:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2341:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2342:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2343: #if !defined(PETSC_HAVE_CONSTRAINTS)
2344:   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);
2345:   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);
2346:   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);
2347: #endif
2348:   VecLocked(y,3);
2349:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2350:   MatCheckPreallocated(mat,1);

2352:   VecLockPush(x);
2353:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2354:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2355:   (*mat->ops->mult)(mat,x,y);
2356:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2357:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2358:   VecLockPop(x);
2359:   return(0);
2360: }

2362: /*@
2363:    MatMultTranspose - Computes matrix transpose times a vector.

2365:    Neighbor-wise Collective on Mat and Vec

2367:    Input Parameters:
2368: +  mat - the matrix
2369: -  x   - the vector to be multilplied

2371:    Output Parameters:
2372: .  y - the result

2374:    Notes:
2375:    The vectors x and y cannot be the same.  I.e., one cannot
2376:    call MatMultTranspose(A,y,y).

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

2381:    Level: beginner

2383:    Concepts: matrix vector product^transpose

2385: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2386: @*/
2387: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2388: {


2397:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2398:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2399:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2400: #if !defined(PETSC_HAVE_CONSTRAINTS)
2401:   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);
2402:   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);
2403: #endif
2404:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2405:   MatCheckPreallocated(mat,1);

2407:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2408:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2409:   VecLockPush(x);
2410:   (*mat->ops->multtranspose)(mat,x,y);
2411:   VecLockPop(x);
2412:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2413:   PetscObjectStateIncrease((PetscObject)y);
2414:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2415:   return(0);
2416: }

2418: /*@
2419:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2421:    Neighbor-wise Collective on Mat and Vec

2423:    Input Parameters:
2424: +  mat - the matrix
2425: -  x   - the vector to be multilplied

2427:    Output Parameters:
2428: .  y - the result

2430:    Notes:
2431:    The vectors x and y cannot be the same.  I.e., one cannot
2432:    call MatMultHermitianTranspose(A,y,y).

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

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

2438:    Level: beginner

2440:    Concepts: matrix vector product^transpose

2442: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2443: @*/
2444: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2445: {
2447:   Vec            w;


2455:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2456:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2457:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2458: #if !defined(PETSC_HAVE_CONSTRAINTS)
2459:   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);
2460:   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);
2461: #endif
2462:   MatCheckPreallocated(mat,1);

2464:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2465:   if (mat->ops->multhermitiantranspose) {
2466:     VecLockPush(x);
2467:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2468:     VecLockPop(x);
2469:   } else {
2470:     VecDuplicate(x,&w);
2471:     VecCopy(x,w);
2472:     VecConjugate(w);
2473:     MatMultTranspose(mat,w,y);
2474:     VecDestroy(&w);
2475:     VecConjugate(y);
2476:   }
2477:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2478:   PetscObjectStateIncrease((PetscObject)y);
2479:   return(0);
2480: }

2482: /*@
2483:     MatMultAdd -  Computes v3 = v2 + A * v1.

2485:     Neighbor-wise Collective on Mat and Vec

2487:     Input Parameters:
2488: +   mat - the matrix
2489: -   v1, v2 - the vectors

2491:     Output Parameters:
2492: .   v3 - the result

2494:     Notes:
2495:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2496:     call MatMultAdd(A,v1,v2,v1).

2498:     Level: beginner

2500:     Concepts: matrix vector product^addition

2502: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2503: @*/
2504: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2505: {


2515:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2516:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2517:   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);
2518:   /* 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);
2519:      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); */
2520:   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);
2521:   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);
2522:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2523:   MatCheckPreallocated(mat,1);

2525:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2526:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2527:   VecLockPush(v1);
2528:   (*mat->ops->multadd)(mat,v1,v2,v3);
2529:   VecLockPop(v1);
2530:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2531:   PetscObjectStateIncrease((PetscObject)v3);
2532:   return(0);
2533: }

2535: /*@
2536:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2538:    Neighbor-wise Collective on Mat and Vec

2540:    Input Parameters:
2541: +  mat - the matrix
2542: -  v1, v2 - the vectors

2544:    Output Parameters:
2545: .  v3 - the result

2547:    Notes:
2548:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2549:    call MatMultTransposeAdd(A,v1,v2,v1).

2551:    Level: beginner

2553:    Concepts: matrix vector product^transpose and addition

2555: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2556: @*/
2557: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2558: {


2568:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2569:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2570:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2571:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2572:   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);
2573:   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);
2574:   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);
2575:   MatCheckPreallocated(mat,1);

2577:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2578:   VecLockPush(v1);
2579:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2580:   VecLockPop(v1);
2581:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2582:   PetscObjectStateIncrease((PetscObject)v3);
2583:   return(0);
2584: }

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

2589:    Neighbor-wise Collective on Mat and Vec

2591:    Input Parameters:
2592: +  mat - the matrix
2593: -  v1, v2 - the vectors

2595:    Output Parameters:
2596: .  v3 - the result

2598:    Notes:
2599:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2600:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2602:    Level: beginner

2604:    Concepts: matrix vector product^transpose and addition

2606: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2607: @*/
2608: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2609: {


2619:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2620:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2621:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2622:   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);
2623:   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);
2624:   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);
2625:   MatCheckPreallocated(mat,1);

2627:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2628:   VecLockPush(v1);
2629:   if (mat->ops->multhermitiantransposeadd) {
2630:     (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2631:    } else {
2632:     Vec w,z;
2633:     VecDuplicate(v1,&w);
2634:     VecCopy(v1,w);
2635:     VecConjugate(w);
2636:     VecDuplicate(v3,&z);
2637:     MatMultTranspose(mat,w,z);
2638:     VecDestroy(&w);
2639:     VecConjugate(z);
2640:     VecWAXPY(v3,1.0,v2,z);
2641:     VecDestroy(&z);
2642:   }
2643:   VecLockPop(v1);
2644:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2645:   PetscObjectStateIncrease((PetscObject)v3);
2646:   return(0);
2647: }

2649: /*@
2650:    MatMultConstrained - The inner multiplication routine for a
2651:    constrained matrix P^T A P.

2653:    Neighbor-wise Collective on Mat and Vec

2655:    Input Parameters:
2656: +  mat - the matrix
2657: -  x   - the vector to be multilplied

2659:    Output Parameters:
2660: .  y - the result

2662:    Notes:
2663:    The vectors x and y cannot be the same.  I.e., one cannot
2664:    call MatMult(A,y,y).

2666:    Level: beginner

2668: .keywords: matrix, multiply, matrix-vector product, constraint
2669: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2670: @*/
2671: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2672: {

2679:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2680:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2681:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2682:   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);
2683:   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);
2684:   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);

2686:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2687:   VecLockPush(x);
2688:   (*mat->ops->multconstrained)(mat,x,y);
2689:   VecLockPop(x);
2690:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2691:   PetscObjectStateIncrease((PetscObject)y);
2692:   return(0);
2693: }

2695: /*@
2696:    MatMultTransposeConstrained - The inner multiplication routine for a
2697:    constrained matrix P^T A^T P.

2699:    Neighbor-wise Collective on Mat and Vec

2701:    Input Parameters:
2702: +  mat - the matrix
2703: -  x   - the vector to be multilplied

2705:    Output Parameters:
2706: .  y - the result

2708:    Notes:
2709:    The vectors x and y cannot be the same.  I.e., one cannot
2710:    call MatMult(A,y,y).

2712:    Level: beginner

2714: .keywords: matrix, multiply, matrix-vector product, constraint
2715: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2716: @*/
2717: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2718: {

2725:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2726:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2727:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2728:   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);
2729:   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);

2731:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2732:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2733:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2734:   PetscObjectStateIncrease((PetscObject)y);
2735:   return(0);
2736: }

2738: /*@C
2739:    MatGetFactorType - gets the type of factorization it is

2741:    Note Collective
2742:    as the flag

2744:    Input Parameters:
2745: .  mat - the matrix

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

2750:     Level: intermediate

2752: .seealso:    MatFactorType, MatGetFactor()
2753: @*/
2754: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2755: {
2759:   *t = mat->factortype;
2760:   return(0);
2761: }

2763: /* ------------------------------------------------------------*/
2764: /*@C
2765:    MatGetInfo - Returns information about matrix storage (number of
2766:    nonzeros, memory, etc.).

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

2770:    Input Parameters:
2771: .  mat - the matrix

2773:    Output Parameters:
2774: +  flag - flag indicating the type of parameters to be returned
2775:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2776:    MAT_GLOBAL_SUM - sum over all processors)
2777: -  info - matrix information context

2779:    Notes:
2780:    The MatInfo context contains a variety of matrix data, including
2781:    number of nonzeros allocated and used, number of mallocs during
2782:    matrix assembly, etc.  Additional information for factored matrices
2783:    is provided (such as the fill ratio, number of mallocs during
2784:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2785:    when using the runtime options
2786: $       -info -mat_view ::ascii_info

2788:    Example for C/C++ Users:
2789:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2790:    data within the MatInfo context.  For example,
2791: .vb
2792:       MatInfo info;
2793:       Mat     A;
2794:       double  mal, nz_a, nz_u;

2796:       MatGetInfo(A,MAT_LOCAL,&info);
2797:       mal  = info.mallocs;
2798:       nz_a = info.nz_allocated;
2799: .ve

2801:    Example for Fortran Users:
2802:    Fortran users should declare info as a double precision
2803:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2804:    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2805:    a complete list of parameter names.
2806: .vb
2807:       double  precision info(MAT_INFO_SIZE)
2808:       double  precision mal, nz_a
2809:       Mat     A
2810:       integer ierr

2812:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2813:       mal = info(MAT_INFO_MALLOCS)
2814:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2815: .ve

2817:     Level: intermediate

2819:     Concepts: matrices^getting information on

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

2824: .seealso: MatStashGetInfo()

2826: @*/
2827: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2828: {

2835:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2836:   MatCheckPreallocated(mat,1);
2837:   (*mat->ops->getinfo)(mat,flag,info);
2838:   return(0);
2839: }

2841: /*
2842:    This is used by external packages where it is not easy to get the info from the actual
2843:    matrix factorization.
2844: */
2845: PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2846: {

2850:   PetscMemzero(info,sizeof(MatInfo));
2851:   return(0);
2852: }

2854: /* ----------------------------------------------------------*/

2856: /*@C
2857:    MatLUFactor - Performs in-place LU factorization of matrix.

2859:    Collective on Mat

2861:    Input Parameters:
2862: +  mat - the matrix
2863: .  row - row permutation
2864: .  col - column permutation
2865: -  info - options for factorization, includes
2866: $          fill - expected fill as ratio of original fill.
2867: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2868: $                   Run with the option -info to determine an optimal value to use

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

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

2878:    Level: developer

2880:    Concepts: matrices^LU factorization

2882: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2883:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2888: @*/
2889: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2890: {
2892:   MatFactorInfo  tinfo;

2900:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2901:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2902:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2903:   MatCheckPreallocated(mat,1);
2904:   if (!info) {
2905:     MatFactorInfoInitialize(&tinfo);
2906:     info = &tinfo;
2907:   }

2909:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2910:   (*mat->ops->lufactor)(mat,row,col,info);
2911:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2912:   PetscObjectStateIncrease((PetscObject)mat);
2913:   return(0);
2914: }

2916: /*@C
2917:    MatILUFactor - Performs in-place ILU factorization of matrix.

2919:    Collective on Mat

2921:    Input Parameters:
2922: +  mat - the matrix
2923: .  row - row permutation
2924: .  col - column permutation
2925: -  info - structure containing
2926: $      levels - number of levels of fill.
2927: $      expected fill - as ratio of original fill.
2928: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2929:                 missing diagonal entries)

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

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

2939:    Level: developer

2941:    Concepts: matrices^ILU factorization

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

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

2948: @*/
2949: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2950: {

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

2965:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2966:   (*mat->ops->ilufactor)(mat,row,col,info);
2967:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2968:   PetscObjectStateIncrease((PetscObject)mat);
2969:   return(0);
2970: }

2972: /*@C
2973:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2974:    Call this routine before calling MatLUFactorNumeric().

2976:    Collective on Mat

2978:    Input Parameters:
2979: +  fact - the factor matrix obtained with MatGetFactor()
2980: .  mat - the matrix
2981: .  row, col - row and column permutations
2982: -  info - options for factorization, includes
2983: $          fill - expected fill as ratio of original fill.
2984: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2985: $                   Run with the option -info to determine an optimal value to use


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

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

2994:    Level: developer

2996:    Concepts: matrices^LU symbolic factorization

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

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

3003: @*/
3004: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3005: {

3015:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3016:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3017:   if (!(fact)->ops->lufactorsymbolic) {
3018:     const MatSolverPackage spackage;
3019:     MatFactorGetSolverPackage(fact,&spackage);
3020:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3021:   }
3022:   MatCheckPreallocated(mat,2);

3024:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
3025:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
3026:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
3027:   PetscObjectStateIncrease((PetscObject)fact);
3028:   return(0);
3029: }

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

3035:    Collective on Mat

3037:    Input Parameters:
3038: +  fact - the factor matrix obtained with MatGetFactor()
3039: .  mat - the matrix
3040: -  info - options for factorization

3042:    Notes:
3043:    See MatLUFactor() for in-place factorization.  See
3044:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

3050:    Level: developer

3052:    Concepts: matrices^LU numeric factorization

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

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

3059: @*/
3060: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3061: {

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

3072:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3073:   MatCheckPreallocated(mat,2);
3074:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
3075:   (fact->ops->lufactornumeric)(fact,mat,info);
3076:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
3077:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3078:   PetscObjectStateIncrease((PetscObject)fact);
3079:   return(0);
3080: }

3082: /*@C
3083:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3084:    symmetric matrix.

3086:    Collective on Mat

3088:    Input Parameters:
3089: +  mat - the matrix
3090: .  perm - row and column permutations
3091: -  f - expected fill as ratio of original fill

3093:    Notes:
3094:    See MatLUFactor() for the nonsymmetric case.  See also
3095:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

3101:    Level: developer

3103:    Concepts: matrices^Cholesky factorization

3105: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3106:           MatGetOrdering()

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

3111: @*/
3112: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3113: {

3121:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3122:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3123:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3124:   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);
3125:   MatCheckPreallocated(mat,1);

3127:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3128:   (*mat->ops->choleskyfactor)(mat,perm,info);
3129:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3130:   PetscObjectStateIncrease((PetscObject)mat);
3131:   return(0);
3132: }

3134: /*@C
3135:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3136:    of a symmetric matrix.

3138:    Collective on Mat

3140:    Input Parameters:
3141: +  fact - the factor matrix obtained with MatGetFactor()
3142: .  mat - the matrix
3143: .  perm - row and column permutations
3144: -  info - options for factorization, includes
3145: $          fill - expected fill as ratio of original fill.
3146: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3147: $                   Run with the option -info to determine an optimal value to use

3149:    Notes:
3150:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3151:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

3157:    Level: developer

3159:    Concepts: matrices^Cholesky symbolic factorization

3161: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3162:           MatGetOrdering()

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

3167: @*/
3168: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3169: {

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

3188:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3189:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3190:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3191:   PetscObjectStateIncrease((PetscObject)fact);
3192:   return(0);
3193: }

3195: /*@C
3196:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3197:    of a symmetric matrix. Call this routine after first calling
3198:    MatCholeskyFactorSymbolic().

3200:    Collective on Mat

3202:    Input Parameters:
3203: +  fact - the factor matrix obtained with MatGetFactor()
3204: .  mat - the initial matrix
3205: .  info - options for factorization
3206: -  fact - the symbolic factor of mat


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

3214:    Level: developer

3216:    Concepts: matrices^Cholesky numeric factorization

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

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

3223: @*/
3224: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3225: {

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

3238:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3239:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3240:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3241:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3242:   PetscObjectStateIncrease((PetscObject)fact);
3243:   return(0);
3244: }

3246: /* ----------------------------------------------------------------*/
3247: /*@
3248:    MatSolve - Solves A x = b, given a factored matrix.

3250:    Neighbor-wise Collective on Mat and Vec

3252:    Input Parameters:
3253: +  mat - the factored matrix
3254: -  b - the right-hand-side vector

3256:    Output Parameter:
3257: .  x - the result vector

3259:    Notes:
3260:    The vectors b and x cannot be the same.  I.e., one cannot
3261:    call MatSolve(A,x,x).

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

3268:    Level: developer

3270:    Concepts: matrices^triangular solves

3272: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3273: @*/
3274: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3275: {

3285:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3286:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3287:   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);
3288:   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);
3289:   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);
3290:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3291:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3292:   MatCheckPreallocated(mat,1);

3294:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3295:   if (mat->factorerrortype) {
3296:     PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3297:     VecSetInf(x);
3298:   } else {
3299:     (*mat->ops->solve)(mat,b,x);
3300:   }
3301:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3302:   PetscObjectStateIncrease((PetscObject)x);
3303:   return(0);
3304: }

3306: static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3307: {
3309:   Vec            b,x;
3310:   PetscInt       m,N,i;
3311:   PetscScalar    *bb,*xx;
3312:   PetscBool      flg;

3315:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3316:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3317:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3318:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

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

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

3346:    Neighbor-wise Collective on Mat

3348:    Input Parameters:
3349: +  A - the factored matrix
3350: -  B - the right-hand-side matrix  (dense matrix)

3352:    Output Parameter:
3353: .  X - the result matrix (dense matrix)

3355:    Notes:
3356:    The matrices b and x cannot be the same.  I.e., one cannot
3357:    call MatMatSolve(A,x,x).

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

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

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

3370:    Level: developer

3372:    Concepts: matrices^triangular solves

3374: .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3375: @*/
3376: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3377: {

3387:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3388:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3389:   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);
3390:   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);
3391:   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);
3392:   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");
3393:   if (!A->rmap->N && !A->cmap->N) return(0);
3394:   MatCheckPreallocated(A,1);

3396:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3397:   if (!A->ops->matsolve) {
3398:     PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3399:     MatMatSolve_Basic(A,B,X,PETSC_FALSE);
3400:   } else {
3401:     (*A->ops->matsolve)(A,B,X);
3402:   }
3403:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3404:   PetscObjectStateIncrease((PetscObject)X);
3405:   return(0);
3406: }

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

3411:    Neighbor-wise Collective on Mat

3413:    Input Parameters:
3414: +  A - the factored matrix
3415: -  B - the right-hand-side matrix  (dense matrix)

3417:    Output Parameter:
3418: .  X - the result matrix (dense matrix)

3420:    Notes:
3421:    The matrices b and x cannot be the same.  I.e., one cannot
3422:    call MatMatSolveTranspose(A,x,x).

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

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

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

3435:    Level: developer

3437:    Concepts: matrices^triangular solves

3439: .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3440: @*/
3441: PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3442: {

3452:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3453:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3454:   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);
3455:   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);
3456:   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);
3457:   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");
3458:   if (!A->rmap->N && !A->cmap->N) return(0);
3459:   MatCheckPreallocated(A,1);

3461:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3462:   if (!A->ops->matsolvetranspose) {
3463:     PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);
3464:     MatMatSolve_Basic(A,B,X,PETSC_TRUE);
3465:   } else {
3466:     (*A->ops->matsolvetranspose)(A,B,X);
3467:   }
3468:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3469:   PetscObjectStateIncrease((PetscObject)X);
3470:   return(0);
3471: }

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

3477:    Neighbor-wise Collective on Mat and Vec

3479:    Input Parameters:
3480: +  mat - the factored matrix
3481: -  b - the right-hand-side vector

3483:    Output Parameter:
3484: .  x - the result vector

3486:    Notes:
3487:    MatSolve() should be used for most applications, as it performs
3488:    a forward solve followed by a backward solve.

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

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

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

3503:    Level: developer

3505:    Concepts: matrices^forward solves

3507: .seealso: MatSolve(), MatBackwardSolve()
3508: @*/
3509: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3510: {

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

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

3538:    Neighbor-wise Collective on Mat and Vec

3540:    Input Parameters:
3541: +  mat - the factored matrix
3542: -  b - the right-hand-side vector

3544:    Output Parameter:
3545: .  x - the result vector

3547:    Notes:
3548:    MatSolve() should be used for most applications, as it performs
3549:    a forward solve followed by a backward solve.

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

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

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

3564:    Level: developer

3566:    Concepts: matrices^backward solves

3568: .seealso: MatSolve(), MatForwardSolve()
3569: @*/
3570: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3571: {

3581:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3582:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3583:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3584:   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);
3585:   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);
3586:   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);
3587:   MatCheckPreallocated(mat,1);

3589:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3590:   (*mat->ops->backwardsolve)(mat,b,x);
3591:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3592:   PetscObjectStateIncrease((PetscObject)x);
3593:   return(0);
3594: }

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

3599:    Neighbor-wise Collective on Mat and Vec

3601:    Input Parameters:
3602: +  mat - the factored matrix
3603: .  b - the right-hand-side vector
3604: -  y - the vector to be added to

3606:    Output Parameter:
3607: .  x - the result vector

3609:    Notes:
3610:    The vectors b and x cannot be the same.  I.e., one cannot
3611:    call MatSolveAdd(A,x,y,x).

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

3617:    Level: developer

3619:    Concepts: matrices^triangular solves

3621: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3622: @*/
3623: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3624: {
3625:   PetscScalar    one = 1.0;
3626:   Vec            tmp;

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

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

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

3672:    Neighbor-wise Collective on Mat and Vec

3674:    Input Parameters:
3675: +  mat - the factored matrix
3676: -  b - the right-hand-side vector

3678:    Output Parameter:
3679: .  x - the result vector

3681:    Notes:
3682:    The vectors b and x cannot be the same.  I.e., one cannot
3683:    call MatSolveTranspose(A,x,x).

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

3689:    Level: developer

3691:    Concepts: matrices^triangular solves

3693: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3694: @*/
3695: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3696: {

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

3724: /*@
3725:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3726:                       factored matrix.

3728:    Neighbor-wise Collective on Mat and Vec

3730:    Input Parameters:
3731: +  mat - the factored matrix
3732: .  b - the right-hand-side vector
3733: -  y - the vector to be added to

3735:    Output Parameter:
3736: .  x - the result vector

3738:    Notes:
3739:    The vectors b and x cannot be the same.  I.e., one cannot
3740:    call MatSolveTransposeAdd(A,x,y,x).

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

3746:    Level: developer

3748:    Concepts: matrices^triangular solves

3750: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3751: @*/
3752: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3753: {
3754:   PetscScalar    one = 1.0;
3756:   Vec            tmp;

3767:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3768:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3769:   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);
3770:   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);
3771:   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);
3772:   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);
3773:   MatCheckPreallocated(mat,1);

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

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

3806:    Neighbor-wise Collective on Mat and Vec

3808:    Input Parameters:
3809: +  mat - the matrix
3810: .  b - the right hand side
3811: .  omega - the relaxation factor
3812: .  flag - flag indicating the type of SOR (see below)
3813: .  shift -  diagonal shift
3814: .  its - the number of iterations
3815: -  lits - the number of local iterations

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

3820:    SOR Flags:
3821: .     SOR_FORWARD_SWEEP - forward SOR
3822: .     SOR_BACKWARD_SWEEP - backward SOR
3823: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3824: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3825: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3826: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3827: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3828:          upper/lower triangular part of matrix to
3829:          vector (with omega)
3830: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3832:    Notes:
3833:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3834:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3835:    on each processor.

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

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

3842:    Notes for Advanced Users:
3843:    The flags are implemented as bitwise inclusive or operations.
3844:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3845:    to specify a zero initial guess for SSOR.

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

3851:    Vectors x and b CANNOT be the same

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

3855:    Level: developer

3857:    Concepts: matrices^relaxation
3858:    Concepts: matrices^SOR
3859:    Concepts: matrices^Gauss-Seidel

3861: @*/
3862: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3863: {

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

3883:   MatCheckPreallocated(mat,1);
3884:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3885:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3886:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3887:   PetscObjectStateIncrease((PetscObject)x);
3888:   return(0);
3889: }

3891: /*
3892:       Default matrix copy routine.
3893: */
3894: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3895: {
3896:   PetscErrorCode    ierr;
3897:   PetscInt          i,rstart = 0,rend = 0,nz;
3898:   const PetscInt    *cwork;
3899:   const PetscScalar *vwork;

3902:   if (B->assembled) {
3903:     MatZeroEntries(B);
3904:   }
3905:   MatGetOwnershipRange(A,&rstart,&rend);
3906:   for (i=rstart; i<rend; i++) {
3907:     MatGetRow(A,i,&nz,&cwork,&vwork);
3908:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3909:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3910:   }
3911:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3912:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3913:   return(0);
3914: }

3916: /*@
3917:    MatCopy - Copys a matrix to another matrix.

3919:    Collective on Mat

3921:    Input Parameters:
3922: +  A - the matrix
3923: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3925:    Output Parameter:
3926: .  B - where the copy is put

3928:    Notes:
3929:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3930:    same nonzero pattern or the routine will crash.

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

3936:    Level: intermediate

3938:    Concepts: matrices^copying

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

3942: @*/
3943: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3944: {
3946:   PetscInt       i;

3954:   MatCheckPreallocated(B,2);
3955:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3956:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3957:   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);
3958:   MatCheckPreallocated(A,1);
3959:   if (A == B) return(0);

3961:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3962:   if (A->ops->copy) {
3963:     (*A->ops->copy)(A,B,str);
3964:   } else { /* generic conversion */
3965:     MatCopy_Basic(A,B,str);
3966:   }

3968:   B->stencil.dim = A->stencil.dim;
3969:   B->stencil.noc = A->stencil.noc;
3970:   for (i=0; i<=A->stencil.dim; i++) {
3971:     B->stencil.dims[i]   = A->stencil.dims[i];
3972:     B->stencil.starts[i] = A->stencil.starts[i];
3973:   }

3975:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3976:   PetscObjectStateIncrease((PetscObject)B);
3977:   return(0);
3978: }

3980: /*@C
3981:    MatConvert - Converts a matrix to another matrix, either of the same
3982:    or different type.

3984:    Collective on Mat

3986:    Input Parameters:
3987: +  mat - the matrix
3988: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3989:    same type as the original matrix.
3990: -  reuse - denotes if the destination matrix is to be created or reused.
3991:    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
3992:    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).

3994:    Output Parameter:
3995: .  M - pointer to place new matrix

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

4002:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4003:    the MPI communicator of the generated matrix is always the same as the communicator
4004:    of the input matrix.

4006:    Level: intermediate

4008:    Concepts: matrices^converting between storage formats

4010: .seealso: MatCopy(), MatDuplicate()
4011: @*/
4012: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4013: {
4015:   PetscBool      sametype,issame,flg;
4016:   char           convname[256],mtype[256];
4017:   Mat            B;

4023:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4024:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4025:   MatCheckPreallocated(mat,1);
4026:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

4028:   PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
4029:   if (flg) {
4030:     newtype = mtype;
4031:   }
4032:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
4033:   PetscStrcmp(newtype,"same",&issame);
4034:   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4035:   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");

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

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

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

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

4085:     /* 3) See if a good general converter is registered for the desired class */
4086:     conv = B->ops->convertfrom;
4087:     MatDestroy(&B);
4088:     if (conv) goto foundconv;

4090:     /* 4) See if a good general converter is known for the current matrix */
4091:     if (mat->ops->convert) {
4092:       conv = mat->ops->convert;
4093:     }
4094:     if (conv) goto foundconv;

4096:     /* 5) Use a really basic converter. */
4097:     conv = MatConvert_Basic;

4099: foundconv:
4100:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4101:     (*conv)(mat,newtype,reuse,M);
4102:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4103:   }
4104:   PetscObjectStateIncrease((PetscObject)*M);

4106:   /* Copy Mat options */
4107:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
4108:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
4109:   return(0);
4110: }

4112: /*@C
4113:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

4115:    Not Collective

4117:    Input Parameter:
4118: .  mat - the matrix, must be a factored matrix

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

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

4127:    Level: intermediate

4129: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4130: @*/
4131: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4132: {
4133:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

4138:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4139:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
4140:   if (!conv) {
4141:     *type = MATSOLVERPETSC;
4142:   } else {
4143:     (*conv)(mat,type);
4144:   }
4145:   return(0);
4146: }

4148: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4149: struct _MatSolverPackageForSpecifcType {
4150:   MatType                        mtype;
4151:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4152:   MatSolverPackageForSpecifcType next;
4153: };

4155: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4156: struct _MatSolverPackageHolder {
4157:   char                           *name;
4158:   MatSolverPackageForSpecifcType handlers;
4159:   MatSolverPackageHolder         next;
4160: };

4162: static MatSolverPackageHolder MatSolverPackageHolders = NULL;

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

4167:    Input Parameters:
4168: +    package - name of the package, for example petsc or superlu
4169: .    mtype - the matrix type that works with this package
4170: .    ftype - the type of factorization supported by the package
4171: -    getfactor - routine that will create the factored matrix ready to be used

4173:     Level: intermediate

4175: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4176: @*/
4177: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4178: {
4179:   PetscErrorCode                 ierr;
4180:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4181:   PetscBool                      flg;
4182:   MatSolverPackageForSpecifcType inext,iprev = NULL;

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

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

4226:    Input Parameters:
4227: +    package - name of the package, for example petsc or superlu
4228: .    ftype - the type of factorization supported by the package
4229: -    mtype - the matrix type that works with this package

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

4236:     Level: intermediate

4238: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4239: @*/
4240: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4241: {
4242:   PetscErrorCode                 ierr;
4243:   MatSolverPackageHolder         next = MatSolverPackageHolders;
4244:   PetscBool                      flg;
4245:   MatSolverPackageForSpecifcType inext;

4248:   if (foundpackage) *foundpackage = PETSC_FALSE;
4249:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4250:   if (getfactor)    *getfactor    = NULL;

4252:   if (package) {
4253:     while (next) {
4254:       PetscStrcasecmp(package,next->name,&flg);
4255:       if (flg) {
4256:         if (foundpackage) *foundpackage = PETSC_TRUE;
4257:         inext = next->handlers;
4258:         while (inext) {
4259:           PetscStrbeginswith(mtype,inext->mtype,&flg);
4260:           if (flg) {
4261:             if (foundmtype) *foundmtype = PETSC_TRUE;
4262:             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4263:             return(0);
4264:           }
4265:           inext = inext->next;
4266:         }
4267:       }
4268:       next = next->next;
4269:     }
4270:   } else {
4271:     while (next) {
4272:       inext = next->handlers;
4273:       while (inext) {
4274:         PetscStrbeginswith(mtype,inext->mtype,&flg);
4275:         if (flg && inext->getfactor[(int)ftype-1]) {
4276:           if (foundpackage) *foundpackage = PETSC_TRUE;
4277:           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4278:           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4279:           return(0);
4280:         }
4281:         inext = inext->next;
4282:       }
4283:       next = next->next;
4284:     }
4285:   }
4286:   return(0);
4287: }

4289: PetscErrorCode MatSolverPackageDestroy(void)
4290: {
4291:   PetscErrorCode                 ierr;
4292:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4293:   MatSolverPackageForSpecifcType inext,iprev;

4296:   while (next) {
4297:     PetscFree(next->name);
4298:     inext = next->handlers;
4299:     while (inext) {
4300:       PetscFree(inext->mtype);
4301:       iprev = inext;
4302:       inext = inext->next;
4303:       PetscFree(iprev);
4304:     }
4305:     prev = next;
4306:     next = next->next;
4307:     PetscFree(prev);
4308:   }
4309:   MatSolverPackageHolders = NULL;
4310:   return(0);
4311: }

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

4316:    Collective on Mat

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

4323:    Output Parameters:
4324: .  f - the factor matrix used with MatXXFactorSymbolic() calls

4326:    Notes:
4327:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4328:      such as pastix, superlu, mumps etc.

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

4332:    Level: intermediate

4334: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4335: @*/
4336: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4337: {
4338:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4339:   PetscBool      foundpackage,foundmtype;


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

4348:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4349:   if (!foundpackage) {
4350:     if (type) {
4351:       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4352:     } else {
4353:       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4354:     }
4355:   }

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

4360:   (*conv)(mat,ftype,f);
4361:   return(0);
4362: }

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

4367:    Not Collective

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

4374:    Output Parameter:
4375: .    flg - PETSC_TRUE if the factorization is available

4377:    Notes:
4378:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4379:      such as pastix, superlu, mumps etc.

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

4383:    Level: intermediate

4385: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4386: @*/
4387: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4388: {
4389:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);


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

4398:   *flg = PETSC_FALSE;
4399:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4400:   if (gconv) {
4401:     *flg = PETSC_TRUE;
4402:   }
4403:   return(0);
4404: }

4406:  #include <petscdmtypes.h>

4408: /*@
4409:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4411:    Collective on Mat

4413:    Input Parameters:
4414: +  mat - the matrix
4415: -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4416:         See the manual page for MatDuplicateOption for an explanation of these options.

4418:    Output Parameter:
4419: .  M - pointer to place new matrix

4421:    Level: intermediate

4423:    Concepts: matrices^duplicating

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

4427: .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4428: @*/
4429: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4430: {
4432:   Mat            B;
4433:   PetscInt       i;
4434:   DM             dm;

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

4444:   *M = 0;
4445:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4446:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4447:   (*mat->ops->duplicate)(mat,op,M);
4448:   B    = *M;

4450:   B->stencil.dim = mat->stencil.dim;
4451:   B->stencil.noc = mat->stencil.noc;
4452:   for (i=0; i<=mat->stencil.dim; i++) {
4453:     B->stencil.dims[i]   = mat->stencil.dims[i];
4454:     B->stencil.starts[i] = mat->stencil.starts[i];
4455:   }

4457:   B->nooffproczerorows = mat->nooffproczerorows;
4458:   B->nooffprocentries  = mat->nooffprocentries;

4460:   PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4461:   if (dm) {
4462:     PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4463:   }
4464:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4465:   PetscObjectStateIncrease((PetscObject)B);
4466:   return(0);
4467: }

4469: /*@
4470:    MatGetDiagonal - Gets the diagonal of a matrix.

4472:    Logically Collective on Mat and Vec

4474:    Input Parameters:
4475: +  mat - the matrix
4476: -  v - the vector for storing the diagonal

4478:    Output Parameter:
4479: .  v - the diagonal of the matrix

4481:    Level: intermediate

4483:    Note:
4484:    Currently only correct in parallel for square matrices.

4486:    Concepts: matrices^accessing diagonals

4488: .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4489: @*/
4490: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4491: {

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

4502:   (*mat->ops->getdiagonal)(mat,v);
4503:   PetscObjectStateIncrease((PetscObject)v);
4504:   return(0);
4505: }

4507: /*@C
4508:    MatGetRowMin - Gets the minimum value (of the real part) of each
4509:         row of the matrix

4511:    Logically Collective on Mat and Vec

4513:    Input Parameters:
4514: .  mat - the matrix

4516:    Output Parameter:
4517: +  v - the vector for storing the maximums
4518: -  idx - the indices of the column found for each row (optional)

4520:    Level: intermediate

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

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

4527:    Concepts: matrices^getting row maximums

4529: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4530:           MatGetRowMax()
4531: @*/
4532: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4533: {

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

4544:   (*mat->ops->getrowmin)(mat,v,idx);
4545:   PetscObjectStateIncrease((PetscObject)v);
4546:   return(0);
4547: }

4549: /*@C
4550:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4551:         row of the matrix

4553:    Logically Collective on Mat and Vec

4555:    Input Parameters:
4556: .  mat - the matrix

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

4562:    Level: intermediate

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

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

4569:    Concepts: matrices^getting row maximums

4571: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4572: @*/
4573: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4574: {

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

4586:   (*mat->ops->getrowminabs)(mat,v,idx);
4587:   PetscObjectStateIncrease((PetscObject)v);
4588:   return(0);
4589: }

4591: /*@C
4592:    MatGetRowMax - Gets the maximum value (of the real part) of each
4593:         row of the matrix

4595:    Logically Collective on Mat and Vec

4597:    Input Parameters:
4598: .  mat - the matrix

4600:    Output Parameter:
4601: +  v - the vector for storing the maximums
4602: -  idx - the indices of the column found for each row (optional)

4604:    Level: intermediate

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

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

4611:    Concepts: matrices^getting row maximums

4613: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4614: @*/
4615: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4616: {

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

4627:   (*mat->ops->getrowmax)(mat,v,idx);
4628:   PetscObjectStateIncrease((PetscObject)v);
4629:   return(0);
4630: }

4632: /*@C
4633:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4634:         row of the matrix

4636:    Logically Collective on Mat and Vec

4638:    Input Parameters:
4639: .  mat - the matrix

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

4645:    Level: intermediate

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

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

4652:    Concepts: matrices^getting row maximums

4654: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4655: @*/
4656: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4657: {

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

4669:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4670:   PetscObjectStateIncrease((PetscObject)v);
4671:   return(0);
4672: }

4674: /*@
4675:    MatGetRowSum - Gets the sum of each row of the matrix

4677:    Logically or Neighborhood Collective on Mat and Vec

4679:    Input Parameters:
4680: .  mat - the matrix

4682:    Output Parameter:
4683: .  v - the vector for storing the sum of rows

4685:    Level: intermediate

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

4689:    Concepts: matrices^getting row sums

4691: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4692: @*/
4693: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4694: {
4695:   Vec            ones;

4702:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4703:   MatCheckPreallocated(mat,1);
4704:   MatCreateVecs(mat,&ones,NULL);
4705:   VecSet(ones,1.);
4706:   MatMult(mat,ones,v);
4707:   VecDestroy(&ones);
4708:   return(0);
4709: }

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

4714:    Collective on Mat

4716:    Input Parameter:
4717: +  mat - the matrix to transpose
4718: -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX

4720:    Output Parameters:
4721: .  B - the transpose

4723:    Notes:
4724:      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B

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

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

4730:    Level: intermediate

4732:    Concepts: matrices^transposing

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

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

4750:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4751:   (*mat->ops->transpose)(mat,reuse,B);
4752:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4753:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4754:   return(0);
4755: }

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

4761:    Collective on Mat

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

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

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

4775:    Level: intermediate

4777:    Concepts: matrices^transposing, matrix^symmetry

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

4789:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4790:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4791:   *flg = PETSC_FALSE;
4792:   if (f && g) {
4793:     if (f == g) {
4794:       (*f)(A,B,tol,flg);
4795:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4796:   } else {
4797:     MatType mattype;
4798:     if (!f) {
4799:       MatGetType(A,&mattype);
4800:     } else {
4801:       MatGetType(B,&mattype);
4802:     }
4803:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4804:   }
4805:   return(0);
4806: }

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

4811:    Collective on Mat

4813:    Input Parameter:
4814: +  mat - the matrix to transpose and complex conjugate
4815: -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose

4817:    Output Parameters:
4818: .  B - the Hermitian

4820:    Level: intermediate

4822:    Concepts: matrices^transposing, complex conjugatex

4824: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4825: @*/
4826: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4827: {

4831:   MatTranspose(mat,reuse,B);
4832: #if defined(PETSC_USE_COMPLEX)
4833:   MatConjugate(*B);
4834: #endif
4835:   return(0);
4836: }

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

4841:    Collective on Mat

4843:    Input Parameter:
4844: +  A - the matrix to test
4845: -  B - the matrix to test against, this can equal the first parameter

4847:    Output Parameters:
4848: .  flg - the result

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

4855:    Level: intermediate

4857:    Concepts: matrices^transposing, matrix^symmetry

4859: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4860: @*/
4861: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4862: {
4863:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4869:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4870:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4871:   if (f && g) {
4872:     if (f==g) {
4873:       (*f)(A,B,tol,flg);
4874:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4875:   }
4876:   return(0);
4877: }

4879: /*@
4880:    MatPermute - Creates a new matrix with rows and columns permuted from the
4881:    original.

4883:    Collective on Mat

4885:    Input Parameters:
4886: +  mat - the matrix to permute
4887: .  row - row permutation, each processor supplies only the permutation for its rows
4888: -  col - column permutation, each processor supplies only the permutation for its columns

4890:    Output Parameters:
4891: .  B - the permuted matrix

4893:    Level: advanced

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

4899:    Concepts: matrices^permuting

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

4903: @*/
4904: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4905: {

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

4919:   (*mat->ops->permute)(mat,row,col,B);
4920:   PetscObjectStateIncrease((PetscObject)*B);
4921:   return(0);
4922: }

4924: /*@
4925:    MatEqual - Compares two matrices.

4927:    Collective on Mat

4929:    Input Parameters:
4930: +  A - the first matrix
4931: -  B - the second matrix

4933:    Output Parameter:
4934: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4936:    Level: intermediate

4938:    Concepts: matrices^equality between
4939: @*/
4940: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4941: {

4951:   MatCheckPreallocated(B,2);
4952:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4953:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4954:   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);
4955:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4956:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4957:   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);
4958:   MatCheckPreallocated(A,1);

4960:   (*A->ops->equal)(A,B,flg);
4961:   return(0);
4962: }

4964: /*@C
4965:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4966:    matrices that are stored as vectors.  Either of the two scaling
4967:    matrices can be NULL.

4969:    Collective on Mat

4971:    Input Parameters:
4972: +  mat - the matrix to be scaled
4973: .  l - the left scaling vector (or NULL)
4974: -  r - the right scaling vector (or NULL)

4976:    Notes:
4977:    MatDiagonalScale() computes A = LAR, where
4978:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4979:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4981:    Level: intermediate

4983:    Concepts: matrices^diagonal scaling
4984:    Concepts: diagonal scaling of matrices

4986: .seealso: MatScale()
4987: @*/
4988: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4989: {

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

5002:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5003:   (*mat->ops->diagonalscale)(mat,l,r);
5004:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5005:   PetscObjectStateIncrease((PetscObject)mat);
5006: #if defined(PETSC_HAVE_CUSP)
5007:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5008:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5009:   }
5010: #elif defined(PETSC_HAVE_VIENNACL)
5011:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5012:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5013:   }
5014: #elif defined(PETSC_HAVE_VECCUDA)
5015:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5016:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5017:   }
5018: #endif
5019:   return(0);
5020: }

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

5025:     Logically Collective on Mat

5027:     Input Parameters:
5028: +   mat - the matrix to be scaled
5029: -   a  - the scaling value

5031:     Output Parameter:
5032: .   mat - the scaled matrix

5034:     Level: intermediate

5036:     Concepts: matrices^scaling all entries

5038: .seealso: MatDiagonalScale()
5039: @*/
5040: PetscErrorCode MatScale(Mat mat,PetscScalar a)
5041: {

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

5053:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5054:   if (a != (PetscScalar)1.0) {
5055:     (*mat->ops->scale)(mat,a);
5056:     PetscObjectStateIncrease((PetscObject)mat);
5057: #if defined(PETSC_HAVE_CUSP)
5058:     if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5059:       mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5060:     }
5061: #elif defined(PETSC_HAVE_VIENNACL)
5062:     if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5063:       mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5064:     }
5065: #elif defined(PETSC_HAVE_VECCUDA)
5066:     if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5067:       mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5068:     }
5069: #endif
5070:   }
5071:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5072:   return(0);
5073: }

5075: /*@
5076:    MatNorm - Calculates various norms of a matrix.

5078:    Collective on Mat

5080:    Input Parameters:
5081: +  mat - the matrix
5082: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

5084:    Output Parameters:
5085: .  nrm - the resulting norm

5087:    Level: intermediate

5089:    Concepts: matrices^norm
5090:    Concepts: norm^of matrix
5091: @*/
5092: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5093: {


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

5106:   (*mat->ops->norm)(mat,type,nrm);
5107:   return(0);
5108: }

5110: /*
5111:      This variable is used to prevent counting of MatAssemblyBegin() that
5112:    are called from within a MatAssemblyEnd().
5113: */
5114: static PetscInt MatAssemblyEnd_InUse = 0;
5115: /*@
5116:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5117:    be called after completing all calls to MatSetValues().

5119:    Collective on Mat

5121:    Input Parameters:
5122: +  mat - the matrix
5123: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

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

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

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

5140:    Level: beginner

5142:    Concepts: matrices^assembling

5144: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5145: @*/
5146: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5147: {

5153:   MatCheckPreallocated(mat,1);
5154:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5155:   if (mat->assembled) {
5156:     mat->was_assembled = PETSC_TRUE;
5157:     mat->assembled     = PETSC_FALSE;
5158:   }
5159:   if (!MatAssemblyEnd_InUse) {
5160:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5161:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5162:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5163:   } else if (mat->ops->assemblybegin) {
5164:     (*mat->ops->assemblybegin)(mat,type);
5165:   }
5166:   return(0);
5167: }

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

5173:    Not Collective

5175:    Input Parameter:
5176: .  mat - the matrix

5178:    Output Parameter:
5179: .  assembled - PETSC_TRUE or PETSC_FALSE

5181:    Level: advanced

5183:    Concepts: matrices^assembled?

5185: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5186: @*/
5187: PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5188: {
5193:   *assembled = mat->assembled;
5194:   return(0);
5195: }

5197: /*@
5198:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5199:    be called after MatAssemblyBegin().

5201:    Collective on Mat

5203:    Input Parameters:
5204: +  mat - the matrix
5205: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5207:    Options Database Keys:
5208: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5209: .  -mat_view ::ascii_info_detail - Prints more detailed info
5210: .  -mat_view - Prints matrix in ASCII format
5211: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5212: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5213: .  -display <name> - Sets display name (default is host)
5214: .  -draw_pause <sec> - Sets number of seconds to pause after display
5215: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 12 Using MATLAB with PETSc )
5216: .  -viewer_socket_machine <machine> - Machine to use for socket
5217: .  -viewer_socket_port <port> - Port number to use for socket
5218: -  -mat_view binary:filename[:append] - Save matrix to file in binary format

5220:    Notes:
5221:    MatSetValues() generally caches the values.  The matrix is ready to
5222:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5223:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5224:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5225:    using the matrix.

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

5231:    Level: beginner

5233: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5234: @*/
5235: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5236: {
5237:   PetscErrorCode  ierr;
5238:   static PetscInt inassm = 0;
5239:   PetscBool       flg    = PETSC_FALSE;


5245:   inassm++;
5246:   MatAssemblyEnd_InUse++;
5247:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5248:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5249:     if (mat->ops->assemblyend) {
5250:       (*mat->ops->assemblyend)(mat,type);
5251:     }
5252:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5253:   } else if (mat->ops->assemblyend) {
5254:     (*mat->ops->assemblyend)(mat,type);
5255:   }

5257:   /* Flush assembly is not a true assembly */
5258:   if (type != MAT_FLUSH_ASSEMBLY) {
5259:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5260:   }
5261:   mat->insertmode = NOT_SET_VALUES;
5262:   MatAssemblyEnd_InUse--;
5263:   PetscObjectStateIncrease((PetscObject)mat);
5264:   if (!mat->symmetric_eternal) {
5265:     mat->symmetric_set              = PETSC_FALSE;
5266:     mat->hermitian_set              = PETSC_FALSE;
5267:     mat->structurally_symmetric_set = PETSC_FALSE;
5268:   }
5269: #if defined(PETSC_HAVE_CUSP)
5270:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5271:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5272:   }
5273: #elif defined(PETSC_HAVE_VIENNACL)
5274:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5275:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5276:   }
5277: #elif defined(PETSC_HAVE_VECCUDA)
5278:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5279:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5280:   }
5281: #endif
5282:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5283:     MatViewFromOptions(mat,NULL,"-mat_view");

5285:     if (mat->checksymmetryonassembly) {
5286:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5287:       if (flg) {
5288:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5289:       } else {
5290:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5291:       }
5292:     }
5293:     if (mat->nullsp && mat->checknullspaceonassembly) {
5294:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5295:     }
5296:   }
5297:   inassm--;
5298:   return(0);
5299: }

5301: /*@
5302:    MatSetOption - Sets a parameter option for a matrix. Some options
5303:    may be specific to certain storage formats.  Some options
5304:    determine how values will be inserted (or added). Sorted,
5305:    row-oriented input will generally assemble the fastest. The default
5306:    is row-oriented.

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

5310:    Input Parameters:
5311: +  mat - the matrix
5312: .  option - the option, one of those listed below (and possibly others),
5313: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5315:   Options Describing Matrix Structure:
5316: +    MAT_SPD - symmetric positive definite
5317: .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5318: .    MAT_HERMITIAN - transpose is the complex conjugation
5319: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5320: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5321:                             you set to be kept with all future use of the matrix
5322:                             including after MatAssemblyBegin/End() which could
5323:                             potentially change the symmetry structure, i.e. you
5324:                             KNOW the matrix will ALWAYS have the property you set.


5327:    Options For Use with MatSetValues():
5328:    Insert a logically dense subblock, which can be
5329: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

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

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

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

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

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

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

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

5383:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5384:    searches during matrix assembly. When this flag is set, the hash table
5385:    is created during the first Matrix Assembly. This hash table is
5386:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5387:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5388:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5389:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5407:    Level: intermediate

5409:    Concepts: matrices^setting options

5411: .seealso:  MatOption, Mat

5413: @*/
5414: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5415: {

5421:   if (op > 0) {
5424:   }

5426:   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);
5427:   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()");

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

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

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

5495:    Input Parameters:
5496: +  mat - the matrix
5497: -  option - the option, this only responds to certain options, check the code for which ones

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

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

5504:    Level: intermediate

5506:    Concepts: matrices^setting options

5508: .seealso:  MatOption, MatSetOption()

5510: @*/
5511: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5512: {

5517:   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);
5518:   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()");

5520:   switch (op) {
5521:   case MAT_NO_OFF_PROC_ENTRIES:
5522:     *flg = mat->nooffprocentries;
5523:     break;
5524:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5525:     *flg = mat->nooffproczerorows;
5526:     break;
5527:   case MAT_SYMMETRIC:
5528:     *flg = mat->symmetric;
5529:     break;
5530:   case MAT_HERMITIAN:
5531:     *flg = mat->hermitian;
5532:     break;
5533:   case MAT_STRUCTURALLY_SYMMETRIC:
5534:     *flg = mat->structurally_symmetric;
5535:     break;
5536:   case MAT_SYMMETRY_ETERNAL:
5537:     *flg = mat->symmetric_eternal;
5538:     break;
5539:   case MAT_SPD:
5540:     *flg = mat->spd;
5541:     break;
5542:   default:
5543:     break;
5544:   }
5545:   return(0);
5546: }

5548: /*@
5549:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5550:    this routine retains the old nonzero structure.

5552:    Logically Collective on Mat

5554:    Input Parameters:
5555: .  mat - the matrix

5557:    Level: intermediate

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

5562:    Concepts: matrices^zeroing

5564: .seealso: MatZeroRows()
5565: @*/
5566: PetscErrorCode MatZeroEntries(Mat mat)
5567: {

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

5578:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5579:   (*mat->ops->zeroentries)(mat);
5580:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5581:   PetscObjectStateIncrease((PetscObject)mat);
5582: #if defined(PETSC_HAVE_CUSP)
5583:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5584:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5585:   }
5586: #elif defined(PETSC_HAVE_VIENNACL)
5587:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5588:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5589:   }
5590: #elif defined(PETSC_HAVE_VECCUDA)
5591:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5592:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5593:   }
5594: #endif
5595:   return(0);
5596: }

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

5602:    Collective on Mat

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

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

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

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

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

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

5629:    Level: intermediate

5631:    Concepts: matrices^zeroing rows

5633: .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5634:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5635: @*/
5636: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5637: {

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

5649:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5650:   MatViewFromOptions(mat,NULL,"-mat_view");
5651:   PetscObjectStateIncrease((PetscObject)mat);
5652: #if defined(PETSC_HAVE_CUSP)
5653:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5654:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5655:   }
5656: #elif defined(PETSC_HAVE_VIENNACL)
5657:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5658:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5659:   }
5660: #elif defined(PETSC_HAVE_VECCUDA)
5661:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5662:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5663:   }
5664: #endif
5665:   return(0);
5666: }

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

5672:    Collective on Mat

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

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

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

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

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

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

5698:    Level: intermediate

5700:    Concepts: matrices^zeroing rows

5702: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5703:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5704: @*/
5705: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5706: {
5708:   PetscInt       numRows;
5709:   const PetscInt *rows;

5716:   ISGetLocalSize(is,&numRows);
5717:   ISGetIndices(is,&rows);
5718:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5719:   ISRestoreIndices(is,&rows);
5720:   return(0);
5721: }

5723: /*@C
5724:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5725:    of a set of rows of a matrix.

5727:    Collective on Mat

5729:    Input Parameters:
5730: +  mat - the matrix
5731: .  numRows - the number of rows to remove
5732: .  rows - the global row indices
5733: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5734: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5735: -  b - optional vector of right hand side, that will be adjusted by provided solution

5737:    Notes:
5738:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5739:    but does not release memory.  For the dense and block diagonal
5740:    formats this does not alter the nonzero structure.

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

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

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

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

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

5761:    Level: intermediate

5763:    Concepts: matrices^zeroing rows

5765: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5766:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5767: @*/
5768: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5769: {

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

5781:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5782:   MatViewFromOptions(mat,NULL,"-mat_view");
5783:   PetscObjectStateIncrease((PetscObject)mat);
5784: #if defined(PETSC_HAVE_CUSP)
5785:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5786:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5787:   }
5788: #elif defined(PETSC_HAVE_VIENNACL)
5789:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5790:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5791:   }
5792: #elif defined(PETSC_HAVE_VECCUDA)
5793:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5794:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5795:   }
5796: #endif
5797:   return(0);
5798: }

5800: /*@C
5801:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5802:    of a set of rows of a matrix.

5804:    Collective on Mat

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

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

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

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

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

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

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

5837:    Level: intermediate

5839:    Concepts: matrices^zeroing rows

5841: .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5842:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5843: @*/
5844: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5845: {
5846:   PetscInt       numRows;
5847:   const PetscInt *rows;

5854:   ISGetLocalSize(is,&numRows);
5855:   ISGetIndices(is,&rows);
5856:   MatZeroRows(mat,numRows,rows,diag,x,b);
5857:   ISRestoreIndices(is,&rows);
5858:   return(0);
5859: }

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

5865:    Collective on Mat

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

5875:    Notes:
5876:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5877:    but does not release memory.  For the dense and block diagonal
5878:    formats this does not alter the nonzero structure.

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

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

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

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

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

5898:    In Fortran idxm and idxn should be declared as
5899: $     MatStencil idxm(4,m)
5900:    and the values inserted using
5901: $    idxm(MatStencil_i,1) = i
5902: $    idxm(MatStencil_j,1) = j
5903: $    idxm(MatStencil_k,1) = k
5904: $    idxm(MatStencil_c,1) = c
5905:    etc

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

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

5915:    Level: intermediate

5917:    Concepts: matrices^zeroing rows

5919: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5920:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5921: @*/
5922: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5923: {
5924:   PetscInt       dim     = mat->stencil.dim;
5925:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5926:   PetscInt       *dims   = mat->stencil.dims+1;
5927:   PetscInt       *starts = mat->stencil.starts;
5928:   PetscInt       *dxm    = (PetscInt*) rows;
5929:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5937:   PetscMalloc1(numRows, &jdxm);
5938:   for (i = 0; i < numRows; ++i) {
5939:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5940:     for (j = 0; j < 3-sdim; ++j) dxm++;
5941:     /* Local index in X dir */
5942:     tmp = *dxm++ - starts[0];
5943:     /* Loop over remaining dimensions */
5944:     for (j = 0; j < dim-1; ++j) {
5945:       /* If nonlocal, set index to be negative */
5946:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5947:       /* Update local index */
5948:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5949:     }
5950:     /* Skip component slot if necessary */
5951:     if (mat->stencil.noc) dxm++;
5952:     /* Local row number */
5953:     if (tmp >= 0) {
5954:       jdxm[numNewRows++] = tmp;
5955:     }
5956:   }
5957:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5958:   PetscFree(jdxm);
5959:   return(0);
5960: }

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

5966:    Collective on Mat

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

5976:    Notes:
5977:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5978:    but does not release memory.  For the dense and block diagonal
5979:    formats this does not alter the nonzero structure.

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

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

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

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

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

5999:    In Fortran idxm and idxn should be declared as
6000: $     MatStencil idxm(4,m)
6001:    and the values inserted using
6002: $    idxm(MatStencil_i,1) = i
6003: $    idxm(MatStencil_j,1) = j
6004: $    idxm(MatStencil_k,1) = k
6005: $    idxm(MatStencil_c,1) = c
6006:    etc

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

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

6016:    Level: intermediate

6018:    Concepts: matrices^zeroing rows

6020: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6021:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6022: @*/
6023: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6024: {
6025:   PetscInt       dim     = mat->stencil.dim;
6026:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6027:   PetscInt       *dims   = mat->stencil.dims+1;
6028:   PetscInt       *starts = mat->stencil.starts;
6029:   PetscInt       *dxm    = (PetscInt*) rows;
6030:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


6038:   PetscMalloc1(numRows, &jdxm);
6039:   for (i = 0; i < numRows; ++i) {
6040:     /* Skip unused dimensions (they are ordered k, j, i, c) */
6041:     for (j = 0; j < 3-sdim; ++j) dxm++;
6042:     /* Local index in X dir */
6043:     tmp = *dxm++ - starts[0];
6044:     /* Loop over remaining dimensions */
6045:     for (j = 0; j < dim-1; ++j) {
6046:       /* If nonlocal, set index to be negative */
6047:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6048:       /* Update local index */
6049:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6050:     }
6051:     /* Skip component slot if necessary */
6052:     if (mat->stencil.noc) dxm++;
6053:     /* Local row number */
6054:     if (tmp >= 0) {
6055:       jdxm[numNewRows++] = tmp;
6056:     }
6057:   }
6058:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
6059:   PetscFree(jdxm);
6060:   return(0);
6061: }

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

6067:    Collective on Mat

6069:    Input Parameters:
6070: +  mat - the matrix
6071: .  numRows - the number of rows to remove
6072: .  rows - the global row indices
6073: .  diag - value put in all diagonals of eliminated rows
6074: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6075: -  b - optional vector of right hand side, that will be adjusted by provided solution

6077:    Notes:
6078:    Before calling MatZeroRowsLocal(), the user must first set the
6079:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6081:    For the AIJ matrix formats this removes the old nonzero structure,
6082:    but does not release memory.  For the dense and block diagonal
6083:    formats this does not alter the nonzero structure.

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

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

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

6096:    Level: intermediate

6098:    Concepts: matrices^zeroing

6100: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6101:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6102: @*/
6103: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6104: {

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

6115:   if (mat->ops->zerorowslocal) {
6116:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6117:   } else {
6118:     IS             is, newis;
6119:     const PetscInt *newRows;

6121:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6122:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6123:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6124:     ISGetIndices(newis,&newRows);
6125:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6126:     ISRestoreIndices(newis,&newRows);
6127:     ISDestroy(&newis);
6128:     ISDestroy(&is);
6129:   }
6130:   PetscObjectStateIncrease((PetscObject)mat);
6131: #if defined(PETSC_HAVE_CUSP)
6132:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6133:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6134:   }
6135: #elif defined(PETSC_HAVE_VIENNACL)
6136:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6137:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6138:   }
6139: #elif defined(PETSC_HAVE_VECCUDA)
6140:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6141:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6142:   }
6143: #endif
6144:   return(0);
6145: }

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

6151:    Collective on Mat

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

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

6164:    For the AIJ matrix formats this removes the old nonzero structure,
6165:    but does not release memory.  For the dense and block diagonal
6166:    formats this does not alter the nonzero structure.

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

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

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

6179:    Level: intermediate

6181:    Concepts: matrices^zeroing

6183: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6184:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6185: @*/
6186: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6187: {
6189:   PetscInt       numRows;
6190:   const PetscInt *rows;

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

6200:   ISGetLocalSize(is,&numRows);
6201:   ISGetIndices(is,&rows);
6202:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6203:   ISRestoreIndices(is,&rows);
6204:   return(0);
6205: }

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

6211:    Collective on Mat

6213:    Input Parameters:
6214: +  mat - the matrix
6215: .  numRows - the number of rows to remove
6216: .  rows - the global row indices
6217: .  diag - value put in all diagonals of eliminated rows
6218: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6219: -  b - optional vector of right hand side, that will be adjusted by provided solution

6221:    Notes:
6222:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6223:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6229:    Level: intermediate

6231:    Concepts: matrices^zeroing

6233: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6234:           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6235: @*/
6236: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6237: {
6239:   IS             is, newis;
6240:   const PetscInt *newRows;

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

6250:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6251:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6252:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6253:   ISGetIndices(newis,&newRows);
6254:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6255:   ISRestoreIndices(newis,&newRows);
6256:   ISDestroy(&newis);
6257:   ISDestroy(&is);
6258:   PetscObjectStateIncrease((PetscObject)mat);
6259: #if defined(PETSC_HAVE_CUSP)
6260:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6261:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6262:   }
6263: #elif defined(PETSC_HAVE_VIENNACL)
6264:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6265:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6266:   }
6267: #elif defined(PETSC_HAVE_VECCUDA)
6268:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6269:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6270:   }
6271: #endif
6272:   return(0);
6273: }

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

6279:    Collective on Mat

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

6288:    Notes:
6289:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6290:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6296:    Level: intermediate

6298:    Concepts: matrices^zeroing

6300: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6301:           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6302: @*/
6303: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6304: {
6306:   PetscInt       numRows;
6307:   const PetscInt *rows;

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

6317:   ISGetLocalSize(is,&numRows);
6318:   ISGetIndices(is,&rows);
6319:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6320:   ISRestoreIndices(is,&rows);
6321:   return(0);
6322: }

6324: /*@C
6325:    MatGetSize - Returns the numbers of rows and columns in a matrix.

6327:    Not Collective

6329:    Input Parameter:
6330: .  mat - the matrix

6332:    Output Parameters:
6333: +  m - the number of global rows
6334: -  n - the number of global columns

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

6338:    Level: beginner

6340:    Concepts: matrices^size

6342: .seealso: MatGetLocalSize()
6343: @*/
6344: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6345: {
6348:   if (m) *m = mat->rmap->N;
6349:   if (n) *n = mat->cmap->N;
6350:   return(0);
6351: }

6353: /*@C
6354:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6355:    stored locally.  This information may be implementation dependent, so
6356:    use with care.

6358:    Not Collective

6360:    Input Parameters:
6361: .  mat - the matrix

6363:    Output Parameters:
6364: +  m - the number of local rows
6365: -  n - the number of local columns

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

6369:    Level: beginner

6371:    Concepts: matrices^local size

6373: .seealso: MatGetSize()
6374: @*/
6375: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6376: {
6381:   if (m) *m = mat->rmap->n;
6382:   if (n) *n = mat->cmap->n;
6383:   return(0);
6384: }

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

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

6392:    Input Parameters:
6393: .  mat - the matrix

6395:    Output Parameters:
6396: +  m - the global index of the first local column
6397: -  n - one more than the global index of the last local column

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

6401:    Level: developer

6403:    Concepts: matrices^column ownership

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

6407: @*/
6408: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6409: {
6415:   MatCheckPreallocated(mat,1);
6416:   if (m) *m = mat->cmap->rstart;
6417:   if (n) *n = mat->cmap->rend;
6418:   return(0);
6419: }

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

6427:    Not Collective

6429:    Input Parameters:
6430: .  mat - the matrix

6432:    Output Parameters:
6433: +  m - the global index of the first local row
6434: -  n - one more than the global index of the last local row

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

6441:    Level: beginner

6443:    Concepts: matrices^row ownership

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

6447: @*/
6448: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6449: {
6455:   MatCheckPreallocated(mat,1);
6456:   if (m) *m = mat->rmap->rstart;
6457:   if (n) *n = mat->rmap->rend;
6458:   return(0);
6459: }

6461: /*@C
6462:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6463:    each process

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

6467:    Input Parameters:
6468: .  mat - the matrix

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

6473:    Level: beginner

6475:    Concepts: matrices^row ownership

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

6479: @*/
6480: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6481: {

6487:   MatCheckPreallocated(mat,1);
6488:   PetscLayoutGetRanges(mat->rmap,ranges);
6489:   return(0);
6490: }

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

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

6498:    Input Parameters:
6499: .  mat - the matrix

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

6504:    Level: beginner

6506:    Concepts: matrices^column ownership

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

6510: @*/
6511: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6512: {

6518:   MatCheckPreallocated(mat,1);
6519:   PetscLayoutGetRanges(mat->cmap,ranges);
6520:   return(0);
6521: }

6523: /*@C
6524:    MatGetOwnershipIS - Get row and column ownership as index sets

6526:    Not Collective

6528:    Input Arguments:
6529: .  A - matrix of type Elemental

6531:    Output Arguments:
6532: +  rows - rows in which this process owns elements
6533: .  cols - columns in which this process owns elements

6535:    Level: intermediate

6537: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6538: @*/
6539: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6540: {
6541:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6544:   MatCheckPreallocated(A,1);
6545:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6546:   if (f) {
6547:     (*f)(A,rows,cols);
6548:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6549:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6550:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6551:   }
6552:   return(0);
6553: }

6555: /*@C
6556:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6557:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6558:    to complete the factorization.

6560:    Collective on Mat

6562:    Input Parameters:
6563: +  mat - the matrix
6564: .  row - row permutation
6565: .  column - column permutation
6566: -  info - structure containing
6567: $      levels - number of levels of fill.
6568: $      expected fill - as ratio of original fill.
6569: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6570:                 missing diagonal entries)

6572:    Output Parameters:
6573: .  fact - new matrix that has been symbolically factored

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

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

6581:    Level: developer

6583:   Concepts: matrices^symbolic LU factorization
6584:   Concepts: matrices^factorization
6585:   Concepts: LU^symbolic factorization

6587: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6588:           MatGetOrdering(), MatFactorInfo

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

6593: @*/
6594: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6595: {

6605:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6606:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6607:   if (!(fact)->ops->ilufactorsymbolic) {
6608:     const MatSolverPackage spackage;
6609:     MatFactorGetSolverPackage(fact,&spackage);
6610:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6611:   }
6612:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6613:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6614:   MatCheckPreallocated(mat,2);

6616:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6617:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6618:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6619:   return(0);
6620: }

6622: /*@C
6623:    MatICCFactorSymbolic - Performs symbolic incomplete
6624:    Cholesky factorization for a symmetric matrix.  Use
6625:    MatCholeskyFactorNumeric() to complete the factorization.

6627:    Collective on Mat

6629:    Input Parameters:
6630: +  mat - the matrix
6631: .  perm - row and column permutation
6632: -  info - structure containing
6633: $      levels - number of levels of fill.
6634: $      expected fill - as ratio of original fill.

6636:    Output Parameter:
6637: .  fact - the factored matrix

6639:    Notes:
6640:    Most users should employ the KSP interface for linear solvers
6641:    instead of working directly with matrix algebra routines such as this.
6642:    See, e.g., KSPCreate().

6644:    Level: developer

6646:   Concepts: matrices^symbolic incomplete Cholesky factorization
6647:   Concepts: matrices^factorization
6648:   Concepts: Cholsky^symbolic factorization

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

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

6655: @*/
6656: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6657: {

6666:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6667:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6668:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6669:   if (!(fact)->ops->iccfactorsymbolic) {
6670:     const MatSolverPackage spackage;
6671:     MatFactorGetSolverPackage(fact,&spackage);
6672:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6673:   }
6674:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6675:   MatCheckPreallocated(mat,2);

6677:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6678:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6679:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6680:   return(0);
6681: }

6683: /*@C
6684:    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6685:    points to an array of valid matrices, they may be reused to store the new
6686:    submatrices.

6688:    Collective on Mat

6690:    Input Parameters:
6691: +  mat - the matrix
6692: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6693: .  irow, icol - index sets of rows and columns to extract
6694: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6696:    Output Parameter:
6697: .  submat - the array of submatrices

6699:    Notes:
6700:    MatCreateSubMatrices() can extract ONLY sequential submatrices
6701:    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6702:    to extract a parallel submatrix.

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

6707:    The index sets may not have duplicate entries.

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

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

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

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

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

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

6731:    Level: advanced

6733:    Concepts: matrices^accessing submatrices
6734:    Concepts: submatrices

6736: .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6737: @*/
6738: PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6739: {
6741:   PetscInt       i;
6742:   PetscBool      eq;

6747:   if (n) {
6752:   }
6754:   if (n && scall == MAT_REUSE_MATRIX) {
6757:   }
6758:   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6759:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6760:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6761:   MatCheckPreallocated(mat,1);

6763:   PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6764:   (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);
6765:   PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6766:   for (i=0; i<n; i++) {
6767:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6768:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6769:       ISEqual(irow[i],icol[i],&eq);
6770:       if (eq) {
6771:         if (mat->symmetric) {
6772:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6773:         } else if (mat->hermitian) {
6774:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6775:         } else if (mat->structurally_symmetric) {
6776:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6777:         }
6778:       }
6779:     }
6780:   }
6781:   return(0);
6782: }

6784: /*@C
6785:    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).

6787:    Collective on Mat

6789:    Input Parameters:
6790: +  mat - the matrix
6791: .  n   - the number of submatrixes to be extracted
6792: .  irow, icol - index sets of rows and columns to extract
6793: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6795:    Output Parameter:
6796: .  submat - the array of submatrices

6798:    Level: advanced

6800:    Concepts: matrices^accessing submatrices
6801:    Concepts: submatrices

6803: .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6804: @*/
6805: PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6806: {
6808:   PetscInt       i;
6809:   PetscBool      eq;

6814:   if (n) {
6819:   }
6821:   if (n && scall == MAT_REUSE_MATRIX) {
6824:   }
6825:   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6826:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6827:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6828:   MatCheckPreallocated(mat,1);

6830:   PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6831:   (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6832:   PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6833:   for (i=0; i<n; i++) {
6834:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6835:       ISEqual(irow[i],icol[i],&eq);
6836:       if (eq) {
6837:         if (mat->symmetric) {
6838:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6839:         } else if (mat->hermitian) {
6840:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6841:         } else if (mat->structurally_symmetric) {
6842:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6843:         }
6844:       }
6845:     }
6846:   }
6847:   return(0);
6848: }

6850: /*@C
6851:    MatDestroyMatrices - Destroys an array of matrices.

6853:    Collective on Mat

6855:    Input Parameters:
6856: +  n - the number of local matrices
6857: -  mat - the matrices (note that this is a pointer to the array of matrices)

6859:    Level: advanced

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

6864: .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6865: @*/
6866: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6867: {
6869:   PetscInt       i;

6872:   if (!*mat) return(0);
6873:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);

6876:   for (i=0; i<n; i++) {
6877:     MatDestroy(&(*mat)[i]);
6878:   }

6880:   /* memory is allocated even if n = 0 */
6881:   PetscFree(*mat);
6882:   return(0);
6883: }

6885: /*@C
6886:    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().

6888:    Collective on Mat

6890:    Input Parameters:
6891: +  n - the number of local matrices
6892: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6893:                        sequence of MatCreateSubMatrices())

6895:    Level: advanced

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

6900: .seealso: MatCreateSubMatrices()
6901: @*/
6902: PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6903: {
6905:   Mat            mat0;

6908:   if (!*mat) return(0);
6909:   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6910:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);

6913:   mat0 = (*mat)[0];
6914:   if (mat0 && mat0->ops->destroysubmatrices) {
6915:     (mat0->ops->destroysubmatrices)(n,mat);
6916:   } else {
6917:     MatDestroyMatrices(n,mat);
6918:   }
6919:   return(0);
6920: }

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

6925:    Collective on Mat

6927:    Input Parameters:
6928: .  mat - the matrix

6930:    Output Parameter:
6931: .  matstruct - the sequential matrix with the nonzero structure of mat

6933:   Level: intermediate

6935: .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6936: @*/
6937: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6938: {


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

6949:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6950:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6951:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6952:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6953:   return(0);
6954: }

6956: /*@C
6957:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6959:    Collective on Mat

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

6965:    Level: advanced

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

6969: .seealso: MatGetSeqNonzeroStructure()
6970: @*/
6971: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6972: {

6977:   MatDestroy(mat);
6978:   return(0);
6979: }

6981: /*@
6982:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6983:    replaces the index sets by larger ones that represent submatrices with
6984:    additional overlap.

6986:    Collective on Mat

6988:    Input Parameters:
6989: +  mat - the matrix
6990: .  n   - the number of index sets
6991: .  is  - the array of index sets (these index sets will changed during the call)
6992: -  ov  - the additional overlap requested

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

6997:    Level: developer

6999:    Concepts: overlap
7000:    Concepts: ASM^computing overlap

7002: .seealso: MatCreateSubMatrices()
7003: @*/
7004: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7005: {

7011:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7012:   if (n) {
7015:   }
7016:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7017:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7018:   MatCheckPreallocated(mat,1);

7020:   if (!ov) return(0);
7021:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7022:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
7023:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
7024:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
7025:   return(0);
7026: }


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

7031: /*@
7032:    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7033:    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7034:    additional overlap.

7036:    Collective on Mat

7038:    Input Parameters:
7039: +  mat - the matrix
7040: .  n   - the number of index sets
7041: .  is  - the array of index sets (these index sets will changed during the call)
7042: -  ov  - the additional overlap requested

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

7047:    Level: developer

7049:    Concepts: overlap
7050:    Concepts: ASM^computing overlap

7052: .seealso: MatCreateSubMatrices()
7053: @*/
7054: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7055: {
7056:   PetscInt       i;

7062:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7063:   if (n) {
7066:   }
7067:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7068:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7069:   MatCheckPreallocated(mat,1);
7070:   if (!ov) return(0);
7071:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
7072:   for(i=0; i<n; i++){
7073:          MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
7074:   }
7075:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
7076:   return(0);
7077: }




7082: /*@
7083:    MatGetBlockSize - Returns the matrix block size.

7085:    Not Collective

7087:    Input Parameter:
7088: .  mat - the matrix

7090:    Output Parameter:
7091: .  bs - block size

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

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

7098:    Level: intermediate

7100:    Concepts: matrices^block size

7102: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7103: @*/
7104: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7105: {
7109:   *bs = PetscAbs(mat->rmap->bs);
7110:   return(0);
7111: }

7113: /*@
7114:    MatGetBlockSizes - Returns the matrix block row and column sizes.

7116:    Not Collective

7118:    Input Parameter:
7119: .  mat - the matrix

7121:    Output Parameter:
7122: .  rbs - row block size
7123: .  cbs - column block size

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

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

7131:    Level: intermediate

7133:    Concepts: matrices^block size

7135: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7136: @*/
7137: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7138: {
7143:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7144:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7145:   return(0);
7146: }

7148: /*@
7149:    MatSetBlockSize - Sets the matrix block size.

7151:    Logically Collective on Mat

7153:    Input Parameters:
7154: +  mat - the matrix
7155: -  bs - block size

7157:    Notes:
7158:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7159:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.

7161:     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7162:     is compatible with the matrix local sizes.

7164:    Level: intermediate

7166:    Concepts: matrices^block size

7168: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7169: @*/
7170: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7171: {

7177:   MatSetBlockSizes(mat,bs,bs);
7178:   return(0);
7179: }

7181: /*@
7182:    MatSetBlockSizes - Sets the matrix block row and column sizes.

7184:    Logically Collective on Mat

7186:    Input Parameters:
7187: +  mat - the matrix
7188: -  rbs - row block size
7189: -  cbs - column block size

7191:    Notes:
7192:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7193:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7194:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

7196:     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7197:     are compatible with the matrix local sizes.

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

7201:    Level: intermediate

7203:    Concepts: matrices^block size

7205: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7206: @*/
7207: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7208: {

7215:   if (mat->ops->setblocksizes) {
7216:     (*mat->ops->setblocksizes)(mat,rbs,cbs);
7217:   }
7218:   if (mat->rmap->refcnt) {
7219:     ISLocalToGlobalMapping l2g = NULL;
7220:     PetscLayout            nmap = NULL;

7222:     PetscLayoutDuplicate(mat->rmap,&nmap);
7223:     if (mat->rmap->mapping) {
7224:       ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);
7225:     }
7226:     PetscLayoutDestroy(&mat->rmap);
7227:     mat->rmap = nmap;
7228:     mat->rmap->mapping = l2g;
7229:   }
7230:   if (mat->cmap->refcnt) {
7231:     ISLocalToGlobalMapping l2g = NULL;
7232:     PetscLayout            nmap = NULL;

7234:     PetscLayoutDuplicate(mat->cmap,&nmap);
7235:     if (mat->cmap->mapping) {
7236:       ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);
7237:     }
7238:     PetscLayoutDestroy(&mat->cmap);
7239:     mat->cmap = nmap;
7240:     mat->cmap->mapping = l2g;
7241:   }
7242:   PetscLayoutSetBlockSize(mat->rmap,rbs);
7243:   PetscLayoutSetBlockSize(mat->cmap,cbs);
7244:   return(0);
7245: }

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

7250:    Logically Collective on Mat

7252:    Input Parameters:
7253: +  mat - the matrix
7254: .  fromRow - matrix from which to copy row block size
7255: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

7257:    Level: developer

7259:    Concepts: matrices^block size

7261: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7262: @*/
7263: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7264: {

7271:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7272:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7273:   return(0);
7274: }

7276: /*@
7277:    MatResidual - Default routine to calculate the residual.

7279:    Collective on Mat and Vec

7281:    Input Parameters:
7282: +  mat - the matrix
7283: .  b   - the right-hand-side
7284: -  x   - the approximate solution

7286:    Output Parameter:
7287: .  r - location to store the residual

7289:    Level: developer

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

7293: .seealso: PCMGSetResidual()
7294: @*/
7295: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7296: {

7305:   MatCheckPreallocated(mat,1);
7306:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7307:   if (!mat->ops->residual) {
7308:     MatMult(mat,x,r);
7309:     VecAYPX(r,-1.0,b);
7310:   } else {
7311:     (*mat->ops->residual)(mat,b,x,r);
7312:   }
7313:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7314:   return(0);
7315: }

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

7320:    Collective on Mat

7322:     Input Parameters:
7323: +   mat - the matrix
7324: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7325: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7326: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7327:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7328:                  always used.

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

7337:     Level: developer

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

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

7344:     Fortran Notes:
7345:     In Fortran use
7346: $
7347: $      PetscInt ia(1), ja(1)
7348: $      PetscOffset iia, jja
7349: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7350: $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)

7352:      or
7353: $
7354: $    PetscInt, pointer :: ia(:),ja(:)
7355: $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7356: $    ! Access the ith and jth entries via ia(i) and ja(j)

7358: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7359: @*/
7360: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7361: {

7371:   MatCheckPreallocated(mat,1);
7372:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7373:   else {
7374:     *done = PETSC_TRUE;
7375:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7376:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7377:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7378:   }
7379:   return(0);
7380: }

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

7385:     Collective on Mat

7387:     Input Parameters:
7388: +   mat - the matrix
7389: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7390: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7391:                 symmetrized
7392: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7393:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7394:                  always used.
7395: .   n - number of columns in the (possibly compressed) matrix
7396: .   ia - the column pointers
7397: -   ja - the row indices

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

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

7407:     Level: developer

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

7422:   MatCheckPreallocated(mat,1);
7423:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7424:   else {
7425:     *done = PETSC_TRUE;
7426:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7427:   }
7428:   return(0);
7429: }

7431: /*@C
7432:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7433:     MatGetRowIJ().

7435:     Collective on Mat

7437:     Input Parameters:
7438: +   mat - the matrix
7439: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7440: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7441:                 symmetrized
7442: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7443:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7444:                  always used.
7445: .   n - size of (possibly compressed) matrix
7446: .   ia - the row pointers
7447: -   ja - the column indices

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

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

7457:     Level: developer

7459: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7460: @*/
7461: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7462: {

7471:   MatCheckPreallocated(mat,1);

7473:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7474:   else {
7475:     *done = PETSC_TRUE;
7476:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7477:     if (n)  *n = 0;
7478:     if (ia) *ia = NULL;
7479:     if (ja) *ja = NULL;
7480:   }
7481:   return(0);
7482: }

7484: /*@C
7485:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7486:     MatGetColumnIJ().

7488:     Collective on Mat

7490:     Input Parameters:
7491: +   mat - the matrix
7492: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7493: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7494:                 symmetrized
7495: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7496:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7497:                  always used.

7499:     Output Parameters:
7500: +   n - size of (possibly compressed) matrix
7501: .   ia - the column pointers
7502: .   ja - the row indices
7503: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7505:     Level: developer

7507: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7508: @*/
7509: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7510: {

7519:   MatCheckPreallocated(mat,1);

7521:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7522:   else {
7523:     *done = PETSC_TRUE;
7524:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7525:     if (n)  *n = 0;
7526:     if (ia) *ia = NULL;
7527:     if (ja) *ja = NULL;
7528:   }
7529:   return(0);
7530: }

7532: /*@C
7533:     MatColoringPatch -Used inside matrix coloring routines that
7534:     use MatGetRowIJ() and/or MatGetColumnIJ().

7536:     Collective on Mat

7538:     Input Parameters:
7539: +   mat - the matrix
7540: .   ncolors - max color value
7541: .   n   - number of entries in colorarray
7542: -   colorarray - array indicating color for each column

7544:     Output Parameters:
7545: .   iscoloring - coloring generated using colorarray information

7547:     Level: developer

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

7551: @*/
7552: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7553: {

7561:   MatCheckPreallocated(mat,1);

7563:   if (!mat->ops->coloringpatch) {
7564:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7565:   } else {
7566:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7567:   }
7568:   return(0);
7569: }


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

7575:    Logically Collective on Mat

7577:    Input Parameter:
7578: .  mat - the factored matrix to be reset

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

7587:    Note that one can specify in-place ILU(0) factorization by calling
7588: .vb
7589:      PCType(pc,PCILU);
7590:      PCFactorSeUseInPlace(pc);
7591: .ve
7592:    or by using the options -pc_type ilu -pc_factor_in_place

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

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

7603:    Level: developer

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

7607:    Concepts: matrices^unfactored

7609: @*/
7610: PetscErrorCode MatSetUnfactored(Mat mat)
7611: {

7617:   MatCheckPreallocated(mat,1);
7618:   mat->factortype = MAT_FACTOR_NONE;
7619:   if (!mat->ops->setunfactored) return(0);
7620:   (*mat->ops->setunfactored)(mat);
7621:   return(0);
7622: }

7624: /*MC
7625:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7627:     Synopsis:
7628:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7630:     Not collective

7632:     Input Parameter:
7633: .   x - matrix

7635:     Output Parameters:
7636: +   xx_v - the Fortran90 pointer to the array
7637: -   ierr - error code

7639:     Example of Usage:
7640: .vb
7641:       PetscScalar, pointer xx_v(:,:)
7642:       ....
7643:       call MatDenseGetArrayF90(x,xx_v,ierr)
7644:       a = xx_v(3)
7645:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7646: .ve

7648:     Level: advanced

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

7652:     Concepts: matrices^accessing array

7654: M*/

7656: /*MC
7657:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7658:     accessed with MatDenseGetArrayF90().

7660:     Synopsis:
7661:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7663:     Not collective

7665:     Input Parameters:
7666: +   x - matrix
7667: -   xx_v - the Fortran90 pointer to the array

7669:     Output Parameter:
7670: .   ierr - error code

7672:     Example of Usage:
7673: .vb
7674:        PetscScalar, pointer xx_v(:,:)
7675:        ....
7676:        call MatDenseGetArrayF90(x,xx_v,ierr)
7677:        a = xx_v(3)
7678:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7679: .ve

7681:     Level: advanced

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

7685: M*/


7688: /*MC
7689:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7691:     Synopsis:
7692:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7694:     Not collective

7696:     Input Parameter:
7697: .   x - matrix

7699:     Output Parameters:
7700: +   xx_v - the Fortran90 pointer to the array
7701: -   ierr - error code

7703:     Example of Usage:
7704: .vb
7705:       PetscScalar, pointer xx_v(:)
7706:       ....
7707:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7708:       a = xx_v(3)
7709:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7710: .ve

7712:     Level: advanced

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

7716:     Concepts: matrices^accessing array

7718: M*/

7720: /*MC
7721:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7722:     accessed with MatSeqAIJGetArrayF90().

7724:     Synopsis:
7725:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7727:     Not collective

7729:     Input Parameters:
7730: +   x - matrix
7731: -   xx_v - the Fortran90 pointer to the array

7733:     Output Parameter:
7734: .   ierr - error code

7736:     Example of Usage:
7737: .vb
7738:        PetscScalar, pointer xx_v(:)
7739:        ....
7740:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7741:        a = xx_v(3)
7742:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7743: .ve

7745:     Level: advanced

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

7749: M*/


7752: /*@
7753:     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7754:                       as the original matrix.

7756:     Collective on Mat

7758:     Input Parameters:
7759: +   mat - the original matrix
7760: .   isrow - parallel IS containing the rows this processor should obtain
7761: .   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.
7762: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7764:     Output Parameter:
7765: .   newmat - the new submatrix, of the same type as the old

7767:     Level: advanced

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

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

7775:     The index sets may not have duplicate entries.

7777:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7778:    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7779:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7780:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7781:    you are finished using it.

7783:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7784:     the input matrix.

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

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

7794: .vb
7795:             1  2  0  |  0  3  0  |  0  4
7796:     Proc0   0  5  6  |  7  0  0  |  8  0
7797:             9  0 10  | 11  0  0  | 12  0
7798:     -------------------------------------
7799:            13  0 14  | 15 16 17  |  0  0
7800:     Proc1   0 18  0  | 19 20 21  |  0  0
7801:             0  0  0  | 22 23  0  | 24  0
7802:     -------------------------------------
7803:     Proc2  25 26 27  |  0  0 28  | 29  0
7804:            30  0  0  | 31 32 33  |  0 34
7805: .ve

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

7809: .vb
7810:             2  0  |  0  3  0  |  0
7811:     Proc0   5  6  |  7  0  0  |  8
7812:     -------------------------------
7813:     Proc1  18  0  | 19 20 21  |  0
7814:     -------------------------------
7815:     Proc2  26 27  |  0  0 28  | 29
7816:             0  0  | 31 32 33  |  0
7817: .ve


7820:     Concepts: matrices^submatrices

7822: .seealso: MatCreateSubMatrices()
7823: @*/
7824: PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7825: {
7827:   PetscMPIInt    size;
7828:   Mat            *local;
7829:   IS             iscoltmp;

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

7841:   MatCheckPreallocated(mat,1);
7842:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7844:   if (!iscol || isrow == iscol) {
7845:     PetscBool   stride;
7846:     PetscMPIInt grabentirematrix = 0,grab;
7847:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7848:     if (stride) {
7849:       PetscInt first,step,n,rstart,rend;
7850:       ISStrideGetInfo(isrow,&first,&step);
7851:       if (step == 1) {
7852:         MatGetOwnershipRange(mat,&rstart,&rend);
7853:         if (rstart == first) {
7854:           ISGetLocalSize(isrow,&n);
7855:           if (n == rend-rstart) {
7856:             grabentirematrix = 1;
7857:           }
7858:         }
7859:       }
7860:     }
7861:     MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7862:     if (grab) {
7863:       PetscInfo(mat,"Getting entire matrix as submatrix\n");
7864:       if (cll == MAT_INITIAL_MATRIX) {
7865:         *newmat = mat;
7866:         PetscObjectReference((PetscObject)mat);
7867:       }
7868:       return(0);
7869:     }
7870:   }

7872:   if (!iscol) {
7873:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7874:   } else {
7875:     iscoltmp = iscol;
7876:   }

7878:   /* if original matrix is on just one processor then use submatrix generated */
7879:   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7880:     MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7881:     if (!iscol) {ISDestroy(&iscoltmp);}
7882:     return(0);
7883:   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7884:     MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7885:     *newmat = *local;
7886:     PetscFree(local);
7887:     if (!iscol) {ISDestroy(&iscoltmp);}
7888:     return(0);
7889:   } else if (!mat->ops->createsubmatrix) {
7890:     /* Create a new matrix type that implements the operation using the full matrix */
7891:     PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7892:     switch (cll) {
7893:     case MAT_INITIAL_MATRIX:
7894:       MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);
7895:       break;
7896:     case MAT_REUSE_MATRIX:
7897:       MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);
7898:       break;
7899:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7900:     }
7901:     PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);
7902:     if (!iscol) {ISDestroy(&iscoltmp);}
7903:     return(0);
7904:   }

7906:   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7907:   PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7908:   (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7909:   PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);
7910:   if (!iscol) {ISDestroy(&iscoltmp);}
7911:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7912:   return(0);
7913: }

7915: /*@
7916:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7917:    used during the assembly process to store values that belong to
7918:    other processors.

7920:    Not Collective

7922:    Input Parameters:
7923: +  mat   - the matrix
7924: .  size  - the initial size of the stash.
7925: -  bsize - the initial size of the block-stash(if used).

7927:    Options Database Keys:
7928: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7929: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7931:    Level: intermediate

7933:    Notes:
7934:      The block-stash is used for values set with MatSetValuesBlocked() while
7935:      the stash is used for values set with MatSetValues()

7937:      Run with the option -info and look for output of the form
7938:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7939:      to determine the appropriate value, MM, to use for size and
7940:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7941:      to determine the value, BMM to use for bsize

7943:    Concepts: stash^setting matrix size
7944:    Concepts: matrices^stash

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

7948: @*/
7949: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7950: {

7956:   MatStashSetInitialSize_Private(&mat->stash,size);
7957:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7958:   return(0);
7959: }

7961: /*@
7962:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7963:      the matrix

7965:    Neighbor-wise Collective on Mat

7967:    Input Parameters:
7968: +  mat   - the matrix
7969: .  x,y - the vectors
7970: -  w - where the result is stored

7972:    Level: intermediate

7974:    Notes:
7975:     w may be the same vector as y.

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

7980:     Concepts: interpolation

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

7984: @*/
7985: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7986: {
7988:   PetscInt       M,N,Ny;

7996:   MatCheckPreallocated(A,1);
7997:   MatGetSize(A,&M,&N);
7998:   VecGetSize(y,&Ny);
7999:   if (M == Ny) {
8000:     MatMultAdd(A,x,y,w);
8001:   } else {
8002:     MatMultTransposeAdd(A,x,y,w);
8003:   }
8004:   return(0);
8005: }

8007: /*@
8008:    MatInterpolate - y = A*x or A'*x depending on the shape of
8009:      the matrix

8011:    Neighbor-wise Collective on Mat

8013:    Input Parameters:
8014: +  mat   - the matrix
8015: -  x,y - the vectors

8017:    Level: intermediate

8019:    Notes:
8020:     This allows one to use either the restriction or interpolation (its transpose)
8021:     matrix to do the interpolation

8023:    Concepts: matrices^interpolation

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

8027: @*/
8028: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8029: {
8031:   PetscInt       M,N,Ny;

8038:   MatCheckPreallocated(A,1);
8039:   MatGetSize(A,&M,&N);
8040:   VecGetSize(y,&Ny);
8041:   if (M == Ny) {
8042:     MatMult(A,x,y);
8043:   } else {
8044:     MatMultTranspose(A,x,y);
8045:   }
8046:   return(0);
8047: }

8049: /*@
8050:    MatRestrict - y = A*x or A'*x

8052:    Neighbor-wise Collective on Mat

8054:    Input Parameters:
8055: +  mat   - the matrix
8056: -  x,y - the vectors

8058:    Level: intermediate

8060:    Notes:
8061:     This allows one to use either the restriction or interpolation (its transpose)
8062:     matrix to do the restriction

8064:    Concepts: matrices^restriction

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

8068: @*/
8069: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8070: {
8072:   PetscInt       M,N,Ny;

8079:   MatCheckPreallocated(A,1);

8081:   MatGetSize(A,&M,&N);
8082:   VecGetSize(y,&Ny);
8083:   if (M == Ny) {
8084:     MatMult(A,x,y);
8085:   } else {
8086:     MatMultTranspose(A,x,y);
8087:   }
8088:   return(0);
8089: }

8091: /*@
8092:    MatGetNullSpace - retrieves the null space to a matrix.

8094:    Logically Collective on Mat and MatNullSpace

8096:    Input Parameters:
8097: +  mat - the matrix
8098: -  nullsp - the null space object

8100:    Level: developer

8102:    Concepts: null space^attaching to matrix

8104: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8105: @*/
8106: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8107: {
8112:   *nullsp = mat->nullsp;
8113:   return(0);
8114: }

8116: /*@
8117:    MatSetNullSpace - attaches a null space to a matrix.

8119:    Logically Collective on Mat and MatNullSpace

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

8125:    Level: advanced

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

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

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


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

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

8144:     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
8145:     routine also automatically calls MatSetTransposeNullSpace().

8147:    Concepts: null space^attaching to matrix

8149: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8150: @*/
8151: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8152: {

8159:   MatCheckPreallocated(mat,1);
8160:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8161:   MatNullSpaceDestroy(&mat->nullsp);
8162:   mat->nullsp = nullsp;
8163:   if (mat->symmetric_set && mat->symmetric) {
8164:     MatSetTransposeNullSpace(mat,nullsp);
8165:   }
8166:   return(0);
8167: }

8169: /*@
8170:    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.

8172:    Logically Collective on Mat and MatNullSpace

8174:    Input Parameters:
8175: +  mat - the matrix
8176: -  nullsp - the null space object

8178:    Level: developer

8180:    Concepts: null space^attaching to matrix

8182: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8183: @*/
8184: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8185: {
8190:   *nullsp = mat->transnullsp;
8191:   return(0);
8192: }

8194: /*@
8195:    MatSetTransposeNullSpace - attaches a null space to a matrix.

8197:    Logically Collective on Mat and MatNullSpace

8199:    Input Parameters:
8200: +  mat - the matrix
8201: -  nullsp - the null space object

8203:    Level: advanced

8205:    Notes:
8206:       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.
8207:       You must also call MatSetNullSpace()


8210:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8211:    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).
8212:    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
8213:    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
8214:    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).

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

8218:    Concepts: null space^attaching to matrix

8220: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8221: @*/
8222: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8223: {

8230:   MatCheckPreallocated(mat,1);
8231:   PetscObjectReference((PetscObject)nullsp);
8232:   MatNullSpaceDestroy(&mat->transnullsp);
8233:   mat->transnullsp = nullsp;
8234:   return(0);
8235: }

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

8241:    Logically Collective on Mat and MatNullSpace

8243:    Input Parameters:
8244: +  mat - the matrix
8245: -  nullsp - the null space object

8247:    Level: advanced

8249:    Notes:
8250:       Overwrites any previous near null space that may have been attached

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

8254:    Concepts: null space^attaching to matrix

8256: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8257: @*/
8258: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8259: {

8266:   MatCheckPreallocated(mat,1);
8267:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8268:   MatNullSpaceDestroy(&mat->nearnullsp);
8269:   mat->nearnullsp = nullsp;
8270:   return(0);
8271: }

8273: /*@
8274:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

8276:    Not Collective

8278:    Input Parameters:
8279: .  mat - the matrix

8281:    Output Parameters:
8282: .  nullsp - the null space object, NULL if not set

8284:    Level: developer

8286:    Concepts: null space^attaching to matrix

8288: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8289: @*/
8290: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8291: {
8296:   MatCheckPreallocated(mat,1);
8297:   *nullsp = mat->nearnullsp;
8298:   return(0);
8299: }

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

8304:    Collective on Mat

8306:    Input Parameters:
8307: +  mat - the matrix
8308: .  row - row/column permutation
8309: .  fill - expected fill factor >= 1.0
8310: -  level - level of fill, for ICC(k)

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

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

8320:    Level: developer

8322:    Concepts: matrices^incomplete Cholesky factorization
8323:    Concepts: Cholesky factorization

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

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

8330: @*/
8331: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8332: {

8340:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8341:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8342:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8343:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8344:   MatCheckPreallocated(mat,1);
8345:   (*mat->ops->iccfactor)(mat,row,info);
8346:   PetscObjectStateIncrease((PetscObject)mat);
8347:   return(0);
8348: }

8350: /*@
8351:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8352:          ghosted ones.

8354:    Not Collective

8356:    Input Parameters:
8357: +  mat - the matrix
8358: -  diag = the diagonal values, including ghost ones

8360:    Level: developer

8362:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

8364: .seealso: MatDiagonalScale()
8365: @*/
8366: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8367: {
8369:   PetscMPIInt    size;


8376:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8377:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8378:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8379:   if (size == 1) {
8380:     PetscInt n,m;
8381:     VecGetSize(diag,&n);
8382:     MatGetSize(mat,0,&m);
8383:     if (m == n) {
8384:       MatDiagonalScale(mat,0,diag);
8385:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8386:   } else {
8387:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8388:   }
8389:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8390:   PetscObjectStateIncrease((PetscObject)mat);
8391:   return(0);
8392: }

8394: /*@
8395:    MatGetInertia - Gets the inertia from a factored matrix

8397:    Collective on Mat

8399:    Input Parameter:
8400: .  mat - the matrix

8402:    Output Parameters:
8403: +   nneg - number of negative eigenvalues
8404: .   nzero - number of zero eigenvalues
8405: -   npos - number of positive eigenvalues

8407:    Level: advanced

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


8412: @*/
8413: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8414: {

8420:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8421:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8422:   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8423:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8424:   return(0);
8425: }

8427: /* ----------------------------------------------------------------*/
8428: /*@C
8429:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

8431:    Neighbor-wise Collective on Mat and Vecs

8433:    Input Parameters:
8434: +  mat - the factored matrix
8435: -  b - the right-hand-side vectors

8437:    Output Parameter:
8438: .  x - the result vectors

8440:    Notes:
8441:    The vectors b and x cannot be the same.  I.e., one cannot
8442:    call MatSolves(A,x,x).

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

8449:    Level: developer

8451:    Concepts: matrices^triangular solves

8453: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8454: @*/
8455: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8456: {

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

8466:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8467:   MatCheckPreallocated(mat,1);
8468:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8469:   (*mat->ops->solves)(mat,b,x);
8470:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8471:   return(0);
8472: }

8474: /*@
8475:    MatIsSymmetric - Test whether a matrix is symmetric

8477:    Collective on Mat

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

8483:    Output Parameters:
8484: .  flg - the result

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

8488:    Level: intermediate

8490:    Concepts: matrix^symmetry

8492: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8493: @*/
8494: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8495: {


8502:   if (!A->symmetric_set) {
8503:     if (!A->ops->issymmetric) {
8504:       MatType mattype;
8505:       MatGetType(A,&mattype);
8506:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8507:     }
8508:     (*A->ops->issymmetric)(A,tol,flg);
8509:     if (!tol) {
8510:       A->symmetric_set = PETSC_TRUE;
8511:       A->symmetric     = *flg;
8512:       if (A->symmetric) {
8513:         A->structurally_symmetric_set = PETSC_TRUE;
8514:         A->structurally_symmetric     = PETSC_TRUE;
8515:       }
8516:     }
8517:   } else if (A->symmetric) {
8518:     *flg = PETSC_TRUE;
8519:   } else if (!tol) {
8520:     *flg = PETSC_FALSE;
8521:   } else {
8522:     if (!A->ops->issymmetric) {
8523:       MatType mattype;
8524:       MatGetType(A,&mattype);
8525:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8526:     }
8527:     (*A->ops->issymmetric)(A,tol,flg);
8528:   }
8529:   return(0);
8530: }

8532: /*@
8533:    MatIsHermitian - Test whether a matrix is Hermitian

8535:    Collective on Mat

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

8541:    Output Parameters:
8542: .  flg - the result

8544:    Level: intermediate

8546:    Concepts: matrix^symmetry

8548: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8549:           MatIsSymmetricKnown(), MatIsSymmetric()
8550: @*/
8551: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8552: {


8559:   if (!A->hermitian_set) {
8560:     if (!A->ops->ishermitian) {
8561:       MatType mattype;
8562:       MatGetType(A,&mattype);
8563:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8564:     }
8565:     (*A->ops->ishermitian)(A,tol,flg);
8566:     if (!tol) {
8567:       A->hermitian_set = PETSC_TRUE;
8568:       A->hermitian     = *flg;
8569:       if (A->hermitian) {
8570:         A->structurally_symmetric_set = PETSC_TRUE;
8571:         A->structurally_symmetric     = PETSC_TRUE;
8572:       }
8573:     }
8574:   } else if (A->hermitian) {
8575:     *flg = PETSC_TRUE;
8576:   } else if (!tol) {
8577:     *flg = PETSC_FALSE;
8578:   } else {
8579:     if (!A->ops->ishermitian) {
8580:       MatType mattype;
8581:       MatGetType(A,&mattype);
8582:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8583:     }
8584:     (*A->ops->ishermitian)(A,tol,flg);
8585:   }
8586:   return(0);
8587: }

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

8592:    Not Collective

8594:    Input Parameter:
8595: .  A - the matrix to check

8597:    Output Parameters:
8598: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8599: -  flg - the result

8601:    Level: advanced

8603:    Concepts: matrix^symmetry

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

8608: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8609: @*/
8610: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8611: {
8616:   if (A->symmetric_set) {
8617:     *set = PETSC_TRUE;
8618:     *flg = A->symmetric;
8619:   } else {
8620:     *set = PETSC_FALSE;
8621:   }
8622:   return(0);
8623: }

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

8628:    Not Collective

8630:    Input Parameter:
8631: .  A - the matrix to check

8633:    Output Parameters:
8634: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8635: -  flg - the result

8637:    Level: advanced

8639:    Concepts: matrix^symmetry

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

8644: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8645: @*/
8646: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8647: {
8652:   if (A->hermitian_set) {
8653:     *set = PETSC_TRUE;
8654:     *flg = A->hermitian;
8655:   } else {
8656:     *set = PETSC_FALSE;
8657:   }
8658:   return(0);
8659: }

8661: /*@
8662:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8664:    Collective on Mat

8666:    Input Parameter:
8667: .  A - the matrix to test

8669:    Output Parameters:
8670: .  flg - the result

8672:    Level: intermediate

8674:    Concepts: matrix^symmetry

8676: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8677: @*/
8678: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8679: {

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

8689:     A->structurally_symmetric_set = PETSC_TRUE;
8690:   }
8691:   *flg = A->structurally_symmetric;
8692:   return(0);
8693: }

8695: /*@
8696:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8697:        to be communicated to other processors during the MatAssemblyBegin/End() process

8699:     Not collective

8701:    Input Parameter:
8702: .   vec - the vector

8704:    Output Parameters:
8705: +   nstash   - the size of the stash
8706: .   reallocs - the number of additional mallocs incurred.
8707: .   bnstash   - the size of the block stash
8708: -   breallocs - the number of additional mallocs incurred.in the block stash

8710:    Level: advanced

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

8714: @*/
8715: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8716: {

8720:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8721:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8722:   return(0);
8723: }

8725: /*@C
8726:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8727:      parallel layout

8729:    Collective on Mat

8731:    Input Parameter:
8732: .  mat - the matrix

8734:    Output Parameter:
8735: +   right - (optional) vector that the matrix can be multiplied against
8736: -   left - (optional) vector that the matrix vector product can be stored in

8738:    Notes:
8739:     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().

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

8743:   Level: advanced

8745: .seealso: MatCreate(), VecDestroy()
8746: @*/
8747: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8748: {

8754:   if (mat->ops->getvecs) {
8755:     (*mat->ops->getvecs)(mat,right,left);
8756:   } else {
8757:     PetscInt rbs,cbs;
8758:     MatGetBlockSizes(mat,&rbs,&cbs);
8759:     if (right) {
8760:       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8761:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8762:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8763:       VecSetBlockSize(*right,cbs);
8764:       VecSetType(*right,VECSTANDARD);
8765:       PetscLayoutReference(mat->cmap,&(*right)->map);
8766:     }
8767:     if (left) {
8768:       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8769:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8770:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8771:       VecSetBlockSize(*left,rbs);
8772:       VecSetType(*left,VECSTANDARD);
8773:       PetscLayoutReference(mat->rmap,&(*left)->map);
8774:     }
8775:   }
8776:   return(0);
8777: }

8779: /*@C
8780:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8781:      with default values.

8783:    Not Collective

8785:    Input Parameters:
8786: .    info - the MatFactorInfo data structure


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

8792:    Level: developer

8794: .seealso: MatFactorInfo

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

8799: @*/

8801: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8802: {

8806:   PetscMemzero(info,sizeof(MatFactorInfo));
8807:   return(0);
8808: }

8810: /*@
8811:    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed

8813:    Collective on Mat

8815:    Input Parameters:
8816: +  mat - the factored matrix
8817: -  is - the index set defining the Schur indices (0-based)

8819:    Notes:  Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.

8821:    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.

8823:    Level: developer

8825:    Concepts:

8827: .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8828:           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()

8830: @*/
8831: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8832: {
8833:   PetscErrorCode ierr,(*f)(Mat,IS);

8841:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8842:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8843:   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");
8844:   if (mat->schur) {
8845:     MatDestroy(&mat->schur);
8846:   }
8847:   (*f)(mat,is);
8848:   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8849:   MatFactorSetUpInPlaceSchur_Private(mat);
8850:   return(0);
8851: }

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

8856:    Logically Collective on Mat

8858:    Input Parameters:
8859: +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8860: .  S - location where to return the Schur complement, can be NULL
8861: -  status - the status of the Schur complement matrix, can be NULL

8863:    Notes:
8864:    You must call MatFactorSetSchurIS() before calling this routine.

8866:    The routine provides a copy of the Schur matrix stored within the solver data structures.
8867:    The caller must destroy the object when it is no longer needed.
8868:    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.

8870:    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)

8872:    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
8873:    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 

8875:    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.

8877:    Level: advanced

8879:    References:

8881: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8882: @*/
8883: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8884: {

8891:   if (S) {
8892:     PetscErrorCode (*f)(Mat,Mat*);

8894:     PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);
8895:     if (f) {
8896:       (*f)(F,S);
8897:     } else {
8898:       MatDuplicate(F->schur,MAT_COPY_VALUES,S);
8899:     }
8900:   }
8901:   if (status) *status = F->schur_status;
8902:   return(0);
8903: }

8905: /*@
8906:   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix

8908:    Logically Collective on Mat

8910:    Input Parameters:
8911: +  F - the factored matrix obtained by calling MatGetFactor()
8912: .  *S - location where to return the Schur complement, can be NULL
8913: -  status - the status of the Schur complement matrix, can be NULL

8915:    Notes:
8916:    You must call MatFactorSetSchurIS() before calling this routine.

8918:    Schur complement mode is currently implemented for sequential matrices.
8919:    The routine returns a the Schur Complement stored within the data strutures of the solver.
8920:    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8921:    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.

8923:    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix

8925:    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.

8927:    Level: advanced

8929:    References:

8931: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8932: @*/
8933: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8934: {
8939:   if (S) *S = F->schur;
8940:   if (status) *status = F->schur_status;
8941:   return(0);
8942: }

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

8947:    Logically Collective on Mat

8949:    Input Parameters:
8950: +  F - the factored matrix obtained by calling MatGetFactor()
8951: .  *S - location where the Schur complement is stored
8952: -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)

8954:    Notes:

8956:    Level: advanced

8958:    References:

8960: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8961: @*/
8962: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8963: {

8968:   if (S) {
8970:     *S = NULL;
8971:   }
8972:   F->schur_status = status;
8973:   MatFactorUpdateSchurStatus_Private(F);
8974:   return(0);
8975: }

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

8980:    Logically Collective on Mat

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

8987:    Notes:
8988:    The sizes of the vectors should match the size of the Schur complement

8990:    Must be called after MatFactorSetSchurIS()

8992:    Level: advanced

8994:    References:

8996: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8997: @*/
8998: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8999: {

9011:   MatFactorFactorizeSchurComplement(F);
9012:   switch (F->schur_status) {
9013:   case MAT_FACTOR_SCHUR_FACTORED:
9014:     MatSolveTranspose(F->schur,rhs,sol);
9015:     break;
9016:   case MAT_FACTOR_SCHUR_INVERTED:
9017:     MatMultTranspose(F->schur,rhs,sol);
9018:     break;
9019:   default:
9020:     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9021:     break;
9022:   }
9023:   return(0);
9024: }

9026: /*@
9027:   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step

9029:    Logically Collective on Mat

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

9036:    Notes:
9037:    The sizes of the vectors should match the size of the Schur complement

9039:    Must be called after MatFactorSetSchurIS()

9041:    Level: advanced

9043:    References:

9045: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9046: @*/
9047: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9048: {

9060:   MatFactorFactorizeSchurComplement(F);
9061:   switch (F->schur_status) {
9062:   case MAT_FACTOR_SCHUR_FACTORED:
9063:     MatSolve(F->schur,rhs,sol);
9064:     break;
9065:   case MAT_FACTOR_SCHUR_INVERTED:
9066:     MatMult(F->schur,rhs,sol);
9067:     break;
9068:   default:
9069:     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9070:     break;
9071:   }
9072:   return(0);
9073: }

9075: /*@
9076:   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step

9078:    Logically Collective on Mat

9080:    Input Parameters:
9081: +  F - the factored matrix obtained by calling MatGetFactor()

9083:    Notes: Must be called after MatFactorSetSchurIS().

9085:    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.

9087:    Level: advanced

9089:    References:

9091: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9092: @*/
9093: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9094: {

9100:   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) return(0);
9101:   MatFactorFactorizeSchurComplement(F);
9102:   MatFactorInvertSchurComplement_Private(F);
9103:   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9104:   return(0);
9105: }

9107: /*@
9108:   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step

9110:    Logically Collective on Mat

9112:    Input Parameters:
9113: +  F - the factored matrix obtained by calling MatGetFactor()

9115:    Notes: Must be called after MatFactorSetSchurIS().

9117:    Level: advanced

9119:    References:

9121: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9122: @*/
9123: PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9124: {

9130:   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) return(0);
9131:   MatFactorFactorizeSchurComplement_Private(F);
9132:   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9133:   return(0);
9134: }

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

9139:    Neighbor-wise Collective on Mat

9141:    Input Parameters:
9142: +  A - the matrix
9143: .  P - the projection matrix
9144: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9145: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9146:           if the result is a dense matrix this is irrelevent

9148:    Output Parameters:
9149: .  C - the product matrix

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

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

9157:    Level: intermediate

9159: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9160: @*/
9161: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9162: {
9164:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9165:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9166:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9167:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

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

9175:   MatCheckPreallocated(A,1);
9176:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9177:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9178:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9181:   MatCheckPreallocated(P,2);
9182:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9183:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

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

9190:   if (scall == MAT_REUSE_MATRIX) {
9193:     if (viatranspose || viamatmatmatmult) {
9194:       Mat Pt;
9195:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9196:       if (viamatmatmatmult) {
9197:         MatMatMatMult(Pt,A,P,scall,fill,C);
9198:       } else {
9199:         Mat AP;
9200:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9201:         MatMatMult(Pt,AP,scall,fill,C);
9202:         MatDestroy(&AP);
9203:       }
9204:       MatDestroy(&Pt);
9205:     } else {
9206:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9207:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9208:       (*(*C)->ops->ptapnumeric)(A,P,*C);
9209:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9210:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9211:     }
9212:     return(0);
9213:   }

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

9218:   fA = A->ops->ptap;
9219:   fP = P->ops->ptap;
9220:   if (fP == fA) {
9221:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9222:     ptap = fA;
9223:   } else {
9224:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9225:     char ptapname[256];
9226:     PetscStrcpy(ptapname,"MatPtAP_");
9227:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
9228:     PetscStrcat(ptapname,"_");
9229:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
9230:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9231:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9232:     if (!ptap) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s (Misses composed function %s)",((PetscObject)A)->type_name,((PetscObject)P)->type_name,ptapname);
9233:   }

9235:   if (viatranspose || viamatmatmatmult) {
9236:     Mat Pt;
9237:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9238:     if (viamatmatmatmult) {
9239:       MatMatMatMult(Pt,A,P,scall,fill,C);
9240:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
9241:     } else {
9242:       Mat AP;
9243:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9244:       MatMatMult(Pt,AP,scall,fill,C);
9245:       MatDestroy(&AP);
9246:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
9247:     }
9248:     MatDestroy(&Pt);
9249:   } else {
9250:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9251:     (*ptap)(A,P,scall,fill,C);
9252:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9253:   }
9254:   return(0);
9255: }

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

9260:    Neighbor-wise Collective on Mat

9262:    Input Parameters:
9263: +  A - the matrix
9264: -  P - the projection matrix

9266:    Output Parameters:
9267: .  C - the product matrix

9269:    Notes:
9270:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9271:    the user using MatDeatroy().

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

9276:    Level: intermediate

9278: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9279: @*/
9280: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9281: {

9287:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9288:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9291:   MatCheckPreallocated(P,2);
9292:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9293:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9296:   MatCheckPreallocated(C,3);
9297:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9298:   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);
9299:   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);
9300:   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);
9301:   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);
9302:   MatCheckPreallocated(A,1);

9304:   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9305:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9306:   (*C->ops->ptapnumeric)(A,P,C);
9307:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9308:   return(0);
9309: }

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

9314:    Neighbor-wise Collective on Mat

9316:    Input Parameters:
9317: +  A - the matrix
9318: -  P - the projection matrix

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

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

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

9330:    Level: intermediate

9332: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9333: @*/
9334: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9335: {

9341:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9342:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9343:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9346:   MatCheckPreallocated(P,2);
9347:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9348:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9351:   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);
9352:   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);
9353:   MatCheckPreallocated(A,1);

9355:   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9356:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9357:   (*A->ops->ptapsymbolic)(A,P,fill,C);
9358:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

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

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

9367:    Neighbor-wise Collective on Mat

9369:    Input Parameters:
9370: +  A - the matrix
9371: .  R - the projection matrix
9372: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9373: -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9374:           if the result is a dense matrix this is irrelevent

9376:    Output Parameters:
9377: .  C - the product matrix

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

9382:    This routine is currently only implemented for pairs of AIJ matrices and classes
9383:    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9384:    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9385:    We recommend using MatPtAP().

9387:    Level: intermediate

9389: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9390: @*/
9391: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9392: {

9398:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9399:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9400:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9403:   MatCheckPreallocated(R,2);
9404:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9405:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9407:   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);

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

9413:   if (!A->ops->rart) {
9414:     Mat Rt;
9415:     MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);
9416:     MatMatMatMult(R,A,Rt,scall,fill,C);
9417:     MatDestroy(&Rt);
9418:     return(0);
9419:   }
9420:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
9421:   (*A->ops->rart)(A,R,scall,fill,C);
9422:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
9423:   return(0);
9424: }

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

9429:    Neighbor-wise Collective on Mat

9431:    Input Parameters:
9432: +  A - the matrix
9433: -  R - the projection matrix

9435:    Output Parameters:
9436: .  C - the product matrix

9438:    Notes:
9439:    C must have been created by calling MatRARtSymbolic and must be destroyed by
9440:    the user using MatDestroy().

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

9445:    Level: intermediate

9447: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9448: @*/
9449: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9450: {

9456:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9457:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9460:   MatCheckPreallocated(R,2);
9461:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9462:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9465:   MatCheckPreallocated(C,3);
9466:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9467:   if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
9468:   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9469:   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);
9470:   if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
9471:   MatCheckPreallocated(A,1);

9473:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
9474:   (*A->ops->rartnumeric)(A,R,C);
9475:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
9476:   return(0);
9477: }

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

9482:    Neighbor-wise Collective on Mat

9484:    Input Parameters:
9485: +  A - the matrix
9486: -  R - the projection matrix

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

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

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

9498:    Level: intermediate

9500: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9501: @*/
9502: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9503: {

9509:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9510:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9511:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9514:   MatCheckPreallocated(R,2);
9515:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9516:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9519:   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9520:   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);
9521:   MatCheckPreallocated(A,1);
9522:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9523:   (*A->ops->rartsymbolic)(A,R,fill,C);
9524:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

9526:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9527:   return(0);
9528: }

9530: /*@
9531:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

9533:    Neighbor-wise Collective on Mat

9535:    Input Parameters:
9536: +  A - the left matrix
9537: .  B - the right matrix
9538: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9539: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9540:           if the result is a dense matrix this is irrelevent

9542:    Output Parameters:
9543: .  C - the product matrix

9545:    Notes:
9546:    Unless scall is MAT_REUSE_MATRIX C will be created.

9548:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call and C was obtained from a previous
9549:    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()

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

9554:    If you have many matrices with the same non-zero structure to multiply, you
9555:    should either
9556: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9557: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9558:    In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine
9559:    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.

9561:    Level: intermediate

9563: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9564: @*/
9565: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9566: {
9568:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9569:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9570:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9575:   MatCheckPreallocated(A,1);
9576:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9577:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9580:   MatCheckPreallocated(B,2);
9581:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9582:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9584:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9585:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9586:   if (scall == MAT_REUSE_MATRIX) {
9589:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9590:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9591:     (*(*C)->ops->matmultnumeric)(A,B,*C);
9592:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9593:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9594:     return(0);
9595:   }
9596:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9597:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9599:   fA = A->ops->matmult;
9600:   fB = B->ops->matmult;
9601:   if (fB == fA) {
9602:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9603:     mult = fB;
9604:   } else {
9605:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9606:     char multname[256];
9607:     PetscStrcpy(multname,"MatMatMult_");
9608:     PetscStrcat(multname,((PetscObject)A)->type_name);
9609:     PetscStrcat(multname,"_");
9610:     PetscStrcat(multname,((PetscObject)B)->type_name);
9611:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9612:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9613:     if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9614:   }
9615:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9616:   (*mult)(A,B,scall,fill,C);
9617:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9618:   return(0);
9619: }

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

9625:    Neighbor-wise Collective on Mat

9627:    Input Parameters:
9628: +  A - the left matrix
9629: .  B - the right matrix
9630: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9631:       if C is a dense matrix this is irrelevent

9633:    Output Parameters:
9634: .  C - the product matrix

9636:    Notes:
9637:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

9642:    This routine is currently implemented for
9643:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9644:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9645:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9647:    Level: intermediate

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

9652: .seealso: MatMatMult(), MatMatMultNumeric()
9653: @*/
9654: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9655: {
9657:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9658:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9659:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

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

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

9674:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9675:   if (fill == PETSC_DEFAULT) fill = 2.0;
9676:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9677:   MatCheckPreallocated(A,1);

9679:   Asymbolic = A->ops->matmultsymbolic;
9680:   Bsymbolic = B->ops->matmultsymbolic;
9681:   if (Asymbolic == Bsymbolic) {
9682:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9683:     symbolic = Bsymbolic;
9684:   } else { /* dispatch based on the type of A and B */
9685:     char symbolicname[256];
9686:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9687:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9688:     PetscStrcat(symbolicname,"_");
9689:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9690:     PetscStrcat(symbolicname,"_C");
9691:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9692:     if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9693:   }
9694:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9695:   (*symbolic)(A,B,fill,C);
9696:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9697:   return(0);
9698: }

9700: /*@
9701:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9702:    Call this routine after first calling MatMatMultSymbolic().

9704:    Neighbor-wise Collective on Mat

9706:    Input Parameters:
9707: +  A - the left matrix
9708: -  B - the right matrix

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

9713:    Notes:
9714:    C must have been created with MatMatMultSymbolic().

9716:    This routine is currently implemented for
9717:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9718:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9719:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9721:    Level: intermediate

9723: .seealso: MatMatMult(), MatMatMultSymbolic()
9724: @*/
9725: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9726: {

9730:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9731:   return(0);
9732: }

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

9737:    Neighbor-wise Collective on Mat

9739:    Input Parameters:
9740: +  A - the left matrix
9741: .  B - the right matrix
9742: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9743: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9745:    Output Parameters:
9746: .  C - the product matrix

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

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

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

9756:    This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class.

9758:    Level: intermediate

9760: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9761: @*/
9762: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9763: {
9765:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9766:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

9771:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9772:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9773:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9776:   MatCheckPreallocated(B,2);
9777:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9778:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9780:   if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
9781:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9782:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9783:   MatCheckPreallocated(A,1);

9785:   fA = A->ops->mattransposemult;
9786:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9787:   fB = B->ops->mattransposemult;
9788:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9789:   if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);

9791:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9792:   if (scall == MAT_INITIAL_MATRIX) {
9793:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9794:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9795:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9796:   }
9797:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9798:   (*A->ops->mattransposemultnumeric)(A,B,*C);
9799:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9800:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9801:   return(0);
9802: }

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

9807:    Neighbor-wise Collective on Mat

9809:    Input Parameters:
9810: +  A - the left matrix
9811: .  B - the right matrix
9812: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9813: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9815:    Output Parameters:
9816: .  C - the product matrix

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

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

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

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

9829:    Level: intermediate

9831: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9832: @*/
9833: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9834: {
9836:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9837:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9838:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

9843:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9844:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9845:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9848:   MatCheckPreallocated(B,2);
9849:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9850:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9852:   if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
9853:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9854:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9855:   MatCheckPreallocated(A,1);

9857:   fA = A->ops->transposematmult;
9858:   fB = B->ops->transposematmult;
9859:   if (fB==fA) {
9860:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9861:     transposematmult = fA;
9862:   } else {
9863:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9864:     char multname[256];
9865:     PetscStrcpy(multname,"MatTransposeMatMult_");
9866:     PetscStrcat(multname,((PetscObject)A)->type_name);
9867:     PetscStrcat(multname,"_");
9868:     PetscStrcat(multname,((PetscObject)B)->type_name);
9869:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9870:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9871:     if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9872:   }
9873:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9874:   (*transposematmult)(A,B,scall,fill,C);
9875:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9876:   return(0);
9877: }

9879: /*@
9880:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

9882:    Neighbor-wise Collective on Mat

9884:    Input Parameters:
9885: +  A - the left matrix
9886: .  B - the middle matrix
9887: .  C - the right matrix
9888: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9889: -  fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate
9890:           if the result is a dense matrix this is irrelevent

9892:    Output Parameters:
9893: .  D - the product matrix

9895:    Notes:
9896:    Unless scall is MAT_REUSE_MATRIX D will be created.

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

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

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

9906:    Level: intermediate

9908: .seealso: MatMatMult, MatPtAP()
9909: @*/
9910: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9911: {
9913:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9914:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9915:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9916:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9921:   MatCheckPreallocated(A,1);
9922:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9923:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9924:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9927:   MatCheckPreallocated(B,2);
9928:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9929:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9932:   MatCheckPreallocated(C,3);
9933:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9934:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9935:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9936:   if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
9937:   if (scall == MAT_REUSE_MATRIX) {
9940:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9941:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9942:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9943:     return(0);
9944:   }
9945:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9946:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9948:   fA = A->ops->matmatmult;
9949:   fB = B->ops->matmatmult;
9950:   fC = C->ops->matmatmult;
9951:   if (fA == fB && fA == fC) {
9952:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9953:     mult = fA;
9954:   } else {
9955:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9956:     char multname[256];
9957:     PetscStrcpy(multname,"MatMatMatMult_");
9958:     PetscStrcat(multname,((PetscObject)A)->type_name);
9959:     PetscStrcat(multname,"_");
9960:     PetscStrcat(multname,((PetscObject)B)->type_name);
9961:     PetscStrcat(multname,"_");
9962:     PetscStrcat(multname,((PetscObject)C)->type_name);
9963:     PetscStrcat(multname,"_C");
9964:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9965:     if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9966:   }
9967:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9968:   (*mult)(A,B,C,scall,fill,D);
9969:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9970:   return(0);
9971: }

9973: /*@
9974:    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

9976:    Collective on Mat

9978:    Input Parameters:
9979: +  mat - the matrix
9980: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9981: .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9982: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9984:    Output Parameter:
9985: .  matredundant - redundant matrix

9987:    Notes:
9988:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9989:    original matrix has not changed from that last call to MatCreateRedundantMatrix().

9991:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9992:    calling it.

9994:    Level: advanced

9996:    Concepts: subcommunicator
9997:    Concepts: duplicate matrix

9999: .seealso: MatDestroy()
10000: @*/
10001: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10002: {
10004:   MPI_Comm       comm;
10005:   PetscMPIInt    size;
10006:   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10007:   Mat_Redundant  *redund=NULL;
10008:   PetscSubcomm   psubcomm=NULL;
10009:   MPI_Comm       subcomm_in=subcomm;
10010:   Mat            *matseq;
10011:   IS             isrow,iscol;
10012:   PetscBool      newsubcomm=PETSC_FALSE;

10016:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10019:   }

10021:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
10022:   if (size == 1 || nsubcomm == 1) {
10023:     if (reuse == MAT_INITIAL_MATRIX) {
10024:       MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
10025:     } else {
10026:       if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10027:       MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
10028:     }
10029:     return(0);
10030:   }

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

10036:   PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
10037:   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10038:     /* create psubcomm, then get subcomm */
10039:     PetscObjectGetComm((PetscObject)mat,&comm);
10040:     MPI_Comm_size(comm,&size);
10041:     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);

10043:     PetscSubcommCreate(comm,&psubcomm);
10044:     PetscSubcommSetNumber(psubcomm,nsubcomm);
10045:     PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
10046:     PetscSubcommSetFromOptions(psubcomm);
10047:     PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);
10048:     newsubcomm = PETSC_TRUE;
10049:     PetscSubcommDestroy(&psubcomm);
10050:   }

10052:   /* get isrow, iscol and a local sequential matrix matseq[0] */
10053:   if (reuse == MAT_INITIAL_MATRIX) {
10054:     mloc_sub = PETSC_DECIDE;
10055:     nloc_sub = PETSC_DECIDE;
10056:     if (bs < 1) {
10057:       PetscSplitOwnership(subcomm,&mloc_sub,&M);
10058:       PetscSplitOwnership(subcomm,&nloc_sub,&N);
10059:     } else {
10060:       PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
10061:       PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);
10062:     }
10063:     MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
10064:     rstart = rend - mloc_sub;
10065:     ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
10066:     ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
10067:   } else { /* reuse == MAT_REUSE_MATRIX */
10068:     if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10069:     /* retrieve subcomm */
10070:     PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
10071:     redund = (*matredundant)->redundant;
10072:     isrow  = redund->isrow;
10073:     iscol  = redund->iscol;
10074:     matseq = redund->matseq;
10075:   }
10076:   MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);

10078:   /* get matredundant over subcomm */
10079:   if (reuse == MAT_INITIAL_MATRIX) {
10080:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);

10082:     /* create a supporting struct and attach it to C for reuse */
10083:     PetscNewLog(*matredundant,&redund);
10084:     (*matredundant)->redundant = redund;
10085:     redund->isrow              = isrow;
10086:     redund->iscol              = iscol;
10087:     redund->matseq             = matseq;
10088:     if (newsubcomm) {
10089:       redund->subcomm          = subcomm;
10090:     } else {
10091:       redund->subcomm          = MPI_COMM_NULL;
10092:     }
10093:   } else {
10094:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
10095:   }
10096:   PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
10097:   return(0);
10098: }

10100: /*@C
10101:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10102:    a given 'mat' object. Each submatrix can span multiple procs.

10104:    Collective on Mat

10106:    Input Parameters:
10107: +  mat - the matrix
10108: .  subcomm - the subcommunicator obtained by com_split(comm)
10109: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

10111:    Output Parameter:
10112: .  subMat - 'parallel submatrices each spans a given subcomm

10114:   Notes:
10115:   The submatrix partition across processors is dictated by 'subComm' a
10116:   communicator obtained by com_split(comm). The comm_split
10117:   is not restriced to be grouped with consecutive original ranks.

10119:   Due the comm_split() usage, the parallel layout of the submatrices
10120:   map directly to the layout of the original matrix [wrt the local
10121:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10122:   into the 'DiagonalMat' of the subMat, hence it is used directly from
10123:   the subMat. However the offDiagMat looses some columns - and this is
10124:   reconstructed with MatSetValues()

10126:   Level: advanced

10128:   Concepts: subcommunicator
10129:   Concepts: submatrices

10131: .seealso: MatCreateSubMatrices()
10132: @*/
10133: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10134: {
10136:   PetscMPIInt    commsize,subCommSize;

10139:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
10140:   MPI_Comm_size(subComm,&subCommSize);
10141:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

10143:   if (scall == MAT_REUSE_MATRIX && *subMat == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10144:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
10145:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
10146:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
10147:   return(0);
10148: }

10150: /*@
10151:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

10153:    Not Collective

10155:    Input Arguments:
10156:    mat - matrix to extract local submatrix from
10157:    isrow - local row indices for submatrix
10158:    iscol - local column indices for submatrix

10160:    Output Arguments:
10161:    submat - the submatrix

10163:    Level: intermediate

10165:    Notes:
10166:    The submat should be returned with MatRestoreLocalSubMatrix().

10168:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10169:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

10171:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10172:    MatSetValuesBlockedLocal() will also be implemented.

10174:    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10175:    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.

10177: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10178: @*/
10179: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10180: {

10189:   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");

10191:   if (mat->ops->getlocalsubmatrix) {
10192:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
10193:   } else {
10194:     MatCreateLocalRef(mat,isrow,iscol,submat);
10195:   }
10196:   return(0);
10197: }

10199: /*@
10200:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

10202:    Not Collective

10204:    Input Arguments:
10205:    mat - matrix to extract local submatrix from
10206:    isrow - local row indices for submatrix
10207:    iscol - local column indices for submatrix
10208:    submat - the submatrix

10210:    Level: intermediate

10212: .seealso: MatGetLocalSubMatrix()
10213: @*/
10214: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10215: {

10224:   if (*submat) {
10226:   }

10228:   if (mat->ops->restorelocalsubmatrix) {
10229:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
10230:   } else {
10231:     MatDestroy(submat);
10232:   }
10233:   *submat = NULL;
10234:   return(0);
10235: }

10237: /* --------------------------------------------------------*/
10238: /*@
10239:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix

10241:    Collective on Mat

10243:    Input Parameter:
10244: .  mat - the matrix

10246:    Output Parameter:
10247: .  is - if any rows have zero diagonals this contains the list of them

10249:    Level: developer

10251:    Concepts: matrix-vector product

10253: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10254: @*/
10255: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10256: {

10262:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10263:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

10265:   if (!mat->ops->findzerodiagonals) {
10266:     Vec                diag;
10267:     const PetscScalar *a;
10268:     PetscInt          *rows;
10269:     PetscInt           rStart, rEnd, r, nrow = 0;

10271:     MatCreateVecs(mat, &diag, NULL);
10272:     MatGetDiagonal(mat, diag);
10273:     MatGetOwnershipRange(mat, &rStart, &rEnd);
10274:     VecGetArrayRead(diag, &a);
10275:     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10276:     PetscMalloc1(nrow, &rows);
10277:     nrow = 0;
10278:     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10279:     VecRestoreArrayRead(diag, &a);
10280:     VecDestroy(&diag);
10281:     ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);
10282:   } else {
10283:     (*mat->ops->findzerodiagonals)(mat, is);
10284:   }
10285:   return(0);
10286: }

10288: /*@
10289:    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)

10291:    Collective on Mat

10293:    Input Parameter:
10294: .  mat - the matrix

10296:    Output Parameter:
10297: .  is - contains the list of rows with off block diagonal entries

10299:    Level: developer

10301:    Concepts: matrix-vector product

10303: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10304: @*/
10305: PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10306: {

10312:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10313:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

10315:   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10316:   (*mat->ops->findoffblockdiagonalentries)(mat,is);
10317:   return(0);
10318: }

10320: /*@C
10321:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

10323:   Collective on Mat

10325:   Input Parameters:
10326: . mat - the matrix

10328:   Output Parameters:
10329: . values - the block inverses in column major order (FORTRAN-like)

10331:    Note:
10332:    This routine is not available from Fortran.

10334:   Level: advanced
10335: @*/
10336: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10337: {

10342:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10343:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10344:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10345:   (*mat->ops->invertblockdiagonal)(mat,values);
10346:   return(0);
10347: }

10349: /*@C
10350:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10351:     via MatTransposeColoringCreate().

10353:     Collective on MatTransposeColoring

10355:     Input Parameter:
10356: .   c - coloring context

10358:     Level: intermediate

10360: .seealso: MatTransposeColoringCreate()
10361: @*/
10362: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10363: {
10364:   PetscErrorCode       ierr;
10365:   MatTransposeColoring matcolor=*c;

10368:   if (!matcolor) return(0);
10369:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

10371:   PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
10372:   PetscFree(matcolor->rows);
10373:   PetscFree(matcolor->den2sp);
10374:   PetscFree(matcolor->colorforcol);
10375:   PetscFree(matcolor->columns);
10376:   if (matcolor->brows>0) {
10377:     PetscFree(matcolor->lstart);
10378:   }
10379:   PetscHeaderDestroy(c);
10380:   return(0);
10381: }

10383: /*@C
10384:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10385:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10386:     MatTransposeColoring to sparse B.

10388:     Collective on MatTransposeColoring

10390:     Input Parameters:
10391: +   B - sparse matrix B
10392: .   Btdense - symbolic dense matrix B^T
10393: -   coloring - coloring context created with MatTransposeColoringCreate()

10395:     Output Parameter:
10396: .   Btdense - dense matrix B^T

10398:     Level: advanced

10400:      Notes: These are used internally for some implementations of MatRARt()

10402: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()

10404: .keywords: coloring
10405: @*/
10406: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10407: {


10415:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10416:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
10417:   return(0);
10418: }

10420: /*@C
10421:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10422:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10423:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10424:     Csp from Cden.

10426:     Collective on MatTransposeColoring

10428:     Input Parameters:
10429: +   coloring - coloring context created with MatTransposeColoringCreate()
10430: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

10432:     Output Parameter:
10433: .   Csp - sparse matrix

10435:     Level: advanced

10437:      Notes: These are used internally for some implementations of MatRARt()

10439: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

10441: .keywords: coloring
10442: @*/
10443: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10444: {


10452:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10453:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
10454:   return(0);
10455: }

10457: /*@C
10458:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

10460:    Collective on Mat

10462:    Input Parameters:
10463: +  mat - the matrix product C
10464: -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()

10466:     Output Parameter:
10467: .   color - the new coloring context

10469:     Level: intermediate

10471: .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10472:            MatTransColoringApplyDenToSp()
10473: @*/
10474: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10475: {
10476:   MatTransposeColoring c;
10477:   MPI_Comm             comm;
10478:   PetscErrorCode       ierr;

10481:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
10482:   PetscObjectGetComm((PetscObject)mat,&comm);
10483:   PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);

10485:   c->ctype = iscoloring->ctype;
10486:   if (mat->ops->transposecoloringcreate) {
10487:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
10488:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

10490:   *color = c;
10491:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
10492:   return(0);
10493: }

10495: /*@
10496:       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10497:         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10498:         same, otherwise it will be larger

10500:      Not Collective

10502:   Input Parameter:
10503: .    A  - the matrix

10505:   Output Parameter:
10506: .    state - the current state

10508:   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10509:          different matrices

10511:   Level: intermediate

10513: @*/
10514: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10515: {
10518:   *state = mat->nonzerostate;
10519:   return(0);
10520: }

10522: /*@
10523:       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10524:                  matrices from each processor

10526:     Collective on MPI_Comm

10528:    Input Parameters:
10529: +    comm - the communicators the parallel matrix will live on
10530: .    seqmat - the input sequential matrices
10531: .    n - number of local columns (or PETSC_DECIDE)
10532: -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

10534:    Output Parameter:
10535: .    mpimat - the parallel matrix generated

10537:     Level: advanced

10539:    Notes: The number of columns of the matrix in EACH processor MUST be the same.

10541: @*/
10542: PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10543: {

10547:   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10548:   if (reuse == MAT_REUSE_MATRIX && seqmat == *mpimat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");

10550:   PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);
10551:   (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);
10552:   PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);
10553:   return(0);
10554: }

10556: /*@
10557:      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10558:                  ranks' ownership ranges.

10560:     Collective on A

10562:    Input Parameters:
10563: +    A   - the matrix to create subdomains from
10564: -    N   - requested number of subdomains


10567:    Output Parameters:
10568: +    n   - number of subdomains resulting on this rank
10569: -    iss - IS list with indices of subdomains on this rank

10571:     Level: advanced

10573:     Notes: number of subdomains must be smaller than the communicator size
10574: @*/
10575: PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10576: {
10577:   MPI_Comm        comm,subcomm;
10578:   PetscMPIInt     size,rank,color;
10579:   PetscInt        rstart,rend,k;
10580:   PetscErrorCode  ierr;

10583:   PetscObjectGetComm((PetscObject)A,&comm);
10584:   MPI_Comm_size(comm,&size);
10585:   MPI_Comm_rank(comm,&rank);
10586:   if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N);
10587:   *n = 1;
10588:   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10589:   color = rank/k;
10590:   MPI_Comm_split(comm,color,rank,&subcomm);
10591:   PetscMalloc1(1,iss);
10592:   MatGetOwnershipRange(A,&rstart,&rend);
10593:   ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);
10594:   MPI_Comm_free(&subcomm);
10595:   return(0);
10596: }

10598: /*@
10599:    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.

10601:    If the interpolation and restriction operators are the same, uses MatPtAP.
10602:    If they are not the same, use MatMatMatMult.

10604:    Once the coarse grid problem is constructed, correct for interpolation operators
10605:    that are not of full rank, which can legitimately happen in the case of non-nested
10606:    geometric multigrid.

10608:    Input Parameters:
10609: +  restrct - restriction operator
10610: .  dA - fine grid matrix
10611: .  interpolate - interpolation operator
10612: .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10613: -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate

10615:    Output Parameters:
10616: .  A - the Galerkin coarse matrix

10618:    Options Database Key:
10619: .  -pc_mg_galerkin <both,pmat,mat,none>

10621:    Level: developer

10623: .keywords: MG, multigrid, Galerkin

10625: .seealso: MatPtAP(), MatMatMatMult()
10626: @*/
10627: PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10628: {
10630:   IS             zerorows;
10631:   Vec            diag;

10634:   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10635:   /* Construct the coarse grid matrix */
10636:   if (interpolate == restrct) {
10637:     MatPtAP(dA,interpolate,reuse,fill,A);
10638:   } else {
10639:     MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);
10640:   }

10642:   /* If the interpolation matrix is not of full rank, A will have zero rows.
10643:      This can legitimately happen in the case of non-nested geometric multigrid.
10644:      In that event, we set the rows of the matrix to the rows of the identity,
10645:      ignoring the equations (as the RHS will also be zero). */

10647:   MatFindZeroRows(*A, &zerorows);

10649:   if (zerorows != NULL) { /* if there are any zero rows */
10650:     MatCreateVecs(*A, &diag, NULL);
10651:     MatGetDiagonal(*A, diag);
10652:     VecISSet(diag, zerorows, 1.0);
10653:     MatDiagonalSet(*A, diag, INSERT_VALUES);
10654:     VecDestroy(&diag);
10655:     ISDestroy(&zerorows);
10656:   }
10657:   return(0);
10658: }