Actual source code: matrix.c

petsc-3.6.4 2016-04-12
Report Typos and Errors
  2: /*
  3:    This is where the abstract matrix operations are defined
  4: */

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

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

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

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

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

 47:    Logically Collective on Vec

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

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

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

 64:    Level: intermediate

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

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


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

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

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


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

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

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

110:   Level: intermediate

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

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

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

131:    Not Collective

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

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

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

143:    Level: advanced

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

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

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

176:    Collective on Mat

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

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

184:    Level: advanced

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

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

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

205:    Logically Collective on Mat

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

210:    Level: advanced


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

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

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

245:    Collective on Mat

247:    Input Parameter:
248: .  mat - the matrix

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

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

256:    Level: advanced

258: @*/
259: PetscErrorCode  MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
260: {

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


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

283:    Logically Collective on Mat

285:    Input Parameters:
286: .  mat - the matrix

288:    Level: advanced


291: .seealso: MatRealPart()
292: @*/
293: PetscErrorCode  MatImaginaryPart(Mat mat)
294: {

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

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

323:    Collective on Mat

325:    Input Parameter:
326: .  mat - the matrix

328:    Output Parameters:
329: +  missing - is any diagonal missing
330: -  dd - first diagonal entry that is missing (optional)

332:    Level: advanced


335: .seealso: MatRealPart()
336: @*/
337: PetscErrorCode  MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
338: {

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

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

358:    Not Collective

360:    Input Parameters:
361: +  mat - the matrix
362: -  row - the row to get

364:    Output Parameters:
365: +  ncols -  if not NULL, the number of nonzeros in the row
366: .  cols - if not NULL, the column numbers
367: -  vals - if not NULL, the values

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

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

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

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

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

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


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

408:    Level: advanced

410:    Concepts: matrices^row access

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

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

435: /*@
436:    MatConjugate - replaces the matrix values with their complex conjugates

438:    Logically Collective on Mat

440:    Input Parameters:
441: .  mat - the matrix

443:    Level: advanced

445: .seealso:  VecConjugate()
446: @*/
447: PetscErrorCode  MatConjugate(Mat mat)
448: {
449: #if defined(PETSC_USE_COMPLEX)

454:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
455:   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");
456:   (*mat->ops->conjugate)(mat);
457: #if defined(PETSC_HAVE_CUSP)
458:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
459:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
460:   }
461: #endif
462: #if defined(PETSC_HAVE_VIENNACL)
463:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
464:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
465:   }
466: #endif
467:   return(0);
468: #else
469:   return 0;
470: #endif
471: }

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

478:    Not Collective

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

486:    Notes:
487:    This routine should be called after you have finished examining the entries.

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

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

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

508:    Level: advanced

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

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

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

534:    Not Collective

536:    Input Parameters:
537: +  mat - the matrix

539:    Notes:
540:    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.

542:    Level: advanced

544:    Concepts: matrices^row access

546: .seealso: MatRestoreRowRowUpperTriangular()
547: @*/
548: PetscErrorCode  MatGetRowUpperTriangular(Mat mat)
549: {

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

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

568:    Not Collective

570:    Input Parameters:
571: +  mat - the matrix

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


577:    Level: advanced

579: .seealso:  MatGetRowUpperTriangular()
580: @*/
581: PetscErrorCode  MatRestoreRowUpperTriangular(Mat mat)
582: {

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

595: /*@C
596:    MatSetOptionsPrefix - Sets the prefix used for searching for all
597:    Mat options in the database.

599:    Logically Collective on Mat

601:    Input Parameter:
602: +  A - the Mat context
603: -  prefix - the prefix to prepend to all option names

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

609:    Level: advanced

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

613: .seealso: MatSetFromOptions()
614: @*/
615: PetscErrorCode  MatSetOptionsPrefix(Mat A,const char prefix[])
616: {

621:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
622:   return(0);
623: }

627: /*@C
628:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
629:    Mat options in the database.

631:    Logically Collective on Mat

633:    Input Parameters:
634: +  A - the Mat context
635: -  prefix - the prefix to prepend to all option names

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

641:    Level: advanced

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

645: .seealso: MatGetOptionsPrefix()
646: @*/
647: PetscErrorCode  MatAppendOptionsPrefix(Mat A,const char prefix[])
648: {

653:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
654:   return(0);
655: }

659: /*@C
660:    MatGetOptionsPrefix - Sets the prefix used for searching for all
661:    Mat options in the database.

663:    Not Collective

665:    Input Parameter:
666: .  A - the Mat context

668:    Output Parameter:
669: .  prefix - pointer to the prefix string used

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

674:    Level: advanced

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

678: .seealso: MatAppendOptionsPrefix()
679: @*/
680: PetscErrorCode  MatGetOptionsPrefix(Mat A,const char *prefix[])
681: {

686:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
687:   return(0);
688: }

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

695:    Collective on Mat

697:    Input Parameters:
698: .  A - the Mat context

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

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

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

707:    Level: beginner

709: .keywords: Mat, setup

711: .seealso: MatCreate(), MatDestroy()
712: @*/
713: PetscErrorCode  MatSetUp(Mat A)
714: {
715:   PetscMPIInt    size;

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

736: #if defined(PETSC_HAVE_SAWS)
737: #include <petscviewersaws.h>
738: #endif
741: /*@C
742:    MatView - Visualizes a matrix object.

744:    Collective on Mat

746:    Input Parameters:
747: +  mat - the matrix
748: -  viewer - visualization context

750:   Notes:
751:   The available visualization contexts include
752: +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
753: .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
754: .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
755: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

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

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

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

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

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

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

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

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

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

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

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

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

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

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

921:    Collective on PetscViewer

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

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

933:    Level: beginner

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1054:    Collective on Mat

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

1059:    Level: beginner

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

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

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

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

1093:    Not Collective

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

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

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

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

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

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

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

1126:    Level: beginner

1128:    Concepts: matrices^putting entries in

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

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

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

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


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

1195:    Not Collective

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

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

1205:    All the nonzeros in the row must be provided

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

1209:    The row must belong to this process

1211:    Level: intermediate

1213:    Concepts: matrices^putting entries in

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

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

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

1248:    Not Collective

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

1255:    Notes:
1256:    The values, v, are column-oriented for the block version.

1258:    All the nonzeros in the row must be provided

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

1262:    The row must belong to this process

1264:    Level: advanced

1266:    Concepts: matrices^putting entries in

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

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

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

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

1313:    Not Collective

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

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

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

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

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

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

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

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

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

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

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

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

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

1373:    Level: beginner

1375:    Concepts: matrices^putting entries in

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

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

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

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

1432:    Not Collective

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

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

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

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

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

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

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

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

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

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

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

1485:    Level: beginner

1487:    Concepts: matrices^putting entries in

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

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

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

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

1555:    Not Collective

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


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

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

1571:    Level: beginner

1573:    Concepts: matrices^putting entries in

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


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

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

1603:    Not Collective

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

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

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

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

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

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

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

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

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

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

1663:    Level: intermediate

1665:    Concepts: matrices^putting entries in blocked

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

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

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

1736: /*@
1737:    MatGetValues - Gets a block of values from a matrix.

1739:    Not Collective; currently only returns a local block

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

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

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

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

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

1763:    Level: advanced

1765:    Concepts: matrices^accessing values

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

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

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

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

1797:   Not Collective

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

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

1809:   Level: advanced

1811:   Concepts: matrices^putting entries in

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

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

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

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

1849:    Not Collective

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

1856:    Level: intermediate

1858:    Concepts: matrices^local to global mapping
1859:    Concepts: local to global mapping^for matrices

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


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


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

1888:    Not Collective

1890:    Input Parameters:
1891: .  A - the matrix

1893:    Output Parameters:
1894: + rmapping - row mapping
1895: - cmapping - column mapping

1897:    Level: advanced

1899:    Concepts: matrices^local to global mapping
1900:    Concepts: local to global mapping^for matrices

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

1918: /*@
1919:    MatGetLayouts - Gets the PetscLayout objects for rows and columns

1921:    Not Collective

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

1926:    Output Parameters:
1927: + rmap - row layout
1928: - cmap - column layout

1930:    Level: advanced

1932: .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
1933: @*/
1934: PetscErrorCode  MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1935: {
1941:   if (rmap) *rmap = A->rmap;
1942:   if (cmap) *cmap = A->cmap;
1943:   return(0);
1944: }

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

1952:    Not Collective

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

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

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

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

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

1976:    Level: intermediate

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

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

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

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

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

2044:    Not Collective

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

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

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

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

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

2069:    Level: intermediate

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

2073: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2074:            MatSetValuesLocal(),  MatSetValuesBlocked()
2075: @*/
2076: PetscErrorCode  MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2077: {

2083:   MatCheckPreallocated(mat,1);
2084:   if (!nrow || !ncol) return(0); /* no values to insert */
2088:   if (mat->insertmode == NOT_SET_VALUES) {
2089:     mat->insertmode = addv;
2090:   }
2091: #if defined(PETSC_USE_DEBUG)
2092:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2093:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2094:   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);
2095: #endif

2097:   if (mat->assembled) {
2098:     mat->was_assembled = PETSC_TRUE;
2099:     mat->assembled     = PETSC_FALSE;
2100:   }
2101:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2102:   if (mat->ops->setvaluesblockedlocal) {
2103:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2104:   } else {
2105:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2106:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2107:       irowm = buf; icolm = buf + nrow;
2108:     } else {
2109:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2110:       irowm = bufr; icolm = bufc;
2111:     }
2112:     ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2113:     ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2114:     MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2115:     PetscFree2(bufr,bufc);
2116:   }
2117:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2118: #if defined(PETSC_HAVE_CUSP)
2119:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2120:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2121:   }
2122: #endif
2123: #if defined(PETSC_HAVE_VIENNACL)
2124:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2125:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2126:   }
2127: #endif
2128:   return(0);
2129: }

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

2136:    Collective on Mat and Vec

2138:    Input Parameters:
2139: +  mat - the matrix
2140: -  x   - the vector to be multiplied

2142:    Output Parameters:
2143: .  y - the result

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

2149:    Level: developer

2151:    Concepts: matrix-vector product

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


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

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

2176: /* --------------------------------------------------------*/
2179: /*@
2180:    MatMult - Computes the matrix-vector product, y = Ax.

2182:    Neighbor-wise Collective on Mat and Vec

2184:    Input Parameters:
2185: +  mat - the matrix
2186: -  x   - the vector to be multiplied

2188:    Output Parameters:
2189: .  y - the result

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

2195:    Level: beginner

2197:    Concepts: matrix-vector product

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

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

2222:   VecLockPush(x);
2223:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2224:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2225:   (*mat->ops->mult)(mat,x,y);
2226:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2227:   if (mat->erroriffpe) {VecValidValues(y,3,PETSC_FALSE);}
2228:   VecLockPop(x);
2229:   return(0);
2230: }

2234: /*@
2235:    MatMultTranspose - Computes matrix transpose times a vector.

2237:    Neighbor-wise Collective on Mat and Vec

2239:    Input Parameters:
2240: +  mat - the matrix
2241: -  x   - the vector to be multilplied

2243:    Output Parameters:
2244: .  y - the result

2246:    Notes:
2247:    The vectors x and y cannot be the same.  I.e., one cannot
2248:    call MatMultTranspose(A,y,y).

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

2253:    Level: beginner

2255:    Concepts: matrix vector product^transpose

2257: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2258: @*/
2259: PetscErrorCode  MatMultTranspose(Mat mat,Vec x,Vec y)
2260: {


2269:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2270:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2271:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2272: #if !defined(PETSC_HAVE_CONSTRAINTS)
2273:   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);
2274:   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);
2275: #endif
2276:   if (mat->erroriffpe) {VecValidValues(x,2,PETSC_TRUE);}
2277:   MatCheckPreallocated(mat,1);

2279:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2280:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2281:   VecLockPush(x);
2282:   (*mat->ops->multtranspose)(mat,x,y);
2283:   VecLockPop(x);
2284:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2285:   PetscObjectStateIncrease((PetscObject)y);
2286:   if (mat->erroriffpe) {VecValidValues(y,3,PETSC_FALSE);}
2287:   return(0);
2288: }

2292: /*@
2293:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2295:    Neighbor-wise Collective on Mat and Vec

2297:    Input Parameters:
2298: +  mat - the matrix
2299: -  x   - the vector to be multilplied

2301:    Output Parameters:
2302: .  y - the result

2304:    Notes:
2305:    The vectors x and y cannot be the same.  I.e., one cannot
2306:    call MatMultHermitianTranspose(A,y,y).

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

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

2312:    Level: beginner

2314:    Concepts: matrix vector product^transpose

2316: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2317: @*/
2318: PetscErrorCode  MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2319: {
2321:   Vec            w;


2329:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2330:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2331:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2332: #if !defined(PETSC_HAVE_CONSTRAINTS)
2333:   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);
2334:   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);
2335: #endif
2336:   MatCheckPreallocated(mat,1);

2338:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2339:   if (mat->ops->multhermitiantranspose) {
2340:     VecLockPush(x);
2341:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2342:     VecLockPop(x);
2343:   } else {
2344:     VecDuplicate(x,&w);
2345:     VecCopy(x,w);
2346:     VecConjugate(w);
2347:     MatMultTranspose(mat,w,y);
2348:     VecDestroy(&w);
2349:     VecConjugate(y);
2350:   }
2351:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2352:   PetscObjectStateIncrease((PetscObject)y);
2353:   return(0);
2354: }

2358: /*@
2359:     MatMultAdd -  Computes v3 = v2 + A * v1.

2361:     Neighbor-wise Collective on Mat and Vec

2363:     Input Parameters:
2364: +   mat - the matrix
2365: -   v1, v2 - the vectors

2367:     Output Parameters:
2368: .   v3 - the result

2370:     Notes:
2371:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2372:     call MatMultAdd(A,v1,v2,v1).

2374:     Level: beginner

2376:     Concepts: matrix vector product^addition

2378: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2379: @*/
2380: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2381: {


2391:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2392:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2393:   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);
2394:   /* 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);
2395:      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); */
2396:   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);
2397:   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);
2398:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2399:   MatCheckPreallocated(mat,1);

2401:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2402:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2403:   VecLockPush(v1);
2404:   (*mat->ops->multadd)(mat,v1,v2,v3);
2405:   VecLockPop(v1);
2406:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2407:   PetscObjectStateIncrease((PetscObject)v3);
2408:   return(0);
2409: }

2413: /*@
2414:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2416:    Neighbor-wise Collective on Mat and Vec

2418:    Input Parameters:
2419: +  mat - the matrix
2420: -  v1, v2 - the vectors

2422:    Output Parameters:
2423: .  v3 - the result

2425:    Notes:
2426:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2427:    call MatMultTransposeAdd(A,v1,v2,v1).

2429:    Level: beginner

2431:    Concepts: matrix vector product^transpose and addition

2433: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2434: @*/
2435: PetscErrorCode  MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2436: {


2446:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2447:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2448:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2449:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2450:   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);
2451:   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);
2452:   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);
2453:   MatCheckPreallocated(mat,1);

2455:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2456:   VecLockPush(v1);
2457:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2458:   VecLockPop(v1);
2459:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2460:   PetscObjectStateIncrease((PetscObject)v3);
2461:   return(0);
2462: }

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

2469:    Neighbor-wise Collective on Mat and Vec

2471:    Input Parameters:
2472: +  mat - the matrix
2473: -  v1, v2 - the vectors

2475:    Output Parameters:
2476: .  v3 - the result

2478:    Notes:
2479:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2480:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2482:    Level: beginner

2484:    Concepts: matrix vector product^transpose and addition

2486: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2487: @*/
2488: PetscErrorCode  MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2489: {


2499:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2500:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2501:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2502:   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);
2503:   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);
2504:   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);
2505:   MatCheckPreallocated(mat,1);

2507:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2508:   VecLockPush(v1);
2509:   if (mat->ops->multhermitiantransposeadd) {
2510:     (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2511:    } else {
2512:     Vec w,z;
2513:     VecDuplicate(v1,&w);
2514:     VecCopy(v1,w);
2515:     VecConjugate(w);
2516:     VecDuplicate(v3,&z);
2517:     MatMultTranspose(mat,w,z);
2518:     VecDestroy(&w);
2519:     VecConjugate(z);
2520:     VecWAXPY(v3,1.0,v2,z);
2521:     VecDestroy(&z);
2522:   }
2523:   VecLockPop(v1);
2524:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2525:   PetscObjectStateIncrease((PetscObject)v3);
2526:   return(0);
2527: }

2531: /*@
2532:    MatMultConstrained - The inner multiplication routine for a
2533:    constrained matrix P^T A P.

2535:    Neighbor-wise Collective on Mat and Vec

2537:    Input Parameters:
2538: +  mat - the matrix
2539: -  x   - the vector to be multilplied

2541:    Output Parameters:
2542: .  y - the result

2544:    Notes:
2545:    The vectors x and y cannot be the same.  I.e., one cannot
2546:    call MatMult(A,y,y).

2548:    Level: beginner

2550: .keywords: matrix, multiply, matrix-vector product, constraint
2551: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2552: @*/
2553: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
2554: {

2561:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2562:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2563:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2564:   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);
2565:   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);
2566:   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);

2568:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2569:   VecLockPush(x);
2570:   (*mat->ops->multconstrained)(mat,x,y);
2571:   VecLockPop(x);
2572:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2573:   PetscObjectStateIncrease((PetscObject)y);
2574:   return(0);
2575: }

2579: /*@
2580:    MatMultTransposeConstrained - The inner multiplication routine for a
2581:    constrained matrix P^T A^T P.

2583:    Neighbor-wise Collective on Mat and Vec

2585:    Input Parameters:
2586: +  mat - the matrix
2587: -  x   - the vector to be multilplied

2589:    Output Parameters:
2590: .  y - the result

2592:    Notes:
2593:    The vectors x and y cannot be the same.  I.e., one cannot
2594:    call MatMult(A,y,y).

2596:    Level: beginner

2598: .keywords: matrix, multiply, matrix-vector product, constraint
2599: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2600: @*/
2601: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2602: {

2609:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2610:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2611:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2612:   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);
2613:   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);

2615:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2616:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2617:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2618:   PetscObjectStateIncrease((PetscObject)y);
2619:   return(0);
2620: }

2624: /*@C
2625:    MatGetFactorType - gets the type of factorization it is

2627:    Note Collective
2628:    as the flag

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

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

2636:     Level: intermediate

2638: .seealso:    MatFactorType, MatGetFactor()
2639: @*/
2640: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
2641: {
2645:   *t = mat->factortype;
2646:   return(0);
2647: }

2649: /* ------------------------------------------------------------*/
2652: /*@C
2653:    MatGetInfo - Returns information about matrix storage (number of
2654:    nonzeros, memory, etc.).

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

2658:    Input Parameters:
2659: .  mat - the matrix

2661:    Output Parameters:
2662: +  flag - flag indicating the type of parameters to be returned
2663:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2664:    MAT_GLOBAL_SUM - sum over all processors)
2665: -  info - matrix information context

2667:    Notes:
2668:    The MatInfo context contains a variety of matrix data, including
2669:    number of nonzeros allocated and used, number of mallocs during
2670:    matrix assembly, etc.  Additional information for factored matrices
2671:    is provided (such as the fill ratio, number of mallocs during
2672:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2673:    when using the runtime options
2674: $       -info -mat_view ::ascii_info

2676:    Example for C/C++ Users:
2677:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2678:    data within the MatInfo context.  For example,
2679: .vb
2680:       MatInfo info;
2681:       Mat     A;
2682:       double  mal, nz_a, nz_u;

2684:       MatGetInfo(A,MAT_LOCAL,&info);
2685:       mal  = info.mallocs;
2686:       nz_a = info.nz_allocated;
2687: .ve

2689:    Example for Fortran Users:
2690:    Fortran users should declare info as a double precision
2691:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2692:    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2693:    a complete list of parameter names.
2694: .vb
2695:       double  precision info(MAT_INFO_SIZE)
2696:       double  precision mal, nz_a
2697:       Mat     A
2698:       integer ierr

2700:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2701:       mal = info(MAT_INFO_MALLOCS)
2702:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2703: .ve

2705:     Level: intermediate

2707:     Concepts: matrices^getting information on

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

2712: .seealso: MatStashGetInfo()

2714: @*/
2715: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2716: {

2723:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2724:   MatCheckPreallocated(mat,1);
2725:   (*mat->ops->getinfo)(mat,flag,info);
2726:   return(0);
2727: }

2729: /* ----------------------------------------------------------*/

2733: /*@C
2734:    MatLUFactor - Performs in-place LU factorization of matrix.

2736:    Collective on Mat

2738:    Input Parameters:
2739: +  mat - the matrix
2740: .  row - row permutation
2741: .  col - column permutation
2742: -  info - options for factorization, includes
2743: $          fill - expected fill as ratio of original fill.
2744: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2745: $                   Run with the option -info to determine an optimal value to use

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

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

2755:    Level: developer

2757:    Concepts: matrices^LU factorization

2759: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2760:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2765: @*/
2766: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2767: {
2769:   MatFactorInfo  tinfo;

2777:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2778:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2779:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2780:   MatCheckPreallocated(mat,1);
2781:   if (!info) {
2782:     MatFactorInfoInitialize(&tinfo);
2783:     info = &tinfo;
2784:   }

2786:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2787:   (*mat->ops->lufactor)(mat,row,col,info);
2788:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2789:   PetscObjectStateIncrease((PetscObject)mat);
2790:   return(0);
2791: }

2795: /*@C
2796:    MatILUFactor - Performs in-place ILU factorization of matrix.

2798:    Collective on Mat

2800:    Input Parameters:
2801: +  mat - the matrix
2802: .  row - row permutation
2803: .  col - column permutation
2804: -  info - structure containing
2805: $      levels - number of levels of fill.
2806: $      expected fill - as ratio of original fill.
2807: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2808:                 missing diagonal entries)

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

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

2818:    Level: developer

2820:    Concepts: matrices^ILU factorization

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

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

2827: @*/
2828: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2829: {

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

2844:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2845:   (*mat->ops->ilufactor)(mat,row,col,info);
2846:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2847:   PetscObjectStateIncrease((PetscObject)mat);
2848:   return(0);
2849: }

2853: /*@C
2854:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2855:    Call this routine before calling MatLUFactorNumeric().

2857:    Collective on Mat

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


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

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:    Level: developer

2877:    Concepts: matrices^LU symbolic factorization

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

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

2884: @*/
2885: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2886: {

2896:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2897:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2898:   if (!(fact)->ops->lufactorsymbolic) {
2899:     const MatSolverPackage spackage;
2900:     MatFactorGetSolverPackage(fact,&spackage);
2901:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2902:   }
2903:   MatCheckPreallocated(mat,2);

2905:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2906:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2907:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2908:   PetscObjectStateIncrease((PetscObject)fact);
2909:   return(0);
2910: }

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

2918:    Collective on Mat

2920:    Input Parameters:
2921: +  fact - the factor matrix obtained with MatGetFactor()
2922: .  mat - the matrix
2923: -  info - options for factorization

2925:    Notes:
2926:    See MatLUFactor() for in-place factorization.  See
2927:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

2933:    Level: developer

2935:    Concepts: matrices^LU numeric factorization

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

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

2942: @*/
2943: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2944: {

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

2955:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2956:   MatCheckPreallocated(mat,2);
2957:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2958:   (fact->ops->lufactornumeric)(fact,mat,info);
2959:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2960:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
2961:   PetscObjectStateIncrease((PetscObject)fact);
2962:   return(0);
2963: }

2967: /*@C
2968:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2969:    symmetric matrix.

2971:    Collective on Mat

2973:    Input Parameters:
2974: +  mat - the matrix
2975: .  perm - row and column permutations
2976: -  f - expected fill as ratio of original fill

2978:    Notes:
2979:    See MatLUFactor() for the nonsymmetric case.  See also
2980:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

2986:    Level: developer

2988:    Concepts: matrices^Cholesky factorization

2990: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2991:           MatGetOrdering()

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

2996: @*/
2997: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2998: {

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

3012:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3013:   (*mat->ops->choleskyfactor)(mat,perm,info);
3014:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3015:   PetscObjectStateIncrease((PetscObject)mat);
3016:   return(0);
3017: }

3021: /*@C
3022:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3023:    of a symmetric matrix.

3025:    Collective on Mat

3027:    Input Parameters:
3028: +  fact - the factor matrix obtained with MatGetFactor()
3029: .  mat - the matrix
3030: .  perm - row and column permutations
3031: -  info - options for factorization, includes
3032: $          fill - expected fill as ratio of original fill.
3033: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3034: $                   Run with the option -info to determine an optimal value to use

3036:    Notes:
3037:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3038:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

3044:    Level: developer

3046:    Concepts: matrices^Cholesky symbolic factorization

3048: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3049:           MatGetOrdering()

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

3054: @*/
3055: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3056: {

3065:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3066:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3067:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3068:   if (!(fact)->ops->choleskyfactorsymbolic) {
3069:     const MatSolverPackage spackage;
3070:     MatFactorGetSolverPackage(fact,&spackage);
3071:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3072:   }
3073:   MatCheckPreallocated(mat,2);

3075:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3076:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3077:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3078:   PetscObjectStateIncrease((PetscObject)fact);
3079:   return(0);
3080: }

3084: /*@C
3085:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3086:    of a symmetric matrix. Call this routine after first calling
3087:    MatCholeskyFactorSymbolic().

3089:    Collective on Mat

3091:    Input Parameters:
3092: +  fact - the factor matrix obtained with MatGetFactor()
3093: .  mat - the initial matrix
3094: .  info - options for factorization
3095: -  fact - the symbolic factor of mat


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

3103:    Level: developer

3105:    Concepts: matrices^Cholesky numeric factorization

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

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

3112: @*/
3113: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3114: {

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

3127:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3128:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3129:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3130:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3131:   PetscObjectStateIncrease((PetscObject)fact);
3132:   return(0);
3133: }

3135: /* ----------------------------------------------------------------*/
3138: /*@
3139:    MatSolve - Solves A x = b, given a factored matrix.

3141:    Neighbor-wise Collective on Mat and Vec

3143:    Input Parameters:
3144: +  mat - the factored matrix
3145: -  b - the right-hand-side vector

3147:    Output Parameter:
3148: .  x - the result vector

3150:    Notes:
3151:    The vectors b and x cannot be the same.  I.e., one cannot
3152:    call MatSolve(A,x,x).

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

3159:    Level: developer

3161:    Concepts: matrices^triangular solves

3163: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3164: @*/
3165: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
3166: {

3176:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3177:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3178:   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);
3179:   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);
3180:   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);
3181:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3182:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3183:   MatCheckPreallocated(mat,1);

3185:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3186:   (*mat->ops->solve)(mat,b,x);
3187:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3188:   PetscObjectStateIncrease((PetscObject)x);
3189:   return(0);
3190: }

3194: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
3195: {
3197:   Vec            b,x;
3198:   PetscInt       m,N,i;
3199:   PetscScalar    *bb,*xx;
3200:   PetscBool      flg;

3203:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3204:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3205:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3206:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3208:   MatDenseGetArray(B,&bb);
3209:   MatDenseGetArray(X,&xx);
3210:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3211:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3212:   MatCreateVecs(A,&x,&b);
3213:   for (i=0; i<N; i++) {
3214:     VecPlaceArray(b,bb + i*m);
3215:     VecPlaceArray(x,xx + i*m);
3216:     MatSolve(A,b,x);
3217:     VecResetArray(x);
3218:     VecResetArray(b);
3219:   }
3220:   VecDestroy(&b);
3221:   VecDestroy(&x);
3222:   MatDenseRestoreArray(B,&bb);
3223:   MatDenseRestoreArray(X,&xx);
3224:   return(0);
3225: }

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

3232:    Neighbor-wise Collective on Mat

3234:    Input Parameters:
3235: +  A - the factored matrix
3236: -  B - the right-hand-side matrix  (dense matrix)

3238:    Output Parameter:
3239: .  X - the result matrix (dense matrix)

3241:    Notes:
3242:    The matrices b and x cannot be the same.  I.e., one cannot
3243:    call MatMatSolve(A,x,x).

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

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

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

3256:    Level: developer

3258:    Concepts: matrices^triangular solves

3260: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3261: @*/
3262: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
3263: {

3273:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3274:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3275:   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);
3276:   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);
3277:   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);
3278:   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");
3279:   if (!A->rmap->N && !A->cmap->N) return(0);
3280:   MatCheckPreallocated(A,1);

3282:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3283:   if (!A->ops->matsolve) {
3284:     PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3285:     MatMatSolve_Basic(A,B,X);
3286:   } else {
3287:     (*A->ops->matsolve)(A,B,X);
3288:   }
3289:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3290:   PetscObjectStateIncrease((PetscObject)X);
3291:   return(0);
3292: }


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

3301:    Neighbor-wise Collective on Mat and Vec

3303:    Input Parameters:
3304: +  mat - the factored matrix
3305: -  b - the right-hand-side vector

3307:    Output Parameter:
3308: .  x - the result vector

3310:    Notes:
3311:    MatSolve() should be used for most applications, as it performs
3312:    a forward solve followed by a backward solve.

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

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

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

3327:    Level: developer

3329:    Concepts: matrices^forward solves

3331: .seealso: MatSolve(), MatBackwardSolve()
3332: @*/
3333: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
3334: {

3344:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3345:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3346:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3347:   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);
3348:   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);
3349:   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);
3350:   MatCheckPreallocated(mat,1);
3351:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3352:   (*mat->ops->forwardsolve)(mat,b,x);
3353:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3354:   PetscObjectStateIncrease((PetscObject)x);
3355:   return(0);
3356: }

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

3364:    Neighbor-wise Collective on Mat and Vec

3366:    Input Parameters:
3367: +  mat - the factored matrix
3368: -  b - the right-hand-side vector

3370:    Output Parameter:
3371: .  x - the result vector

3373:    Notes:
3374:    MatSolve() should be used for most applications, as it performs
3375:    a forward solve followed by a backward solve.

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

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

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

3390:    Level: developer

3392:    Concepts: matrices^backward solves

3394: .seealso: MatSolve(), MatForwardSolve()
3395: @*/
3396: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
3397: {

3407:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3408:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3409:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3410:   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);
3411:   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);
3412:   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);
3413:   MatCheckPreallocated(mat,1);

3415:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3416:   (*mat->ops->backwardsolve)(mat,b,x);
3417:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3418:   PetscObjectStateIncrease((PetscObject)x);
3419:   return(0);
3420: }

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

3427:    Neighbor-wise Collective on Mat and Vec

3429:    Input Parameters:
3430: +  mat - the factored matrix
3431: .  b - the right-hand-side vector
3432: -  y - the vector to be added to

3434:    Output Parameter:
3435: .  x - the result vector

3437:    Notes:
3438:    The vectors b and x cannot be the same.  I.e., one cannot
3439:    call MatSolveAdd(A,x,y,x).

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

3445:    Level: developer

3447:    Concepts: matrices^triangular solves

3449: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3450: @*/
3451: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3452: {
3453:   PetscScalar    one = 1.0;
3454:   Vec            tmp;

3466:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3467:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3468:   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);
3469:   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);
3470:   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);
3471:   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);
3472:   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);
3473:   MatCheckPreallocated(mat,1);

3475:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3476:   if (mat->ops->solveadd) {
3477:     (*mat->ops->solveadd)(mat,b,y,x);
3478:   } else {
3479:     /* do the solve then the add manually */
3480:     if (x != y) {
3481:       MatSolve(mat,b,x);
3482:       VecAXPY(x,one,y);
3483:     } else {
3484:       VecDuplicate(x,&tmp);
3485:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3486:       VecCopy(x,tmp);
3487:       MatSolve(mat,b,x);
3488:       VecAXPY(x,one,tmp);
3489:       VecDestroy(&tmp);
3490:     }
3491:   }
3492:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3493:   PetscObjectStateIncrease((PetscObject)x);
3494:   return(0);
3495: }

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

3502:    Neighbor-wise Collective on Mat and Vec

3504:    Input Parameters:
3505: +  mat - the factored matrix
3506: -  b - the right-hand-side vector

3508:    Output Parameter:
3509: .  x - the result vector

3511:    Notes:
3512:    The vectors b and x cannot be the same.  I.e., one cannot
3513:    call MatSolveTranspose(A,x,x).

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

3519:    Level: developer

3521:    Concepts: matrices^triangular solves

3523: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3524: @*/
3525: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
3526: {

3536:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3537:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3538:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3539:   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);
3540:   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);
3541:   MatCheckPreallocated(mat,1);
3542:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3543:   (*mat->ops->solvetranspose)(mat,b,x);
3544:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3545:   PetscObjectStateIncrease((PetscObject)x);
3546:   return(0);
3547: }

3551: /*@
3552:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3553:                       factored matrix.

3555:    Neighbor-wise Collective on Mat and Vec

3557:    Input Parameters:
3558: +  mat - the factored matrix
3559: .  b - the right-hand-side vector
3560: -  y - the vector to be added to

3562:    Output Parameter:
3563: .  x - the result vector

3565:    Notes:
3566:    The vectors b and x cannot be the same.  I.e., one cannot
3567:    call MatSolveTransposeAdd(A,x,y,x).

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

3573:    Level: developer

3575:    Concepts: matrices^triangular solves

3577: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3578: @*/
3579: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3580: {
3581:   PetscScalar    one = 1.0;
3583:   Vec            tmp;

3594:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3595:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3596:   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);
3597:   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);
3598:   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);
3599:   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);
3600:   MatCheckPreallocated(mat,1);

3602:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3603:   if (mat->ops->solvetransposeadd) {
3604:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3605:   } else {
3606:     /* do the solve then the add manually */
3607:     if (x != y) {
3608:       MatSolveTranspose(mat,b,x);
3609:       VecAXPY(x,one,y);
3610:     } else {
3611:       VecDuplicate(x,&tmp);
3612:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3613:       VecCopy(x,tmp);
3614:       MatSolveTranspose(mat,b,x);
3615:       VecAXPY(x,one,tmp);
3616:       VecDestroy(&tmp);
3617:     }
3618:   }
3619:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3620:   PetscObjectStateIncrease((PetscObject)x);
3621:   return(0);
3622: }
3623: /* ----------------------------------------------------------------*/

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

3630:    Neighbor-wise Collective on Mat and Vec

3632:    Input Parameters:
3633: +  mat - the matrix
3634: .  b - the right hand side
3635: .  omega - the relaxation factor
3636: .  flag - flag indicating the type of SOR (see below)
3637: .  shift -  diagonal shift
3638: .  its - the number of iterations
3639: -  lits - the number of local iterations

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

3644:    SOR Flags:
3645: .     SOR_FORWARD_SWEEP - forward SOR
3646: .     SOR_BACKWARD_SWEEP - backward SOR
3647: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3648: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3649: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3650: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3651: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3652:          upper/lower triangular part of matrix to
3653:          vector (with omega)
3654: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3656:    Notes:
3657:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3658:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3659:    on each processor.

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

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

3666:    Notes for Advanced Users:
3667:    The flags are implemented as bitwise inclusive or operations.
3668:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3669:    to specify a zero initial guess for SSOR.

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

3675:    Vectors x and b CANNOT be the same

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

3679:    Level: developer

3681:    Concepts: matrices^relaxation
3682:    Concepts: matrices^SOR
3683:    Concepts: matrices^Gauss-Seidel

3685: @*/
3686: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3687: {

3697:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3698:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3699:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3700:   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);
3701:   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);
3702:   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);
3703:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3704:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3705:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3707:   MatCheckPreallocated(mat,1);
3708:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3709:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3710:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3711:   PetscObjectStateIncrease((PetscObject)x);
3712:   return(0);
3713: }

3717: /*
3718:       Default matrix copy routine.
3719: */
3720: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3721: {
3722:   PetscErrorCode    ierr;
3723:   PetscInt          i,rstart = 0,rend = 0,nz;
3724:   const PetscInt    *cwork;
3725:   const PetscScalar *vwork;

3728:   if (B->assembled) {
3729:     MatZeroEntries(B);
3730:   }
3731:   MatGetOwnershipRange(A,&rstart,&rend);
3732:   for (i=rstart; i<rend; i++) {
3733:     MatGetRow(A,i,&nz,&cwork,&vwork);
3734:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3735:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3736:   }
3737:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3738:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3739:   PetscObjectStateIncrease((PetscObject)B);
3740:   return(0);
3741: }

3745: /*@
3746:    MatCopy - Copys a matrix to another matrix.

3748:    Collective on Mat

3750:    Input Parameters:
3751: +  A - the matrix
3752: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3754:    Output Parameter:
3755: .  B - where the copy is put

3757:    Notes:
3758:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3759:    same nonzero pattern or the routine will crash.

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

3765:    Level: intermediate

3767:    Concepts: matrices^copying

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

3771: @*/
3772: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3773: {
3775:   PetscInt       i;

3783:   MatCheckPreallocated(B,2);
3784:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3785:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3786:   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);
3787:   MatCheckPreallocated(A,1);

3789:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3790:   if (A->ops->copy) {
3791:     (*A->ops->copy)(A,B,str);
3792:   } else { /* generic conversion */
3793:     MatCopy_Basic(A,B,str);
3794:   }

3796:   B->stencil.dim = A->stencil.dim;
3797:   B->stencil.noc = A->stencil.noc;
3798:   for (i=0; i<=A->stencil.dim; i++) {
3799:     B->stencil.dims[i]   = A->stencil.dims[i];
3800:     B->stencil.starts[i] = A->stencil.starts[i];
3801:   }

3803:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3804:   PetscObjectStateIncrease((PetscObject)B);
3805:   return(0);
3806: }

3810: /*@C
3811:    MatConvert - Converts a matrix to another matrix, either of the same
3812:    or different type.

3814:    Collective on Mat

3816:    Input Parameters:
3817: +  mat - the matrix
3818: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3819:    same type as the original matrix.
3820: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3821:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3822:    MAT_INITIAL_MATRIX.

3824:    Output Parameter:
3825: .  M - pointer to place new matrix

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

3832:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3833:    the MPI communicator of the generated matrix is always the same as the communicator
3834:    of the input matrix.

3836:    Level: intermediate

3838:    Concepts: matrices^converting between storage formats

3840: .seealso: MatCopy(), MatDuplicate()
3841: @*/
3842: PetscErrorCode  MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3843: {
3845:   PetscBool      sametype,issame,flg;
3846:   char           convname[256],mtype[256];
3847:   Mat            B;

3853:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3854:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3855:   MatCheckPreallocated(mat,1);
3856:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

3858:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3859:   if (flg) {
3860:     newtype = mtype;
3861:   }
3862:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3863:   PetscStrcmp(newtype,"same",&issame);
3864:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");

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

3868:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3869:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3870:   } else {
3871:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3872:     const char     *prefix[3] = {"seq","mpi",""};
3873:     PetscInt       i;
3874:     /*
3875:        Order of precedence:
3876:        1) See if a specialized converter is known to the current matrix.
3877:        2) See if a specialized converter is known to the desired matrix class.
3878:        3) See if a good general converter is registered for the desired class
3879:           (as of 6/27/03 only MATMPIADJ falls into this category).
3880:        4) See if a good general converter is known for the current matrix.
3881:        5) Use a really basic converter.
3882:     */

3884:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3885:     for (i=0; i<3; i++) {
3886:       PetscStrcpy(convname,"MatConvert_");
3887:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3888:       PetscStrcat(convname,"_");
3889:       PetscStrcat(convname,prefix[i]);
3890:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3891:       PetscStrcat(convname,"_C");
3892:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3893:       if (conv) goto foundconv;
3894:     }

3896:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3897:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
3898:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3899:     MatSetType(B,newtype);
3900:     for (i=0; i<3; i++) {
3901:       PetscStrcpy(convname,"MatConvert_");
3902:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3903:       PetscStrcat(convname,"_");
3904:       PetscStrcat(convname,prefix[i]);
3905:       PetscStrcat(convname,newtype);
3906:       PetscStrcat(convname,"_C");
3907:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3908:       if (conv) {
3909:         MatDestroy(&B);
3910:         goto foundconv;
3911:       }
3912:     }

3914:     /* 3) See if a good general converter is registered for the desired class */
3915:     conv = B->ops->convertfrom;
3916:     MatDestroy(&B);
3917:     if (conv) goto foundconv;

3919:     /* 4) See if a good general converter is known for the current matrix */
3920:     if (mat->ops->convert) {
3921:       conv = mat->ops->convert;
3922:     }
3923:     if (conv) goto foundconv;

3925:     /* 5) Use a really basic converter. */
3926:     conv = MatConvert_Basic;

3928: foundconv:
3929:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3930:     (*conv)(mat,newtype,reuse,M);
3931:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3932:   }
3933:   PetscObjectStateIncrease((PetscObject)*M);

3935:   /* Copy Mat options */
3936:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3937:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3938:   return(0);
3939: }

3943: /*@C
3944:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3946:    Not Collective

3948:    Input Parameter:
3949: .  mat - the matrix, must be a factored matrix

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

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

3958:    Level: intermediate

3960: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3961: @*/
3962: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3963: {
3964:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

3969:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3970:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
3971:   if (!conv) {
3972:     *type = MATSOLVERPETSC;
3973:   } else {
3974:     (*conv)(mat,type);
3975:   }
3976:   return(0);
3977: }

3979: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
3980: struct _MatSolverPackageForSpecifcType {
3981:   MatType                        mtype;
3982:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
3983:   MatSolverPackageForSpecifcType next;
3984: };

3986: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
3987: struct _MatSolverPackageHolder {
3988:   char                           *name;
3989:   MatSolverPackageForSpecifcType handlers;
3990:   MatSolverPackageHolder         next;
3991: };

3993: static MatSolverPackageHolder MatSolverPackageHolders = NULL;

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

4000:    Input Parameters:
4001: +    package - name of the package, for example petsc or superlu
4002: .    mtype - the matrix type that works with this package
4003: .    ftype - the type of factorization supported by the package
4004: -    getfactor - routine that will create the factored matrix ready to be used

4006:     Level: intermediate

4008: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4009: @*/
4010: PetscErrorCode  MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4011: {
4012:   PetscErrorCode                 ierr;
4013:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4014:   PetscBool                      flg;
4015:   MatSolverPackageForSpecifcType inext,iprev = NULL;

4018:   if (!MatSolverPackageHolders) {
4019:     PetscNew(&MatSolverPackageHolders);
4020:     PetscStrallocpy(package,&MatSolverPackageHolders->name);
4021:     PetscNew(&MatSolverPackageHolders->handlers);
4022:     PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4023:     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4024:     return(0);
4025:   }
4026:   while (next) {
4027:     PetscStrcasecmp(package,next->name,&flg);
4028:     if (flg) {
4029:       inext = next->handlers;
4030:       while (inext) {
4031:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4032:         if (flg) {
4033:           inext->getfactor[(int)ftype-1] = getfactor;
4034:           return(0);
4035:         }
4036:         iprev = inext;
4037:         inext = inext->next;
4038:       }
4039:       PetscNew(&iprev->next);
4040:       PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4041:       iprev->next->getfactor[(int)ftype-1] = getfactor;
4042:       return(0);
4043:     }
4044:     prev = next;
4045:     next = next->next;
4046:   }
4047:   PetscNew(&prev->next);
4048:   PetscStrallocpy(package,&prev->next->name);
4049:   PetscNew(&prev->next->handlers);
4050:   PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4051:   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4052:   return(0);
4053: }

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

4060:    Input Parameters:
4061: +    package - name of the package, for example petsc or superlu
4062: .    ftype - the type of factorization supported by the package
4063: -    mtype - the matrix type that works with this package

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

4070:     Level: intermediate

4072: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4073: @*/
4074: PetscErrorCode  MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4075: {
4076:   PetscErrorCode                 ierr;
4077:   MatSolverPackageHolder         next = MatSolverPackageHolders;
4078:   PetscBool                      flg;
4079:   MatSolverPackageForSpecifcType inext;

4082:   if (foundpackage) *foundpackage = PETSC_FALSE;
4083:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4084:   if (getfactor)    *getfactor    = NULL;
4085:   while (next) {
4086:     PetscStrcasecmp(package,next->name,&flg);
4087:     if (flg) {
4088:       if (foundpackage) *foundpackage = PETSC_TRUE;
4089:       inext = next->handlers;
4090:       while (inext) {
4091:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4092:         if (flg) {
4093:           if (foundmtype) *foundmtype = PETSC_TRUE;
4094:           if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4095:           return(0);
4096:         }
4097:         inext = inext->next;
4098:       }
4099:     }
4100:     next = next->next;
4101:   }
4102:   return(0);
4103: }

4107: PetscErrorCode  MatSolverPackageDestroy(void)
4108: {
4109:   PetscErrorCode                 ierr;
4110:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4111:   MatSolverPackageForSpecifcType inext,iprev;

4114:   while (next) {
4115:     PetscFree(next->name);
4116:     inext = next->handlers;
4117:     while (inext) {
4118:       PetscFree(inext->mtype);
4119:       iprev = inext;
4120:       inext = inext->next;
4121:       PetscFree(iprev);
4122:     }
4123:     prev = next;
4124:     next = next->next;
4125:     PetscFree(prev);
4126:   }
4127:   MatSolverPackageHolders = NULL;
4128:   return(0);
4129: }

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

4136:    Collective on Mat

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

4143:    Output Parameters:
4144: .  f - the factor matrix used with MatXXFactorSymbolic() calls

4146:    Notes:
4147:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4148:      such as pastix, superlu, mumps etc.

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

4152:    Level: intermediate

4154: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4155: @*/
4156: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4157: {
4158:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4159:   PetscBool      foundpackage,foundmtype;


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

4168:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4169:   if (!foundpackage) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4170:   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4171:   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);

4173:   (*conv)(mat,ftype,f);
4174:   return(0);
4175: }

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

4182:    Not Collective

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

4189:    Output Parameter:
4190: .    flg - PETSC_TRUE if the factorization is available

4192:    Notes:
4193:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4194:      such as pastix, superlu, mumps etc.

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

4198:    Level: intermediate

4200: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4201: @*/
4202: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4203: {
4204:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);


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

4213:   *flg = PETSC_FALSE;
4214:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4215:   if (gconv) {
4216:     *flg = PETSC_TRUE;
4217:   }
4218:   return(0);
4219: }

4221: #include <petscdmtypes.h>

4225: /*@
4226:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4228:    Collective on Mat

4230:    Input Parameters:
4231: +  mat - the matrix
4232: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4233:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

4235:    Output Parameter:
4236: .  M - pointer to place new matrix

4238:    Level: intermediate

4240:    Concepts: matrices^duplicating

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

4244: .seealso: MatCopy(), MatConvert()
4245: @*/
4246: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4247: {
4249:   Mat            B;
4250:   PetscInt       i;
4251:   DM             dm;

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

4261:   *M = 0;
4262:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4263:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4264:   (*mat->ops->duplicate)(mat,op,M);
4265:   B    = *M;

4267:   B->stencil.dim = mat->stencil.dim;
4268:   B->stencil.noc = mat->stencil.noc;
4269:   for (i=0; i<=mat->stencil.dim; i++) {
4270:     B->stencil.dims[i]   = mat->stencil.dims[i];
4271:     B->stencil.starts[i] = mat->stencil.starts[i];
4272:   }

4274:   B->nooffproczerorows = mat->nooffproczerorows;
4275:   B->nooffprocentries  = mat->nooffprocentries;

4277:   PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4278:   if (dm) {
4279:     PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4280:   }
4281:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4282:   PetscObjectStateIncrease((PetscObject)B);
4283:   return(0);
4284: }

4288: /*@
4289:    MatGetDiagonal - Gets the diagonal of a matrix.

4291:    Logically Collective on Mat and Vec

4293:    Input Parameters:
4294: +  mat - the matrix
4295: -  v - the vector for storing the diagonal

4297:    Output Parameter:
4298: .  v - the diagonal of the matrix

4300:    Level: intermediate

4302:    Note:
4303:    Currently only correct in parallel for square matrices.

4305:    Concepts: matrices^accessing diagonals

4307: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4308: @*/
4309: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
4310: {

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

4321:   (*mat->ops->getdiagonal)(mat,v);
4322:   PetscObjectStateIncrease((PetscObject)v);
4323:   return(0);
4324: }

4328: /*@C
4329:    MatGetRowMin - Gets the minimum value (of the real part) of each
4330:         row of the matrix

4332:    Logically Collective on Mat and Vec

4334:    Input Parameters:
4335: .  mat - the matrix

4337:    Output Parameter:
4338: +  v - the vector for storing the maximums
4339: -  idx - the indices of the column found for each row (optional)

4341:    Level: intermediate

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

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

4348:    Concepts: matrices^getting row maximums

4350: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4351:           MatGetRowMax()
4352: @*/
4353: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4354: {

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

4365:   (*mat->ops->getrowmin)(mat,v,idx);
4366:   PetscObjectStateIncrease((PetscObject)v);
4367:   return(0);
4368: }

4372: /*@C
4373:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4374:         row of the matrix

4376:    Logically Collective on Mat and Vec

4378:    Input Parameters:
4379: .  mat - the matrix

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

4385:    Level: intermediate

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

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

4392:    Concepts: matrices^getting row maximums

4394: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4395: @*/
4396: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4397: {

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

4409:   (*mat->ops->getrowminabs)(mat,v,idx);
4410:   PetscObjectStateIncrease((PetscObject)v);
4411:   return(0);
4412: }

4416: /*@C
4417:    MatGetRowMax - Gets the maximum value (of the real part) of each
4418:         row of the matrix

4420:    Logically Collective on Mat and Vec

4422:    Input Parameters:
4423: .  mat - the matrix

4425:    Output Parameter:
4426: +  v - the vector for storing the maximums
4427: -  idx - the indices of the column found for each row (optional)

4429:    Level: intermediate

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

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

4436:    Concepts: matrices^getting row maximums

4438: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4439: @*/
4440: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4441: {

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

4452:   (*mat->ops->getrowmax)(mat,v,idx);
4453:   PetscObjectStateIncrease((PetscObject)v);
4454:   return(0);
4455: }

4459: /*@C
4460:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4461:         row of the matrix

4463:    Logically Collective on Mat and Vec

4465:    Input Parameters:
4466: .  mat - the matrix

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

4472:    Level: intermediate

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

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

4479:    Concepts: matrices^getting row maximums

4481: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4482: @*/
4483: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4484: {

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

4496:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4497:   PetscObjectStateIncrease((PetscObject)v);
4498:   return(0);
4499: }

4503: /*@
4504:    MatGetRowSum - Gets the sum of each row of the matrix

4506:    Logically Collective on Mat and Vec

4508:    Input Parameters:
4509: .  mat - the matrix

4511:    Output Parameter:
4512: .  v - the vector for storing the sum of rows

4514:    Level: intermediate

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

4518:    Concepts: matrices^getting row sums

4520: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4521: @*/
4522: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4523: {
4524:   PetscInt       start = 0, end = 0, row;
4525:   PetscScalar    *array;

4532:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4533:   MatCheckPreallocated(mat,1);
4534:   MatGetOwnershipRange(mat, &start, &end);
4535:   VecGetArray(v, &array);
4536:   for (row = start; row < end; ++row) {
4537:     PetscInt          ncols, col;
4538:     const PetscInt    *cols;
4539:     const PetscScalar *vals;

4541:     array[row - start] = 0.0;

4543:     MatGetRow(mat, row, &ncols, &cols, &vals);
4544:     for (col = 0; col < ncols; col++) {
4545:       array[row - start] += vals[col];
4546:     }
4547:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4548:   }
4549:   VecRestoreArray(v, &array);
4550:   PetscObjectStateIncrease((PetscObject) v);
4551:   return(0);
4552: }

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

4559:    Collective on Mat

4561:    Input Parameter:
4562: +  mat - the matrix to transpose
4563: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4565:    Output Parameters:
4566: .  B - the transpose

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

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

4573:    Level: intermediate

4575:    Concepts: matrices^transposing

4577: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4578: @*/
4579: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4580: {

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

4591:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4592:   (*mat->ops->transpose)(mat,reuse,B);
4593:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4594:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4595:   return(0);
4596: }

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

4604:    Collective on Mat

4606:    Input Parameter:
4607: +  A - the matrix to test
4608: -  B - the matrix to test against, this can equal the first parameter

4610:    Output Parameters:
4611: .  flg - the result

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

4618:    Level: intermediate

4620:    Concepts: matrices^transposing, matrix^symmetry

4622: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4623: @*/
4624: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4625: {
4626:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4632:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4633:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4634:   *flg = PETSC_FALSE;
4635:   if (f && g) {
4636:     if (f == g) {
4637:       (*f)(A,B,tol,flg);
4638:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4639:   } else {
4640:     MatType mattype;
4641:     if (!f) {
4642:       MatGetType(A,&mattype);
4643:     } else {
4644:       MatGetType(B,&mattype);
4645:     }
4646:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4647:   }
4648:   return(0);
4649: }

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

4656:    Collective on Mat

4658:    Input Parameter:
4659: +  mat - the matrix to transpose and complex conjugate
4660: -  reuse - store the transpose matrix in the provided B

4662:    Output Parameters:
4663: .  B - the Hermitian

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

4668:    Level: intermediate

4670:    Concepts: matrices^transposing, complex conjugatex

4672: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4673: @*/
4674: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4675: {

4679:   MatTranspose(mat,reuse,B);
4680: #if defined(PETSC_USE_COMPLEX)
4681:   MatConjugate(*B);
4682: #endif
4683:   return(0);
4684: }

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

4691:    Collective on Mat

4693:    Input Parameter:
4694: +  A - the matrix to test
4695: -  B - the matrix to test against, this can equal the first parameter

4697:    Output Parameters:
4698: .  flg - the result

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

4705:    Level: intermediate

4707:    Concepts: matrices^transposing, matrix^symmetry

4709: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4710: @*/
4711: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4712: {
4713:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4719:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4720:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4721:   if (f && g) {
4722:     if (f==g) {
4723:       (*f)(A,B,tol,flg);
4724:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4725:   }
4726:   return(0);
4727: }

4731: /*@
4732:    MatPermute - Creates a new matrix with rows and columns permuted from the
4733:    original.

4735:    Collective on Mat

4737:    Input Parameters:
4738: +  mat - the matrix to permute
4739: .  row - row permutation, each processor supplies only the permutation for its rows
4740: -  col - column permutation, each processor supplies only the permutation for its columns

4742:    Output Parameters:
4743: .  B - the permuted matrix

4745:    Level: advanced

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

4751:    Concepts: matrices^permuting

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

4755: @*/
4756: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4757: {

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

4771:   (*mat->ops->permute)(mat,row,col,B);
4772:   PetscObjectStateIncrease((PetscObject)*B);
4773:   return(0);
4774: }

4778: /*@
4779:    MatEqual - Compares two matrices.

4781:    Collective on Mat

4783:    Input Parameters:
4784: +  A - the first matrix
4785: -  B - the second matrix

4787:    Output Parameter:
4788: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4790:    Level: intermediate

4792:    Concepts: matrices^equality between
4793: @*/
4794: PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4795: {

4805:   MatCheckPreallocated(B,2);
4806:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4807:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4808:   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);
4809:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4810:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4811:   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);
4812:   MatCheckPreallocated(A,1);

4814:   (*A->ops->equal)(A,B,flg);
4815:   return(0);
4816: }

4820: /*@
4821:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4822:    matrices that are stored as vectors.  Either of the two scaling
4823:    matrices can be NULL.

4825:    Collective on Mat

4827:    Input Parameters:
4828: +  mat - the matrix to be scaled
4829: .  l - the left scaling vector (or NULL)
4830: -  r - the right scaling vector (or NULL)

4832:    Notes:
4833:    MatDiagonalScale() computes A = LAR, where
4834:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4835:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4837:    Level: intermediate

4839:    Concepts: matrices^diagonal scaling
4840:    Concepts: diagonal scaling of matrices

4842: .seealso: MatScale()
4843: @*/
4844: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4845: {

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

4858:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4859:   (*mat->ops->diagonalscale)(mat,l,r);
4860:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4861:   PetscObjectStateIncrease((PetscObject)mat);
4862: #if defined(PETSC_HAVE_CUSP)
4863:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4864:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4865:   }
4866: #endif
4867: #if defined(PETSC_HAVE_VIENNACL)
4868:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4869:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4870:   }
4871: #endif
4872:   return(0);
4873: }

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

4880:     Logically Collective on Mat

4882:     Input Parameters:
4883: +   mat - the matrix to be scaled
4884: -   a  - the scaling value

4886:     Output Parameter:
4887: .   mat - the scaled matrix

4889:     Level: intermediate

4891:     Concepts: matrices^scaling all entries

4893: .seealso: MatDiagonalScale()
4894: @*/
4895: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4896: {

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

4908:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4909:   if (a != (PetscScalar)1.0) {
4910:     (*mat->ops->scale)(mat,a);
4911:     PetscObjectStateIncrease((PetscObject)mat);
4912:   }
4913:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4914: #if defined(PETSC_HAVE_CUSP)
4915:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4916:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4917:   }
4918: #endif
4919: #if defined(PETSC_HAVE_VIENNACL)
4920:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4921:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4922:   }
4923: #endif
4924:   return(0);
4925: }

4929: /*@
4930:    MatNorm - Calculates various norms of a matrix.

4932:    Collective on Mat

4934:    Input Parameters:
4935: +  mat - the matrix
4936: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4938:    Output Parameters:
4939: .  nrm - the resulting norm

4941:    Level: intermediate

4943:    Concepts: matrices^norm
4944:    Concepts: norm^of matrix
4945: @*/
4946: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4947: {


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

4960:   (*mat->ops->norm)(mat,type,nrm);
4961:   return(0);
4962: }

4964: /*
4965:      This variable is used to prevent counting of MatAssemblyBegin() that
4966:    are called from within a MatAssemblyEnd().
4967: */
4968: static PetscInt MatAssemblyEnd_InUse = 0;
4971: /*@
4972:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4973:    be called after completing all calls to MatSetValues().

4975:    Collective on Mat

4977:    Input Parameters:
4978: +  mat - the matrix
4979: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4981:    Notes:
4982:    MatSetValues() generally caches the values.  The matrix is ready to
4983:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4984:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4985:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4986:    using the matrix.

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

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

4996:    Level: beginner

4998:    Concepts: matrices^assembling

5000: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5001: @*/
5002: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
5003: {

5009:   MatCheckPreallocated(mat,1);
5010:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5011:   if (mat->assembled) {
5012:     mat->was_assembled = PETSC_TRUE;
5013:     mat->assembled     = PETSC_FALSE;
5014:   }
5015:   if (!MatAssemblyEnd_InUse) {
5016:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5017:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5018:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5019:   } else if (mat->ops->assemblybegin) {
5020:     (*mat->ops->assemblybegin)(mat,type);
5021:   }
5022:   return(0);
5023: }

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

5031:    Not Collective

5033:    Input Parameter:
5034: .  mat - the matrix

5036:    Output Parameter:
5037: .  assembled - PETSC_TRUE or PETSC_FALSE

5039:    Level: advanced

5041:    Concepts: matrices^assembled?

5043: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5044: @*/
5045: PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
5046: {
5051:   *assembled = mat->assembled;
5052:   return(0);
5053: }

5057: /*@
5058:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5059:    be called after MatAssemblyBegin().

5061:    Collective on Mat

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

5067:    Options Database Keys:
5068: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5069: .  -mat_view ::ascii_info_detail - Prints more detailed info
5070: .  -mat_view - Prints matrix in ASCII format
5071: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5072: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5073: .  -display <name> - Sets display name (default is host)
5074: .  -draw_pause <sec> - Sets number of seconds to pause after display
5075: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 11 Using MATLAB with PETSc )
5076: .  -viewer_socket_machine <machine> - Machine to use for socket
5077: .  -viewer_socket_port <port> - Port number to use for socket
5078: -  -mat_view binary:filename[:append] - Save matrix to file in binary format

5080:    Notes:
5081:    MatSetValues() generally caches the values.  The matrix is ready to
5082:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5083:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5084:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5085:    using the matrix.

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

5091:    Level: beginner

5093: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5094: @*/
5095: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
5096: {
5097:   PetscErrorCode  ierr;
5098:   static PetscInt inassm = 0;
5099:   PetscBool       flg    = PETSC_FALSE;


5105:   inassm++;
5106:   MatAssemblyEnd_InUse++;
5107:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5108:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5109:     if (mat->ops->assemblyend) {
5110:       (*mat->ops->assemblyend)(mat,type);
5111:     }
5112:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5113:   } else if (mat->ops->assemblyend) {
5114:     (*mat->ops->assemblyend)(mat,type);
5115:   }

5117:   /* Flush assembly is not a true assembly */
5118:   if (type != MAT_FLUSH_ASSEMBLY) {
5119:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5120:   }
5121:   mat->insertmode = NOT_SET_VALUES;
5122:   MatAssemblyEnd_InUse--;
5123:   PetscObjectStateIncrease((PetscObject)mat);
5124:   if (!mat->symmetric_eternal) {
5125:     mat->symmetric_set              = PETSC_FALSE;
5126:     mat->hermitian_set              = PETSC_FALSE;
5127:     mat->structurally_symmetric_set = PETSC_FALSE;
5128:   }
5129: #if defined(PETSC_HAVE_CUSP)
5130:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5131:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5132:   }
5133: #endif
5134: #if defined(PETSC_HAVE_VIENNACL)
5135:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5136:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5137:   }
5138: #endif
5139:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5140:     MatViewFromOptions(mat,NULL,"-mat_view");

5142:     if (mat->checksymmetryonassembly) {
5143:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5144:       if (flg) {
5145:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5146:       } else {
5147:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5148:       }
5149:     }
5150:     if (mat->nullsp && mat->checknullspaceonassembly) {
5151:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5152:     }
5153:   }
5154:   inassm--;
5155:   return(0);
5156: }

5160: /*@
5161:    MatSetOption - Sets a parameter option for a matrix. Some options
5162:    may be specific to certain storage formats.  Some options
5163:    determine how values will be inserted (or added). Sorted,
5164:    row-oriented input will generally assemble the fastest. The default
5165:    is row-oriented.

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

5169:    Input Parameters:
5170: +  mat - the matrix
5171: .  option - the option, one of those listed below (and possibly others),
5172: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5174:   Options Describing Matrix Structure:
5175: +    MAT_SPD - symmetric positive definite
5176: .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5177: .    MAT_HERMITIAN - transpose is the complex conjugation
5178: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5179: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5180:                             you set to be kept with all future use of the matrix
5181:                             including after MatAssemblyBegin/End() which could
5182:                             potentially change the symmetry structure, i.e. you
5183:                             KNOW the matrix will ALWAYS have the property you set.


5186:    Options For Use with MatSetValues():
5187:    Insert a logically dense subblock, which can be
5188: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

5205:    Notes:
5206:    Some options are relevant only for particular matrix types and
5207:    are thus ignored by others.  Other options are not supported by
5208:    certain matrix types and will generate an error message if set.

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

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

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

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

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

5236:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5237:    searches during matrix assembly. When this flag is set, the hash table
5238:    is created during the first Matrix Assembly. This hash table is
5239:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5240:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5241:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5242:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5261:    Level: intermediate

5263:    Concepts: matrices^setting options

5265: .seealso:  MatOption, Mat

5267: @*/
5268: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool flg)
5269: {

5275:   if (op > 0) {
5278:   }

5280:   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);
5281:   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()");

5283:   switch (op) {
5284:   case MAT_NO_OFF_PROC_ENTRIES:
5285:     mat->nooffprocentries = flg;
5286:     return(0);
5287:     break;
5288:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5289:     mat->nooffproczerorows = flg;
5290:     return(0);
5291:     break;
5292:   case MAT_SPD:
5293:     mat->spd_set = PETSC_TRUE;
5294:     mat->spd     = flg;
5295:     if (flg) {
5296:       mat->symmetric                  = PETSC_TRUE;
5297:       mat->structurally_symmetric     = PETSC_TRUE;
5298:       mat->symmetric_set              = PETSC_TRUE;
5299:       mat->structurally_symmetric_set = PETSC_TRUE;
5300:     }
5301:     break;
5302:   case MAT_SYMMETRIC:
5303:     mat->symmetric = flg;
5304:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5305:     mat->symmetric_set              = PETSC_TRUE;
5306:     mat->structurally_symmetric_set = flg;
5307:     break;
5308:   case MAT_HERMITIAN:
5309:     mat->hermitian = flg;
5310:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5311:     mat->hermitian_set              = PETSC_TRUE;
5312:     mat->structurally_symmetric_set = flg;
5313:     break;
5314:   case MAT_STRUCTURALLY_SYMMETRIC:
5315:     mat->structurally_symmetric     = flg;
5316:     mat->structurally_symmetric_set = PETSC_TRUE;
5317:     break;
5318:   case MAT_SYMMETRY_ETERNAL:
5319:     mat->symmetric_eternal = flg;
5320:     break;
5321:   default:
5322:     break;
5323:   }
5324:   if (mat->ops->setoption) {
5325:     (*mat->ops->setoption)(mat,op,flg);
5326:   }
5327:   return(0);
5328: }

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

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

5337:    Input Parameters:
5338: +  mat - the matrix
5339: -  option - the option, this only responds to certain options, check the code for which ones

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

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

5346:    Level: intermediate

5348:    Concepts: matrices^setting options

5350: .seealso:  MatOption, MatSetOption()

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

5359:   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);
5360:   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()");

5362:   switch (op) {
5363:   case MAT_NO_OFF_PROC_ENTRIES:
5364:     *flg = mat->nooffprocentries;
5365:     break;
5366:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5367:     *flg = mat->nooffproczerorows;
5368:     break;
5369:   case MAT_SYMMETRIC:
5370:     *flg = mat->symmetric;
5371:     break;
5372:   case MAT_HERMITIAN:
5373:     *flg = mat->hermitian;
5374:     break;
5375:   case MAT_STRUCTURALLY_SYMMETRIC:
5376:     *flg = mat->structurally_symmetric;
5377:     break;
5378:   case MAT_SYMMETRY_ETERNAL:
5379:     *flg = mat->symmetric_eternal;
5380:     break;
5381:   default:
5382:     break;
5383:   }
5384:   return(0);
5385: }

5389: /*@
5390:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5391:    this routine retains the old nonzero structure.

5393:    Logically Collective on Mat

5395:    Input Parameters:
5396: .  mat - the matrix

5398:    Level: intermediate

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

5403:    Concepts: matrices^zeroing

5405: .seealso: MatZeroRows()
5406: @*/
5407: PetscErrorCode  MatZeroEntries(Mat mat)
5408: {

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

5419:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5420:   (*mat->ops->zeroentries)(mat);
5421:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5422:   PetscObjectStateIncrease((PetscObject)mat);
5423: #if defined(PETSC_HAVE_CUSP)
5424:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5425:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5426:   }
5427: #endif
5428: #if defined(PETSC_HAVE_VIENNACL)
5429:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5430:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5431:   }
5432: #endif
5433:   return(0);
5434: }

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

5442:    Collective on Mat

5444:    Input Parameters:
5445: +  mat - the matrix
5446: .  numRows - the number of rows to remove
5447: .  rows - the global row indices
5448: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5449: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5450: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5469:    Level: intermediate

5471:    Concepts: matrices^zeroing rows

5473: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5474: @*/
5475: PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5476: {

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

5488:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5489:   MatViewFromOptions(mat,NULL,"-mat_view");
5490:   PetscObjectStateIncrease((PetscObject)mat);
5491: #if defined(PETSC_HAVE_CUSP)
5492:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5493:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5494:   }
5495: #endif
5496: #if defined(PETSC_HAVE_VIENNACL)
5497:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5498:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5499:   }
5500: #endif
5501:   return(0);
5502: }

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

5510:    Collective on Mat

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

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

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

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

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

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

5536:    Level: intermediate

5538:    Concepts: matrices^zeroing rows

5540: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5541: @*/
5542: PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5543: {
5545:   PetscInt       numRows;
5546:   const PetscInt *rows;

5553:   ISGetLocalSize(is,&numRows);
5554:   ISGetIndices(is,&rows);
5555:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5556:   ISRestoreIndices(is,&rows);
5557:   return(0);
5558: }

5562: /*@C
5563:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5564:    of a set of rows of a matrix.

5566:    Collective on Mat

5568:    Input Parameters:
5569: +  mat - the matrix
5570: .  numRows - the number of rows to remove
5571: .  rows - the global row indices
5572: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5573: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5574: -  b - optional vector of right hand side, that will be adjusted by provided solution

5576:    Notes:
5577:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5578:    but does not release memory.  For the dense and block diagonal
5579:    formats this does not alter the nonzero structure.

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

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

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

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

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

5600:    Level: intermediate

5602:    Concepts: matrices^zeroing rows

5604: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5605: @*/
5606: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5607: {

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

5619:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5620:   MatViewFromOptions(mat,NULL,"-mat_view");
5621:   PetscObjectStateIncrease((PetscObject)mat);
5622: #if defined(PETSC_HAVE_CUSP)
5623:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5624:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5625:   }
5626: #endif
5627: #if defined(PETSC_HAVE_VIENNACL)
5628:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5629:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5630:   }
5631: #endif
5632:   return(0);
5633: }

5637: /*@C
5638:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5639:    of a set of rows of a matrix.

5641:    Collective on Mat

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

5650:    Notes:
5651:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5652:    but does not release memory.  For the dense and block diagonal
5653:    formats this does not alter the nonzero structure.

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

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

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

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

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

5674:    Level: intermediate

5676:    Concepts: matrices^zeroing rows

5678: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5679: @*/
5680: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5681: {
5682:   PetscInt       numRows;
5683:   const PetscInt *rows;

5690:   ISGetLocalSize(is,&numRows);
5691:   ISGetIndices(is,&rows);
5692:   MatZeroRows(mat,numRows,rows,diag,x,b);
5693:   ISRestoreIndices(is,&rows);
5694:   return(0);
5695: }

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

5703:    Collective on Mat

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

5713:    Notes:
5714:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5715:    but does not release memory.  For the dense and block diagonal
5716:    formats this does not alter the nonzero structure.

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

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

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

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

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

5736:    In Fortran idxm and idxn should be declared as
5737: $     MatStencil idxm(4,m)
5738:    and the values inserted using
5739: $    idxm(MatStencil_i,1) = i
5740: $    idxm(MatStencil_j,1) = j
5741: $    idxm(MatStencil_k,1) = k
5742: $    idxm(MatStencil_c,1) = c
5743:    etc

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

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

5753:    Level: intermediate

5755:    Concepts: matrices^zeroing rows

5757: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5758: @*/
5759: PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5760: {
5761:   PetscInt       dim     = mat->stencil.dim;
5762:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5763:   PetscInt       *dims   = mat->stencil.dims+1;
5764:   PetscInt       *starts = mat->stencil.starts;
5765:   PetscInt       *dxm    = (PetscInt*) rows;
5766:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


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

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

5805:    Collective on Mat

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

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

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

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

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

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

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

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

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

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

5855:    Level: intermediate

5857:    Concepts: matrices^zeroing rows

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


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

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

5907:    Collective on Mat

5909:    Input Parameters:
5910: +  mat - the matrix
5911: .  numRows - the number of rows to remove
5912: .  rows - the global row indices
5913: .  diag - value put in all diagonals of eliminated rows
5914: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5915: -  b - optional vector of right hand side, that will be adjusted by provided solution

5917:    Notes:
5918:    Before calling MatZeroRowsLocal(), the user must first set the
5919:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

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

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

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

5936:    Level: intermediate

5938:    Concepts: matrices^zeroing

5940: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5941: @*/
5942: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5943: {

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

5954:   if (mat->ops->zerorowslocal) {
5955:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5956:   } else {
5957:     IS             is, newis;
5958:     const PetscInt *newRows;

5960:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5961:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5962:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5963:     ISGetIndices(newis,&newRows);
5964:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5965:     ISRestoreIndices(newis,&newRows);
5966:     ISDestroy(&newis);
5967:     ISDestroy(&is);
5968:   }
5969:   PetscObjectStateIncrease((PetscObject)mat);
5970: #if defined(PETSC_HAVE_CUSP)
5971:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5972:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5973:   }
5974: #endif
5975: #if defined(PETSC_HAVE_VIENNACL)
5976:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5977:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5978:   }
5979: #endif
5980:   return(0);
5981: }

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

5989:    Collective on Mat

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

5998:    Notes:
5999:    Before calling MatZeroRowsLocalIS(), the user must first set the
6000:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6002:    For the AIJ matrix formats this removes the old nonzero structure,
6003:    but does not release memory.  For the dense and block diagonal
6004:    formats this does not alter the nonzero structure.

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

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

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

6017:    Level: intermediate

6019:    Concepts: matrices^zeroing

6021: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6022: @*/
6023: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6024: {
6026:   PetscInt       numRows;
6027:   const PetscInt *rows;

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

6037:   ISGetLocalSize(is,&numRows);
6038:   ISGetIndices(is,&rows);
6039:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6040:   ISRestoreIndices(is,&rows);
6041:   return(0);
6042: }

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

6050:    Collective on Mat

6052:    Input Parameters:
6053: +  mat - the matrix
6054: .  numRows - the number of rows to remove
6055: .  rows - the global row indices
6056: .  diag - value put in all diagonals of eliminated rows
6057: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6058: -  b - optional vector of right hand side, that will be adjusted by provided solution

6060:    Notes:
6061:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6062:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6068:    Level: intermediate

6070:    Concepts: matrices^zeroing

6072: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6073: @*/
6074: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6075: {
6077:   IS             is, newis;
6078:   const PetscInt *newRows;

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

6088:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6089:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6090:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6091:   ISGetIndices(newis,&newRows);
6092:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6093:   ISRestoreIndices(newis,&newRows);
6094:   ISDestroy(&newis);
6095:   ISDestroy(&is);
6096:   PetscObjectStateIncrease((PetscObject)mat);
6097: #if defined(PETSC_HAVE_CUSP)
6098:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6099:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6100:   }
6101: #endif
6102: #if defined(PETSC_HAVE_VIENNACL)
6103:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6104:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6105:   }
6106: #endif
6107:   return(0);
6108: }

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

6116:    Collective on Mat

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

6125:    Notes:
6126:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6127:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6133:    Level: intermediate

6135:    Concepts: matrices^zeroing

6137: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6138: @*/
6139: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6140: {
6142:   PetscInt       numRows;
6143:   const PetscInt *rows;

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

6153:   ISGetLocalSize(is,&numRows);
6154:   ISGetIndices(is,&rows);
6155:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6156:   ISRestoreIndices(is,&rows);
6157:   return(0);
6158: }

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

6165:    Not Collective

6167:    Input Parameter:
6168: .  mat - the matrix

6170:    Output Parameters:
6171: +  m - the number of global rows
6172: -  n - the number of global columns

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

6176:    Level: beginner

6178:    Concepts: matrices^size

6180: .seealso: MatGetLocalSize()
6181: @*/
6182: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6183: {
6186:   if (m) *m = mat->rmap->N;
6187:   if (n) *n = mat->cmap->N;
6188:   return(0);
6189: }

6193: /*@
6194:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6195:    stored locally.  This information may be implementation dependent, so
6196:    use with care.

6198:    Not Collective

6200:    Input Parameters:
6201: .  mat - the matrix

6203:    Output Parameters:
6204: +  m - the number of local rows
6205: -  n - the number of local columns

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

6209:    Level: beginner

6211:    Concepts: matrices^local size

6213: .seealso: MatGetSize()
6214: @*/
6215: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6216: {
6221:   if (m) *m = mat->rmap->n;
6222:   if (n) *n = mat->cmap->n;
6223:   return(0);
6224: }

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

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

6234:    Input Parameters:
6235: .  mat - the matrix

6237:    Output Parameters:
6238: +  m - the global index of the first local column
6239: -  n - one more than the global index of the last local column

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

6243:    Level: developer

6245:    Concepts: matrices^column ownership

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

6249: @*/
6250: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6251: {
6257:   MatCheckPreallocated(mat,1);
6258:   if (m) *m = mat->cmap->rstart;
6259:   if (n) *n = mat->cmap->rend;
6260:   return(0);
6261: }

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

6271:    Not Collective

6273:    Input Parameters:
6274: .  mat - the matrix

6276:    Output Parameters:
6277: +  m - the global index of the first local row
6278: -  n - one more than the global index of the last local row

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

6285:    Level: beginner

6287:    Concepts: matrices^row ownership

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

6291: @*/
6292: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6293: {
6299:   MatCheckPreallocated(mat,1);
6300:   if (m) *m = mat->rmap->rstart;
6301:   if (n) *n = mat->rmap->rend;
6302:   return(0);
6303: }

6307: /*@C
6308:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6309:    each process

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

6313:    Input Parameters:
6314: .  mat - the matrix

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

6319:    Level: beginner

6321:    Concepts: matrices^row ownership

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

6325: @*/
6326: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6327: {

6333:   MatCheckPreallocated(mat,1);
6334:   PetscLayoutGetRanges(mat->rmap,ranges);
6335:   return(0);
6336: }

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

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

6346:    Input Parameters:
6347: .  mat - the matrix

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

6352:    Level: beginner

6354:    Concepts: matrices^column ownership

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

6358: @*/
6359: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6360: {

6366:   MatCheckPreallocated(mat,1);
6367:   PetscLayoutGetRanges(mat->cmap,ranges);
6368:   return(0);
6369: }

6373: /*@C
6374:    MatGetOwnershipIS - Get row and column ownership as index sets

6376:    Not Collective

6378:    Input Arguments:
6379: .  A - matrix of type Elemental

6381:    Output Arguments:
6382: +  rows - rows in which this process owns elements
6383: .  cols - columns in which this process owns elements

6385:    Level: intermediate

6387: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6388: @*/
6389: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6390: {
6391:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6394:   MatCheckPreallocated(A,1);
6395:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6396:   if (f) {
6397:     (*f)(A,rows,cols);
6398:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6399:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6400:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6401:   }
6402:   return(0);
6403: }

6407: /*@C
6408:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6409:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6410:    to complete the factorization.

6412:    Collective on Mat

6414:    Input Parameters:
6415: +  mat - the matrix
6416: .  row - row permutation
6417: .  column - column permutation
6418: -  info - structure containing
6419: $      levels - number of levels of fill.
6420: $      expected fill - as ratio of original fill.
6421: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6422:                 missing diagonal entries)

6424:    Output Parameters:
6425: .  fact - new matrix that has been symbolically factored

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

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

6433:    Level: developer

6435:   Concepts: matrices^symbolic LU factorization
6436:   Concepts: matrices^factorization
6437:   Concepts: LU^symbolic factorization

6439: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6440:           MatGetOrdering(), MatFactorInfo

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

6445: @*/
6446: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6447: {

6457:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6458:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6459:   if (!(fact)->ops->ilufactorsymbolic) {
6460:     const MatSolverPackage spackage;
6461:     MatFactorGetSolverPackage(fact,&spackage);
6462:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6463:   }
6464:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6465:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6466:   MatCheckPreallocated(mat,2);

6468:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6469:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6470:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6471:   return(0);
6472: }

6476: /*@C
6477:    MatICCFactorSymbolic - Performs symbolic incomplete
6478:    Cholesky factorization for a symmetric matrix.  Use
6479:    MatCholeskyFactorNumeric() to complete the factorization.

6481:    Collective on Mat

6483:    Input Parameters:
6484: +  mat - the matrix
6485: .  perm - row and column permutation
6486: -  info - structure containing
6487: $      levels - number of levels of fill.
6488: $      expected fill - as ratio of original fill.

6490:    Output Parameter:
6491: .  fact - the factored matrix

6493:    Notes:
6494:    Most users should employ the KSP interface for linear solvers
6495:    instead of working directly with matrix algebra routines such as this.
6496:    See, e.g., KSPCreate().

6498:    Level: developer

6500:   Concepts: matrices^symbolic incomplete Cholesky factorization
6501:   Concepts: matrices^factorization
6502:   Concepts: Cholsky^symbolic factorization

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

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

6509: @*/
6510: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6511: {

6520:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6521:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6522:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6523:   if (!(fact)->ops->iccfactorsymbolic) {
6524:     const MatSolverPackage spackage;
6525:     MatFactorGetSolverPackage(fact,&spackage);
6526:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6527:   }
6528:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6529:   MatCheckPreallocated(mat,2);

6531:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6532:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6533:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6534:   return(0);
6535: }

6539: /*@C
6540:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6541:    points to an array of valid matrices, they may be reused to store the new
6542:    submatrices.

6544:    Collective on Mat

6546:    Input Parameters:
6547: +  mat - the matrix
6548: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6549: .  irow, icol - index sets of rows and columns to extract
6550: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6552:    Output Parameter:
6553: .  submat - the array of submatrices

6555:    Notes:
6556:    MatGetSubMatrices() can extract ONLY sequential submatrices
6557:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6558:    to extract a parallel submatrix.

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

6563:    The index sets may not have duplicate entries.

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

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

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

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

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

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

6587:    Level: advanced

6589:    Concepts: matrices^accessing submatrices
6590:    Concepts: submatrices

6592: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6593: @*/
6594: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6595: {
6597:   PetscInt       i;
6598:   PetscBool      eq;

6603:   if (n) {
6608:   }
6610:   if (n && scall == MAT_REUSE_MATRIX) {
6613:   }
6614:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6615:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6616:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6617:   MatCheckPreallocated(mat,1);

6619:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6620:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6621:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6622:   for (i=0; i<n; i++) {
6623:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6624:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6625:       ISEqual(irow[i],icol[i],&eq);
6626:       if (eq) {
6627:         if (mat->symmetric) {
6628:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6629:         } else if (mat->hermitian) {
6630:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6631:         } else if (mat->structurally_symmetric) {
6632:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6633:         }
6634:       }
6635:     }
6636:   }
6637:   return(0);
6638: }

6642: PetscErrorCode  MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6643: {
6645:   PetscInt       i;
6646:   PetscBool      eq;

6651:   if (n) {
6656:   }
6658:   if (n && scall == MAT_REUSE_MATRIX) {
6661:   }
6662:   if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6663:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6664:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6665:   MatCheckPreallocated(mat,1);

6667:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6668:   (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6669:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6670:   for (i=0; i<n; i++) {
6671:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6672:       ISEqual(irow[i],icol[i],&eq);
6673:       if (eq) {
6674:         if (mat->symmetric) {
6675:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6676:         } else if (mat->hermitian) {
6677:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6678:         } else if (mat->structurally_symmetric) {
6679:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6680:         }
6681:       }
6682:     }
6683:   }
6684:   return(0);
6685: }

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

6692:    Collective on Mat

6694:    Input Parameters:
6695: +  n - the number of local matrices
6696: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6697:                        sequence of MatGetSubMatrices())

6699:    Level: advanced

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

6704: .seealso: MatGetSubMatrices()
6705: @*/
6706: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6707: {
6709:   PetscInt       i;

6712:   if (!*mat) return(0);
6713:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6715:   for (i=0; i<n; i++) {
6716:     MatDestroy(&(*mat)[i]);
6717:   }
6718:   /* memory is allocated even if n = 0 */
6719:   PetscFree(*mat);
6720:   *mat = NULL;
6721:   return(0);
6722: }

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

6729:    Collective on Mat

6731:    Input Parameters:
6732: .  mat - the matrix

6734:    Output Parameter:
6735: .  matstruct - the sequential matrix with the nonzero structure of mat

6737:   Level: intermediate

6739: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6740: @*/
6741: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6742: {


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

6753:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6754:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6755:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6756:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6757:   return(0);
6758: }

6762: /*@C
6763:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6765:    Collective on Mat

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

6771:    Level: advanced

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

6775: .seealso: MatGetSeqNonzeroStructure()
6776: @*/
6777: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6778: {

6783:   MatDestroy(mat);
6784:   return(0);
6785: }

6789: /*@
6790:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6791:    replaces the index sets by larger ones that represent submatrices with
6792:    additional overlap.

6794:    Collective on Mat

6796:    Input Parameters:
6797: +  mat - the matrix
6798: .  n   - the number of index sets
6799: .  is  - the array of index sets (these index sets will changed during the call)
6800: -  ov  - the additional overlap requested

6802:    Level: developer

6804:    Concepts: overlap
6805:    Concepts: ASM^computing overlap

6807: .seealso: MatGetSubMatrices()
6808: @*/
6809: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6810: {

6816:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6817:   if (n) {
6820:   }
6821:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6822:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6823:   MatCheckPreallocated(mat,1);

6825:   if (!ov) return(0);
6826:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6827:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6828:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6829:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6830:   return(0);
6831: }

6835: /*@
6836:    MatGetBlockSize - Returns the matrix block size.

6838:    Not Collective

6840:    Input Parameter:
6841: .  mat - the matrix

6843:    Output Parameter:
6844: .  bs - block size

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

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

6851:    Level: intermediate

6853:    Concepts: matrices^block size

6855: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6856: @*/
6857: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6858: {
6862:   *bs = PetscAbs(mat->rmap->bs);
6863:   return(0);
6864: }

6868: /*@
6869:    MatGetBlockSizes - Returns the matrix block row and column sizes.

6871:    Not Collective

6873:    Input Parameter:
6874: .  mat - the matrix

6876:    Output Parameter:
6877: .  rbs - row block size
6878: .  cbs - coumn block size

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

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

6886:    Level: intermediate

6888:    Concepts: matrices^block size

6890: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
6891: @*/
6892: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6893: {
6898:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
6899:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
6900:   return(0);
6901: }

6905: /*@
6906:    MatSetBlockSize - Sets the matrix block size.

6908:    Logically Collective on Mat

6910:    Input Parameters:
6911: +  mat - the matrix
6912: -  bs - block size

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

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

6919:    Level: intermediate

6921:    Concepts: matrices^block size

6923: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
6924: @*/
6925: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6926: {

6932:   PetscLayoutSetBlockSize(mat->rmap,bs);
6933:   PetscLayoutSetBlockSize(mat->cmap,bs);
6934:   return(0);
6935: }

6939: /*@
6940:    MatSetBlockSizes - Sets the matrix block row and column sizes.

6942:    Logically Collective on Mat

6944:    Input Parameters:
6945: +  mat - the matrix
6946: -  rbs - row block size
6947: -  cbs - column block size

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

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

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

6957:    Level: intermediate

6959:    Concepts: matrices^block size

6961: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
6962: @*/
6963: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6964: {

6971:   PetscLayoutSetBlockSize(mat->rmap,rbs);
6972:   PetscLayoutSetBlockSize(mat->cmap,cbs);
6973:   return(0);
6974: }

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

6981:    Logically Collective on Mat

6983:    Input Parameters:
6984: +  mat - the matrix
6985: .  fromRow - matrix from which to copy row block size
6986: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

6988:    Level: developer

6990:    Concepts: matrices^block size

6992: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
6993: @*/
6994: PetscErrorCode  MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
6995: {

7002:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7003:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7004:   return(0);
7005: }

7009: /*@
7010:    MatResidual - Default routine to calculate the residual.

7012:    Collective on Mat and Vec

7014:    Input Parameters:
7015: +  mat - the matrix
7016: .  b   - the right-hand-side
7017: -  x   - the approximate solution

7019:    Output Parameter:
7020: .  r - location to store the residual

7022:    Level: developer

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

7026: .seealso: PCMGSetResidual()
7027: @*/
7028: PetscErrorCode  MatResidual(Mat mat,Vec b,Vec x,Vec r)
7029: {

7038:   MatCheckPreallocated(mat,1);
7039:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7040:   if (!mat->ops->residual) {
7041:     MatMult(mat,x,r);
7042:     VecAYPX(r,-1.0,b);
7043:   } else {
7044:     (*mat->ops->residual)(mat,b,x,r);
7045:   }
7046:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7047:   return(0);
7048: }

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

7055:    Collective on Mat

7057:     Input Parameters:
7058: +   mat - the matrix
7059: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7060: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7061: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7062:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7063:                  always used.

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

7072:     Level: developer

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

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

7078:     Fortran Node

7080:            In Fortran use
7081: $           PetscInt ia(1), ja(1)
7082: $           PetscOffset iia, jja
7083: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7084: $
7085: $          or
7086: $
7087: $           PetscScalar, pointer :: xx_v(:)
7088: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)


7091:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

7093: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7094: @*/
7095: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7096: {

7106:   MatCheckPreallocated(mat,1);
7107:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7108:   else {
7109:     *done = PETSC_TRUE;
7110:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7111:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7112:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7113:   }
7114:   return(0);
7115: }

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

7122:     Collective on Mat

7124:     Input Parameters:
7125: +   mat - the matrix
7126: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7127: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7128:                 symmetrized
7129: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7130:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7131:                  always used.
7132: .   n - number of columns in the (possibly compressed) matrix
7133: .   ia - the column pointers
7134: -   ja - the row indices

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

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

7144:     Level: developer

7146: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7147: @*/
7148: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7149: {

7159:   MatCheckPreallocated(mat,1);
7160:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7161:   else {
7162:     *done = PETSC_TRUE;
7163:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7164:   }
7165:   return(0);
7166: }

7170: /*@C
7171:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7172:     MatGetRowIJ().

7174:     Collective on Mat

7176:     Input Parameters:
7177: +   mat - the matrix
7178: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7179: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7180:                 symmetrized
7181: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7182:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7183:                  always used.
7184: .   n - size of (possibly compressed) matrix
7185: .   ia - the row pointers
7186: -   ja - the column indices

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

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

7196:     Level: developer

7198: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7199: @*/
7200: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7201: {

7210:   MatCheckPreallocated(mat,1);

7212:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7213:   else {
7214:     *done = PETSC_TRUE;
7215:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7216:     if (n)  *n = 0;
7217:     if (ia) *ia = NULL;
7218:     if (ja) *ja = NULL;
7219:   }
7220:   return(0);
7221: }

7225: /*@C
7226:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7227:     MatGetColumnIJ().

7229:     Collective on Mat

7231:     Input Parameters:
7232: +   mat - the matrix
7233: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7234: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7235:                 symmetrized
7236: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7237:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7238:                  always used.

7240:     Output Parameters:
7241: +   n - size of (possibly compressed) matrix
7242: .   ia - the column pointers
7243: .   ja - the row indices
7244: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7246:     Level: developer

7248: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7249: @*/
7250: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7251: {

7260:   MatCheckPreallocated(mat,1);

7262:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7263:   else {
7264:     *done = PETSC_TRUE;
7265:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7266:     if (n)  *n = 0;
7267:     if (ia) *ia = NULL;
7268:     if (ja) *ja = NULL;
7269:   }
7270:   return(0);
7271: }

7275: /*@C
7276:     MatColoringPatch -Used inside matrix coloring routines that
7277:     use MatGetRowIJ() and/or MatGetColumnIJ().

7279:     Collective on Mat

7281:     Input Parameters:
7282: +   mat - the matrix
7283: .   ncolors - max color value
7284: .   n   - number of entries in colorarray
7285: -   colorarray - array indicating color for each column

7287:     Output Parameters:
7288: .   iscoloring - coloring generated using colorarray information

7290:     Level: developer

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

7294: @*/
7295: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7296: {

7304:   MatCheckPreallocated(mat,1);

7306:   if (!mat->ops->coloringpatch) {
7307:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7308:   } else {
7309:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7310:   }
7311:   return(0);
7312: }


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

7320:    Logically Collective on Mat

7322:    Input Parameter:
7323: .  mat - the factored matrix to be reset

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

7332:    Note that one can specify in-place ILU(0) factorization by calling
7333: .vb
7334:      PCType(pc,PCILU);
7335:      PCFactorSeUseInPlace(pc);
7336: .ve
7337:    or by using the options -pc_type ilu -pc_factor_in_place

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

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

7348:    Level: developer

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

7352:    Concepts: matrices^unfactored

7354: @*/
7355: PetscErrorCode  MatSetUnfactored(Mat mat)
7356: {

7362:   MatCheckPreallocated(mat,1);
7363:   mat->factortype = MAT_FACTOR_NONE;
7364:   if (!mat->ops->setunfactored) return(0);
7365:   (*mat->ops->setunfactored)(mat);
7366:   return(0);
7367: }

7369: /*MC
7370:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7372:     Synopsis:
7373:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7375:     Not collective

7377:     Input Parameter:
7378: .   x - matrix

7380:     Output Parameters:
7381: +   xx_v - the Fortran90 pointer to the array
7382: -   ierr - error code

7384:     Example of Usage:
7385: .vb
7386:       PetscScalar, pointer xx_v(:,:)
7387:       ....
7388:       call MatDenseGetArrayF90(x,xx_v,ierr)
7389:       a = xx_v(3)
7390:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7391: .ve

7393:     Level: advanced

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

7397:     Concepts: matrices^accessing array

7399: M*/

7401: /*MC
7402:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7403:     accessed with MatDenseGetArrayF90().

7405:     Synopsis:
7406:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7408:     Not collective

7410:     Input Parameters:
7411: +   x - matrix
7412: -   xx_v - the Fortran90 pointer to the array

7414:     Output Parameter:
7415: .   ierr - error code

7417:     Example of Usage:
7418: .vb
7419:        PetscScalar, pointer xx_v(:)
7420:        ....
7421:        call MatDenseGetArrayF90(x,xx_v,ierr)
7422:        a = xx_v(3)
7423:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7424: .ve

7426:     Level: advanced

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

7430: M*/


7433: /*MC
7434:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7436:     Synopsis:
7437:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7439:     Not collective

7441:     Input Parameter:
7442: .   x - matrix

7444:     Output Parameters:
7445: +   xx_v - the Fortran90 pointer to the array
7446: -   ierr - error code

7448:     Example of Usage:
7449: .vb
7450:       PetscScalar, pointer xx_v(:,:)
7451:       ....
7452:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7453:       a = xx_v(3)
7454:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7455: .ve

7457:     Level: advanced

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

7461:     Concepts: matrices^accessing array

7463: M*/

7465: /*MC
7466:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7467:     accessed with MatSeqAIJGetArrayF90().

7469:     Synopsis:
7470:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7472:     Not collective

7474:     Input Parameters:
7475: +   x - matrix
7476: -   xx_v - the Fortran90 pointer to the array

7478:     Output Parameter:
7479: .   ierr - error code

7481:     Example of Usage:
7482: .vb
7483:        PetscScalar, pointer xx_v(:)
7484:        ....
7485:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7486:        a = xx_v(3)
7487:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7488: .ve

7490:     Level: advanced

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

7494: M*/


7499: /*@
7500:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7501:                       as the original matrix.

7503:     Collective on Mat

7505:     Input Parameters:
7506: +   mat - the original matrix
7507: .   isrow - parallel IS containing the rows this processor should obtain
7508: .   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.
7509: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7511:     Output Parameter:
7512: .   newmat - the new submatrix, of the same type as the old

7514:     Level: advanced

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

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

7522:     The index sets may not have duplicate entries.

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

7530:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7531:     the input matrix.

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

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

7541: .vb
7542:             1  2  0  |  0  3  0  |  0  4
7543:     Proc0   0  5  6  |  7  0  0  |  8  0
7544:             9  0 10  | 11  0  0  | 12  0
7545:     -------------------------------------
7546:            13  0 14  | 15 16 17  |  0  0
7547:     Proc1   0 18  0  | 19 20 21  |  0  0
7548:             0  0  0  | 22 23  0  | 24  0
7549:     -------------------------------------
7550:     Proc2  25 26 27  |  0  0 28  | 29  0
7551:            30  0  0  | 31 32 33  |  0 34
7552: .ve

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

7556: .vb
7557:             2  0  |  0  3  0  |  0
7558:     Proc0   5  6  |  7  0  0  |  8
7559:     -------------------------------
7560:     Proc1  18  0  | 19 20 21  |  0
7561:     -------------------------------
7562:     Proc2  26 27  |  0  0 28  | 29
7563:             0  0  | 31 32 33  |  0
7564: .ve


7567:     Concepts: matrices^submatrices

7569: .seealso: MatGetSubMatrices()
7570: @*/
7571: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7572: {
7574:   PetscMPIInt    size;
7575:   Mat            *local;
7576:   IS             iscoltmp;

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

7588:   MatCheckPreallocated(mat,1);
7589:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7591:   if (!iscol || isrow == iscol) {
7592:     PetscBool   stride;
7593:     PetscMPIInt grabentirematrix = 0,grab;
7594:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7595:     if (stride) {
7596:       PetscInt first,step,n,rstart,rend;
7597:       ISStrideGetInfo(isrow,&first,&step);
7598:       if (step == 1) {
7599:         MatGetOwnershipRange(mat,&rstart,&rend);
7600:         if (rstart == first) {
7601:           ISGetLocalSize(isrow,&n);
7602:           if (n == rend-rstart) {
7603:             grabentirematrix = 1;
7604:           }
7605:         }
7606:       }
7607:     }
7608:     MPI_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7609:     if (grab) {
7610:       PetscInfo(mat,"Getting entire matrix as submatrix\n");
7611:       if (cll == MAT_INITIAL_MATRIX) {
7612:         *newmat = mat;
7613:         PetscObjectReference((PetscObject)mat);
7614:       }
7615:       return(0);
7616:     }
7617:   }

7619:   if (!iscol) {
7620:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7621:   } else {
7622:     iscoltmp = iscol;
7623:   }

7625:   /* if original matrix is on just one processor then use submatrix generated */
7626:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7627:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7628:     if (!iscol) {ISDestroy(&iscoltmp);}
7629:     return(0);
7630:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7631:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7632:     *newmat = *local;
7633:     PetscFree(local);
7634:     if (!iscol) {ISDestroy(&iscoltmp);}
7635:     return(0);
7636:   } else if (!mat->ops->getsubmatrix) {
7637:     /* Create a new matrix type that implements the operation using the full matrix */
7638:     PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7639:     switch (cll) {
7640:     case MAT_INITIAL_MATRIX:
7641:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7642:       break;
7643:     case MAT_REUSE_MATRIX:
7644:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7645:       break;
7646:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7647:     }
7648:     PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7649:     if (!iscol) {ISDestroy(&iscoltmp);}
7650:     return(0);
7651:   }

7653:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7654:   PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7655:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7656:   PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7657:   if (!iscol) {ISDestroy(&iscoltmp);}
7658:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7659:   return(0);
7660: }

7664: /*@
7665:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7666:    used during the assembly process to store values that belong to
7667:    other processors.

7669:    Not Collective

7671:    Input Parameters:
7672: +  mat   - the matrix
7673: .  size  - the initial size of the stash.
7674: -  bsize - the initial size of the block-stash(if used).

7676:    Options Database Keys:
7677: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7678: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7680:    Level: intermediate

7682:    Notes:
7683:      The block-stash is used for values set with MatSetValuesBlocked() while
7684:      the stash is used for values set with MatSetValues()

7686:      Run with the option -info and look for output of the form
7687:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7688:      to determine the appropriate value, MM, to use for size and
7689:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7690:      to determine the value, BMM to use for bsize

7692:    Concepts: stash^setting matrix size
7693:    Concepts: matrices^stash

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

7697: @*/
7698: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7699: {

7705:   MatStashSetInitialSize_Private(&mat->stash,size);
7706:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7707:   return(0);
7708: }

7712: /*@
7713:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7714:      the matrix

7716:    Neighbor-wise Collective on Mat

7718:    Input Parameters:
7719: +  mat   - the matrix
7720: .  x,y - the vectors
7721: -  w - where the result is stored

7723:    Level: intermediate

7725:    Notes:
7726:     w may be the same vector as y.

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

7731:     Concepts: interpolation

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

7735: @*/
7736: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7737: {
7739:   PetscInt       M,N,Ny;

7747:   MatCheckPreallocated(A,1);
7748:   MatGetSize(A,&M,&N);
7749:   VecGetSize(y,&Ny);
7750:   if (M == Ny) {
7751:     MatMultAdd(A,x,y,w);
7752:   } else {
7753:     MatMultTransposeAdd(A,x,y,w);
7754:   }
7755:   return(0);
7756: }

7760: /*@
7761:    MatInterpolate - y = A*x or A'*x depending on the shape of
7762:      the matrix

7764:    Neighbor-wise Collective on Mat

7766:    Input Parameters:
7767: +  mat   - the matrix
7768: -  x,y - the vectors

7770:    Level: intermediate

7772:    Notes:
7773:     This allows one to use either the restriction or interpolation (its transpose)
7774:     matrix to do the interpolation

7776:    Concepts: matrices^interpolation

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

7780: @*/
7781: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7782: {
7784:   PetscInt       M,N,Ny;

7791:   MatCheckPreallocated(A,1);
7792:   MatGetSize(A,&M,&N);
7793:   VecGetSize(y,&Ny);
7794:   if (M == Ny) {
7795:     MatMult(A,x,y);
7796:   } else {
7797:     MatMultTranspose(A,x,y);
7798:   }
7799:   return(0);
7800: }

7804: /*@
7805:    MatRestrict - y = A*x or A'*x

7807:    Neighbor-wise Collective on Mat

7809:    Input Parameters:
7810: +  mat   - the matrix
7811: -  x,y - the vectors

7813:    Level: intermediate

7815:    Notes:
7816:     This allows one to use either the restriction or interpolation (its transpose)
7817:     matrix to do the restriction

7819:    Concepts: matrices^restriction

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

7823: @*/
7824: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7825: {
7827:   PetscInt       M,N,Ny;

7834:   MatCheckPreallocated(A,1);

7836:   MatGetSize(A,&M,&N);
7837:   VecGetSize(y,&Ny);
7838:   if (M == Ny) {
7839:     MatMult(A,x,y);
7840:   } else {
7841:     MatMultTranspose(A,x,y);
7842:   }
7843:   return(0);
7844: }

7848: /*@
7849:    MatGetNullSpace - retrieves the null space to a matrix.

7851:    Logically Collective on Mat and MatNullSpace

7853:    Input Parameters:
7854: +  mat - the matrix
7855: -  nullsp - the null space object

7857:    Level: developer

7859:    Concepts: null space^attaching to matrix

7861: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
7862: @*/
7863: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7864: {
7869:   *nullsp = mat->nullsp;
7870:   return(0);
7871: }

7875: /*@
7876:    MatSetNullSpace - attaches a null space to a matrix.

7878:    Logically Collective on Mat and MatNullSpace

7880:    Input Parameters:
7881: +  mat - the matrix
7882: -  nullsp - the null space object

7884:    Level: advanced

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

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


7893:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
7894:    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).
7895:    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
7896:    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
7897:    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).

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

7901:    Concepts: null space^attaching to matrix

7903: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
7904: @*/
7905: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7906: {

7913:   MatCheckPreallocated(mat,1);
7914:   PetscObjectReference((PetscObject)nullsp);
7915:   MatNullSpaceDestroy(&mat->nullsp);
7916:   mat->nullsp = nullsp;
7917:   return(0);
7918: }

7922: /*@
7923:    MatGetTransposeNullSpace - retrieves the null space to a matrix.

7925:    Logically Collective on Mat and MatNullSpace

7927:    Input Parameters:
7928: +  mat - the matrix
7929: -  nullsp - the null space object

7931:    Level: developer

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

7936:    Concepts: null space^attaching to matrix

7938: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7939: @*/
7940: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
7941: {
7946:   *nullsp = mat->transnullsp;
7947:   return(0);
7948: }

7952: /*@
7953:    MatSetTransposeNullSpace - attaches a null space to a matrix.

7955:    Logically Collective on Mat and MatNullSpace

7957:    Input Parameters:
7958: +  mat - the matrix
7959: -  nullsp - the null space object

7961:    Level: advanced

7963:    Notes:
7964:       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.
7965:       You must also call MatSetNullSpace()


7968:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
7969:    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).
7970:    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
7971:    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
7972:    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).

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

7976:    Concepts: null space^attaching to matrix

7978: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetNullSpace(), MatNullSpaceRemove()
7979: @*/
7980: PetscErrorCode  MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
7981: {

7988:   MatCheckPreallocated(mat,1);
7989:   PetscObjectReference((PetscObject)nullsp);
7990:   MatNullSpaceDestroy(&mat->transnullsp);
7991:   mat->transnullsp = nullsp;
7992:   return(0);
7993: }

7997: /*@
7998:    MatSetNearNullSpace - attaches a null space to a matrix.
7999:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

8001:    Logically Collective on Mat and MatNullSpace

8003:    Input Parameters:
8004: +  mat - the matrix
8005: -  nullsp - the null space object

8007:    Level: advanced

8009:    Notes:
8010:       Overwrites any previous near null space that may have been attached

8012:    Concepts: null space^attaching to matrix

8014: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
8015: @*/
8016: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8017: {

8024:   MatCheckPreallocated(mat,1);
8025:   PetscObjectReference((PetscObject)nullsp);
8026:   MatNullSpaceDestroy(&mat->nearnullsp);

8028:   mat->nearnullsp = nullsp;
8029:   return(0);
8030: }

8034: /*@
8035:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

8037:    Not Collective

8039:    Input Parameters:
8040: .  mat - the matrix

8042:    Output Parameters:
8043: .  nullsp - the null space object, NULL if not set

8045:    Level: developer

8047:    Concepts: null space^attaching to matrix

8049: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
8050: @*/
8051: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8052: {
8057:   MatCheckPreallocated(mat,1);
8058:   *nullsp = mat->nearnullsp;
8059:   return(0);
8060: }

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

8067:    Collective on Mat

8069:    Input Parameters:
8070: +  mat - the matrix
8071: .  row - row/column permutation
8072: .  fill - expected fill factor >= 1.0
8073: -  level - level of fill, for ICC(k)

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

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

8083:    Level: developer

8085:    Concepts: matrices^incomplete Cholesky factorization
8086:    Concepts: Cholesky factorization

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

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

8093: @*/
8094: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8095: {

8103:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8104:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8105:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8106:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8107:   MatCheckPreallocated(mat,1);
8108:   (*mat->ops->iccfactor)(mat,row,info);
8109:   PetscObjectStateIncrease((PetscObject)mat);
8110:   return(0);
8111: }

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

8118:    Not Collective

8120:    Input Parameters:
8121: +  mat - the matrix
8122: .  nl - leading dimension of v
8123: -  v - the values compute with ADIFOR

8125:    Level: developer

8127:    Notes:
8128:      Must call MatSetColoring() before using this routine. Also this matrix must already
8129:      have its nonzero pattern determined.

8131: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8132:           MatSetValues(), MatSetColoring()
8133: @*/
8134: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8135: {


8143:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8144:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
8145:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8146:   (*mat->ops->setvaluesadifor)(mat,nl,v);
8147:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
8148:   PetscObjectStateIncrease((PetscObject)mat);
8149:   return(0);
8150: }

8154: /*@
8155:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8156:          ghosted ones.

8158:    Not Collective

8160:    Input Parameters:
8161: +  mat - the matrix
8162: -  diag = the diagonal values, including ghost ones

8164:    Level: developer

8166:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

8168: .seealso: MatDiagonalScale()
8169: @*/
8170: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
8171: {
8173:   PetscMPIInt    size;


8180:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8181:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8182:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8183:   if (size == 1) {
8184:     PetscInt n,m;
8185:     VecGetSize(diag,&n);
8186:     MatGetSize(mat,0,&m);
8187:     if (m == n) {
8188:       MatDiagonalScale(mat,0,diag);
8189:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8190:   } else {
8191:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8192:   }
8193:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8194:   PetscObjectStateIncrease((PetscObject)mat);
8195:   return(0);
8196: }

8200: /*@
8201:    MatGetInertia - Gets the inertia from a factored matrix

8203:    Collective on Mat

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

8208:    Output Parameters:
8209: +   nneg - number of negative eigenvalues
8210: .   nzero - number of zero eigenvalues
8211: -   npos - number of positive eigenvalues

8213:    Level: advanced

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


8218: @*/
8219: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8220: {

8226:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8227:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8228:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8229:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8230:   return(0);
8231: }

8233: /* ----------------------------------------------------------------*/
8236: /*@C
8237:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

8239:    Neighbor-wise Collective on Mat and Vecs

8241:    Input Parameters:
8242: +  mat - the factored matrix
8243: -  b - the right-hand-side vectors

8245:    Output Parameter:
8246: .  x - the result vectors

8248:    Notes:
8249:    The vectors b and x cannot be the same.  I.e., one cannot
8250:    call MatSolves(A,x,x).

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

8257:    Level: developer

8259:    Concepts: matrices^triangular solves

8261: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8262: @*/
8263: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
8264: {

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

8274:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8275:   MatCheckPreallocated(mat,1);
8276:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8277:   (*mat->ops->solves)(mat,b,x);
8278:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8279:   return(0);
8280: }

8284: /*@
8285:    MatIsSymmetric - Test whether a matrix is symmetric

8287:    Collective on Mat

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

8293:    Output Parameters:
8294: .  flg - the result

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

8298:    Level: intermediate

8300:    Concepts: matrix^symmetry

8302: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8303: @*/
8304: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8305: {


8312:   if (!A->symmetric_set) {
8313:     if (!A->ops->issymmetric) {
8314:       MatType mattype;
8315:       MatGetType(A,&mattype);
8316:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8317:     }
8318:     (*A->ops->issymmetric)(A,tol,flg);
8319:     if (!tol) {
8320:       A->symmetric_set = PETSC_TRUE;
8321:       A->symmetric     = *flg;
8322:       if (A->symmetric) {
8323:         A->structurally_symmetric_set = PETSC_TRUE;
8324:         A->structurally_symmetric     = PETSC_TRUE;
8325:       }
8326:     }
8327:   } else if (A->symmetric) {
8328:     *flg = PETSC_TRUE;
8329:   } else if (!tol) {
8330:     *flg = PETSC_FALSE;
8331:   } else {
8332:     if (!A->ops->issymmetric) {
8333:       MatType mattype;
8334:       MatGetType(A,&mattype);
8335:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8336:     }
8337:     (*A->ops->issymmetric)(A,tol,flg);
8338:   }
8339:   return(0);
8340: }

8344: /*@
8345:    MatIsHermitian - Test whether a matrix is Hermitian

8347:    Collective on Mat

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

8353:    Output Parameters:
8354: .  flg - the result

8356:    Level: intermediate

8358:    Concepts: matrix^symmetry

8360: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8361:           MatIsSymmetricKnown(), MatIsSymmetric()
8362: @*/
8363: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8364: {


8371:   if (!A->hermitian_set) {
8372:     if (!A->ops->ishermitian) {
8373:       MatType mattype;
8374:       MatGetType(A,&mattype);
8375:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8376:     }
8377:     (*A->ops->ishermitian)(A,tol,flg);
8378:     if (!tol) {
8379:       A->hermitian_set = PETSC_TRUE;
8380:       A->hermitian     = *flg;
8381:       if (A->hermitian) {
8382:         A->structurally_symmetric_set = PETSC_TRUE;
8383:         A->structurally_symmetric     = PETSC_TRUE;
8384:       }
8385:     }
8386:   } else if (A->hermitian) {
8387:     *flg = PETSC_TRUE;
8388:   } else if (!tol) {
8389:     *flg = PETSC_FALSE;
8390:   } else {
8391:     if (!A->ops->ishermitian) {
8392:       MatType mattype;
8393:       MatGetType(A,&mattype);
8394:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8395:     }
8396:     (*A->ops->ishermitian)(A,tol,flg);
8397:   }
8398:   return(0);
8399: }

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

8406:    Not Collective

8408:    Input Parameter:
8409: .  A - the matrix to check

8411:    Output Parameters:
8412: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8413: -  flg - the result

8415:    Level: advanced

8417:    Concepts: matrix^symmetry

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

8422: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8423: @*/
8424: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8425: {
8430:   if (A->symmetric_set) {
8431:     *set = PETSC_TRUE;
8432:     *flg = A->symmetric;
8433:   } else {
8434:     *set = PETSC_FALSE;
8435:   }
8436:   return(0);
8437: }

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

8444:    Not Collective

8446:    Input Parameter:
8447: .  A - the matrix to check

8449:    Output Parameters:
8450: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8451: -  flg - the result

8453:    Level: advanced

8455:    Concepts: matrix^symmetry

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

8460: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8461: @*/
8462: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8463: {
8468:   if (A->hermitian_set) {
8469:     *set = PETSC_TRUE;
8470:     *flg = A->hermitian;
8471:   } else {
8472:     *set = PETSC_FALSE;
8473:   }
8474:   return(0);
8475: }

8479: /*@
8480:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8482:    Collective on Mat

8484:    Input Parameter:
8485: .  A - the matrix to test

8487:    Output Parameters:
8488: .  flg - the result

8490:    Level: intermediate

8492:    Concepts: matrix^symmetry

8494: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8495: @*/
8496: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8497: {

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

8507:     A->structurally_symmetric_set = PETSC_TRUE;
8508:   }
8509:   *flg = A->structurally_symmetric;
8510:   return(0);
8511: }

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

8520:     Not collective

8522:    Input Parameter:
8523: .   vec - the vector

8525:    Output Parameters:
8526: +   nstash   - the size of the stash
8527: .   reallocs - the number of additional mallocs incurred.
8528: .   bnstash   - the size of the block stash
8529: -   breallocs - the number of additional mallocs incurred.in the block stash

8531:    Level: advanced

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

8535: @*/
8536: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8537: {

8541:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8542:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8543:   return(0);
8544: }

8548: /*@C
8549:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8550:      parallel layout

8552:    Collective on Mat

8554:    Input Parameter:
8555: .  mat - the matrix

8557:    Output Parameter:
8558: +   right - (optional) vector that the matrix can be multiplied against
8559: -   left - (optional) vector that the matrix vector product can be stored in

8561:    Notes:
8562:     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().

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

8566:   Level: advanced

8568: .seealso: MatCreate(), VecDestroy()
8569: @*/
8570: PetscErrorCode  MatCreateVecs(Mat mat,Vec *right,Vec *left)
8571: {

8577:   MatCheckPreallocated(mat,1);
8578:   if (mat->ops->getvecs) {
8579:     (*mat->ops->getvecs)(mat,right,left);
8580:   } else {
8581:     PetscMPIInt size;
8582:     PetscInt    rbs,cbs;
8583:     MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8584:     MatGetBlockSizes(mat,&rbs,&cbs);
8585:     if (right) {
8586:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8587:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8588:       VecSetBlockSize(*right,cbs);
8589:       VecSetType(*right,VECSTANDARD);
8590:       PetscLayoutReference(mat->cmap,&(*right)->map);
8591:     }
8592:     if (left) {
8593:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8594:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8595:       VecSetBlockSize(*left,rbs);
8596:       VecSetType(*left,VECSTANDARD);
8597:       PetscLayoutReference(mat->rmap,&(*left)->map);
8598:     }
8599:   }
8600:   return(0);
8601: }

8605: /*@C
8606:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8607:      with default values.

8609:    Not Collective

8611:    Input Parameters:
8612: .    info - the MatFactorInfo data structure


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

8618:    Level: developer

8620: .seealso: MatFactorInfo

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

8625: @*/

8627: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8628: {

8632:   PetscMemzero(info,sizeof(MatFactorInfo));
8633:   return(0);
8634: }

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

8641:    Neighbor-wise Collective on Mat

8643:    Input Parameters:
8644: +  A - the matrix
8645: .  P - the projection matrix
8646: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8647: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

8649:    Output Parameters:
8650: .  C - the product matrix

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

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

8658:    Level: intermediate

8660: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8661: @*/
8662: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8663: {
8665:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8666:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8667:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8668:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

8671:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8672:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

8676:   MatCheckPreallocated(A,1);
8677:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8678:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8681:   MatCheckPreallocated(P,2);
8682:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8683:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8685:   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);
8686:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

8688:   if (scall == MAT_REUSE_MATRIX) {
8691:     if (viatranspose || viamatmatmatmult) {
8692:       Mat Pt;
8693:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8694:       if (viamatmatmatmult) {
8695:         MatMatMatMult(Pt,A,P,scall,fill,C);
8696:       } else {
8697:         Mat AP;
8698:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8699:         MatMatMult(Pt,AP,scall,fill,C);
8700:         MatDestroy(&AP);
8701:       }
8702:       MatDestroy(&Pt);
8703:     } else {
8704:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8705:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8706:       (*(*C)->ops->ptapnumeric)(A,P,*C);
8707:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8708:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8709:     }
8710:     return(0);
8711:   }

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

8716:   fA = A->ops->ptap;
8717:   fP = P->ops->ptap;
8718:   if (fP == fA) {
8719:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8720:     ptap = fA;
8721:   } else {
8722:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8723:     char ptapname[256];
8724:     PetscStrcpy(ptapname,"MatPtAP_");
8725:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
8726:     PetscStrcat(ptapname,"_");
8727:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
8728:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8729:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8730:     if (!ptap) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s",((PetscObject)A)->type_name,((PetscObject)P)->type_name);
8731:   }

8733:   if (viatranspose || viamatmatmatmult) {
8734:     Mat Pt;
8735:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8736:     if (viamatmatmatmult) {
8737:       MatMatMatMult(Pt,A,P,scall,fill,C);
8738:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8739:     } else {
8740:       Mat AP;
8741:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8742:       MatMatMult(Pt,AP,scall,fill,C);
8743:       MatDestroy(&AP);
8744:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8745:     }
8746:     MatDestroy(&Pt);
8747:   } else {
8748:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8749:     (*ptap)(A,P,scall,fill,C);
8750:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8751:   }
8752:   return(0);
8753: }

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

8760:    Neighbor-wise Collective on Mat

8762:    Input Parameters:
8763: +  A - the matrix
8764: -  P - the projection matrix

8766:    Output Parameters:
8767: .  C - the product matrix

8769:    Notes:
8770:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8771:    the user using MatDeatroy().

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

8776:    Level: intermediate

8778: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8779: @*/
8780: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8781: {

8787:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8788:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8791:   MatCheckPreallocated(P,2);
8792:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8793:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8796:   MatCheckPreallocated(C,3);
8797:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8798:   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);
8799:   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);
8800:   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);
8801:   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);
8802:   MatCheckPreallocated(A,1);

8804:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8805:   (*C->ops->ptapnumeric)(A,P,C);
8806:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8807:   return(0);
8808: }

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

8815:    Neighbor-wise Collective on Mat

8817:    Input Parameters:
8818: +  A - the matrix
8819: -  P - the projection matrix

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

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

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

8831:    Level: intermediate

8833: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8834: @*/
8835: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8836: {

8842:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8843:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8844:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8847:   MatCheckPreallocated(P,2);
8848:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8849:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8852:   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);
8853:   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);
8854:   MatCheckPreallocated(A,1);
8855:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8856:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8857:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

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

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

8868:    Neighbor-wise Collective on Mat

8870:    Input Parameters:
8871: +  A - the matrix
8872: .  R - the projection matrix
8873: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8874: -  fill - expected fill as ratio of nnz(C)/nnz(A)

8876:    Output Parameters:
8877: .  C - the product matrix

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

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

8885:    Level: intermediate

8887: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8888: @*/
8889: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8890: {

8896:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8897:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8900:   MatCheckPreallocated(R,2);
8901:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8902:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8904:   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);
8905:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8906:   MatCheckPreallocated(A,1);

8908:   if (!A->ops->rart) {
8909:     MatType mattype;
8910:     MatGetType(A,&mattype);
8911:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8912:   }
8913:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
8914:   (*A->ops->rart)(A,R,scall,fill,C);
8915:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
8916:   return(0);
8917: }

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

8924:    Neighbor-wise Collective on Mat

8926:    Input Parameters:
8927: +  A - the matrix
8928: -  R - the projection matrix

8930:    Output Parameters:
8931: .  C - the product matrix

8933:    Notes:
8934:    C must have been created by calling MatRARtSymbolic and must be destroyed by
8935:    the user using MatDeatroy().

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

8940:    Level: intermediate

8942: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8943: @*/
8944: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8945: {

8951:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8952:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8955:   MatCheckPreallocated(R,2);
8956:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8957:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8960:   MatCheckPreallocated(C,3);
8961:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8962:   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);
8963:   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);
8964:   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);
8965:   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);
8966:   MatCheckPreallocated(A,1);

8968:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8969:   (*A->ops->rartnumeric)(A,R,C);
8970:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8971:   return(0);
8972: }

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

8979:    Neighbor-wise Collective on Mat

8981:    Input Parameters:
8982: +  A - the matrix
8983: -  R - the projection matrix

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

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

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

8995:    Level: intermediate

8997: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8998: @*/
8999: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9000: {

9006:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9007:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9008:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9011:   MatCheckPreallocated(R,2);
9012:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9013:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9016:   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);
9017:   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);
9018:   MatCheckPreallocated(A,1);
9019:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9020:   (*A->ops->rartsymbolic)(A,R,fill,C);
9021:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

9023:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9024:   return(0);
9025: }

9029: /*@
9030:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

9032:    Neighbor-wise Collective on Mat

9034:    Input Parameters:
9035: +  A - the left matrix
9036: .  B - the right matrix
9037: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9038: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9039:           if the result is a dense matrix this is irrelevent

9041:    Output Parameters:
9042: .  C - the product matrix

9044:    Notes:
9045:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

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

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

9059:    Level: intermediate

9061: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9062: @*/
9063: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9064: {
9066:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9067:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9068:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9073:   MatCheckPreallocated(A,1);
9074:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9075:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9078:   MatCheckPreallocated(B,2);
9079:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9080:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9082:   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);
9083:   if (scall == MAT_REUSE_MATRIX) {
9086:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9087:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9088:     (*(*C)->ops->matmultnumeric)(A,B,*C);
9089:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9090:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9091:     return(0);
9092:   }
9093:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9094:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9096:   fA = A->ops->matmult;
9097:   fB = B->ops->matmult;
9098:   if (fB == fA) {
9099:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9100:     mult = fB;
9101:   } else {
9102:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9103:     char multname[256];
9104:     PetscStrcpy(multname,"MatMatMult_");
9105:     PetscStrcat(multname,((PetscObject)A)->type_name);
9106:     PetscStrcat(multname,"_");
9107:     PetscStrcat(multname,((PetscObject)B)->type_name);
9108:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9109:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9110:     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);
9111:   }
9112:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9113:   (*mult)(A,B,scall,fill,C);
9114:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9115:   return(0);
9116: }

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

9124:    Neighbor-wise Collective on Mat

9126:    Input Parameters:
9127: +  A - the left matrix
9128: .  B - the right matrix
9129: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9130:       if C is a dense matrix this is irrelevent

9132:    Output Parameters:
9133: .  C - the product matrix

9135:    Notes:
9136:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

9141:    This routine is currently implemented for
9142:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9143:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9144:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9146:    Level: intermediate

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

9151: .seealso: MatMatMult(), MatMatMultNumeric()
9152: @*/
9153: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9154: {
9156:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9157:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9158:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

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

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

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

9178:   Asymbolic = A->ops->matmultsymbolic;
9179:   Bsymbolic = B->ops->matmultsymbolic;
9180:   if (Asymbolic == Bsymbolic) {
9181:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9182:     symbolic = Bsymbolic;
9183:   } else { /* dispatch based on the type of A and B */
9184:     char symbolicname[256];
9185:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9186:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9187:     PetscStrcat(symbolicname,"_");
9188:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9189:     PetscStrcat(symbolicname,"_C");
9190:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9191:     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);
9192:   }
9193:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9194:   (*symbolic)(A,B,fill,C);
9195:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9196:   return(0);
9197: }

9201: /*@
9202:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9203:    Call this routine after first calling MatMatMultSymbolic().

9205:    Neighbor-wise Collective on Mat

9207:    Input Parameters:
9208: +  A - the left matrix
9209: -  B - the right matrix

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

9214:    Notes:
9215:    C must have been created with MatMatMultSymbolic().

9217:    This routine is currently implemented for
9218:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9219:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9220:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

9222:    Level: intermediate

9224: .seealso: MatMatMult(), MatMatMultSymbolic()
9225: @*/
9226: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
9227: {

9231:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9232:   return(0);
9233: }

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

9240:    Neighbor-wise Collective on Mat

9242:    Input Parameters:
9243: +  A - the left matrix
9244: .  B - the right matrix
9245: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9246: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9248:    Output Parameters:
9249: .  C - the product matrix

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

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

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

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

9261:    Level: intermediate

9263: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9264: @*/
9265: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9266: {
9268:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9269:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

9274:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9275:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9278:   MatCheckPreallocated(B,2);
9279:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9280:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9282:   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);
9283:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9284:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9285:   MatCheckPreallocated(A,1);

9287:   fA = A->ops->mattransposemult;
9288:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9289:   fB = B->ops->mattransposemult;
9290:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9291:   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);

9293:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9294:   if (scall == MAT_INITIAL_MATRIX) {
9295:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9296:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9297:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9298:   }
9299:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9300:   (*A->ops->mattransposemultnumeric)(A,B,*C);
9301:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9302:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9303:   return(0);
9304: }

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

9311:    Neighbor-wise Collective on Mat

9313:    Input Parameters:
9314: +  A - the left matrix
9315: .  B - the right matrix
9316: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9317: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

9319:    Output Parameters:
9320: .  C - the product matrix

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

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

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

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

9333:    Level: intermediate

9335: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9336: @*/
9337: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9338: {
9340:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9341:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9342:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

9347:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9348:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9351:   MatCheckPreallocated(B,2);
9352:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9353:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9355:   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);
9356:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9357:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9358:   MatCheckPreallocated(A,1);

9360:   fA = A->ops->transposematmult;
9361:   fB = B->ops->transposematmult;
9362:   if (fB==fA) {
9363:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9364:     transposematmult = fA;
9365:   } else {
9366:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9367:     char multname[256];
9368:     PetscStrcpy(multname,"MatTransposeMatMult_");
9369:     PetscStrcat(multname,((PetscObject)A)->type_name);
9370:     PetscStrcat(multname,"_");
9371:     PetscStrcat(multname,((PetscObject)B)->type_name);
9372:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9373:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9374:     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);
9375:   }
9376:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9377:   (*transposematmult)(A,B,scall,fill,C);
9378:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9379:   return(0);
9380: }

9384: /*@
9385:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

9387:    Neighbor-wise Collective on Mat

9389:    Input Parameters:
9390: +  A - the left matrix
9391: .  B - the middle matrix
9392: .  C - the right matrix
9393: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9394: -  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
9395:           if the result is a dense matrix this is irrelevent

9397:    Output Parameters:
9398: .  D - the product matrix

9400:    Notes:
9401:    Unless scall is MAT_REUSE_MATRIX D will be created.

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

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

9408:    If you have many matrices with the same non-zero structure to multiply, you
9409:    should either
9410: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9411: $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed

9413:    Level: intermediate

9415: .seealso: MatMatMult, MatPtAP()
9416: @*/
9417: PetscErrorCode  MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9418: {
9420:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9421:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9422:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9423:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

9428:   MatCheckPreallocated(A,1);
9429:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9430:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9433:   MatCheckPreallocated(B,2);
9434:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9435:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9438:   MatCheckPreallocated(C,3);
9439:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9440:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9441:   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);
9442:   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);
9443:   if (scall == MAT_REUSE_MATRIX) {
9446:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9447:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9448:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9449:     return(0);
9450:   }
9451:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9452:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9454:   fA = A->ops->matmatmult;
9455:   fB = B->ops->matmatmult;
9456:   fC = C->ops->matmatmult;
9457:   if (fA == fB && fA == fC) {
9458:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9459:     mult = fA;
9460:   } else {
9461:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9462:     char multname[256];
9463:     PetscStrcpy(multname,"MatMatMatMult_");
9464:     PetscStrcat(multname,((PetscObject)A)->type_name);
9465:     PetscStrcat(multname,"_");
9466:     PetscStrcat(multname,((PetscObject)B)->type_name);
9467:     PetscStrcat(multname,"_");
9468:     PetscStrcat(multname,((PetscObject)C)->type_name);
9469:     PetscStrcat(multname,"_C");
9470:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9471:     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);
9472:   }
9473:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9474:   (*mult)(A,B,C,scall,fill,D);
9475:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9476:   return(0);
9477: }

9481: /*@C
9482:    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

9484:    Collective on Mat

9486:    Input Parameters:
9487: +  mat - the matrix
9488: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9489: .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9490: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9492:    Output Parameter:
9493: .  matredundant - redundant matrix

9495:    Notes:
9496:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9497:    original matrix has not changed from that last call to MatCreateRedundantMatrix().

9499:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9500:    calling it.

9502:    Level: advanced

9504:    Concepts: subcommunicator
9505:    Concepts: duplicate matrix

9507: .seealso: MatDestroy()
9508: @*/
9509: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9510: {
9512:   MPI_Comm       comm;
9513:   PetscMPIInt    size;
9514:   PetscInt       mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9515:   Mat_Redundant  *redund=NULL;
9516:   PetscSubcomm   psubcomm=NULL;
9517:   MPI_Comm       subcomm_in=subcomm;
9518:   Mat            *matseq;
9519:   IS             isrow,iscol;
9520:   PetscBool      newsubcomm=PETSC_FALSE;

9523:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
9524:   if (size == 1 || nsubcomm == 1) {
9525:     if (reuse == MAT_INITIAL_MATRIX) {
9526:       MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
9527:     } else {
9528:       MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
9529:     }
9530:     return(0);
9531:   }

9534:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9537:   }
9538:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9539:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9540:   MatCheckPreallocated(mat,1);

9542:   PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
9543:   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9544:     /* create psubcomm, then get subcomm */
9545:     PetscObjectGetComm((PetscObject)mat,&comm);
9546:     MPI_Comm_size(comm,&size);
9547:     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);

9549:     PetscSubcommCreate(comm,&psubcomm);
9550:     PetscSubcommSetNumber(psubcomm,nsubcomm);
9551:     PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
9552:     PetscSubcommSetFromOptions(psubcomm);
9553:     PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);
9554:     newsubcomm = PETSC_TRUE;
9555:     PetscSubcommDestroy(&psubcomm);
9556:   }

9558:   /* get isrow, iscol and a local sequential matrix matseq[0] */
9559:   if (reuse == MAT_INITIAL_MATRIX) {
9560:     mloc_sub = PETSC_DECIDE;
9561:     if (bs < 1) {
9562:       PetscSplitOwnership(subcomm,&mloc_sub,&M);
9563:     } else {
9564:       PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
9565:     }
9566:     MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
9567:     rstart = rend - mloc_sub;
9568:     ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
9569:     ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
9570:   } else { /* reuse == MAT_REUSE_MATRIX */
9571:     /* retrieve subcomm */
9572:     PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
9573:     redund = (*matredundant)->redundant;
9574:     isrow  = redund->isrow;
9575:     iscol  = redund->iscol;
9576:     matseq = redund->matseq;
9577:   }
9578:   MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);

9580:   /* get matredundant over subcomm */
9581:   if (reuse == MAT_INITIAL_MATRIX) {
9582:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);

9584:     /* create a supporting struct and attach it to C for reuse */
9585:     PetscNewLog(*matredundant,&redund);
9586:     (*matredundant)->redundant = redund;
9587:     redund->isrow              = isrow;
9588:     redund->iscol              = iscol;
9589:     redund->matseq             = matseq;
9590:     if (newsubcomm) {
9591:       redund->subcomm          = subcomm;
9592:     } else {
9593:       redund->subcomm          = MPI_COMM_NULL;
9594:     }
9595:   } else {
9596:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
9597:   }
9598:   PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
9599:   return(0);
9600: }

9604: /*@C
9605:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9606:    a given 'mat' object. Each submatrix can span multiple procs.

9608:    Collective on Mat

9610:    Input Parameters:
9611: +  mat - the matrix
9612: .  subcomm - the subcommunicator obtained by com_split(comm)
9613: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9615:    Output Parameter:
9616: .  subMat - 'parallel submatrices each spans a given subcomm

9618:   Notes:
9619:   The submatrix partition across processors is dictated by 'subComm' a
9620:   communicator obtained by com_split(comm). The comm_split
9621:   is not restriced to be grouped with consecutive original ranks.

9623:   Due the comm_split() usage, the parallel layout of the submatrices
9624:   map directly to the layout of the original matrix [wrt the local
9625:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9626:   into the 'DiagonalMat' of the subMat, hence it is used directly from
9627:   the subMat. However the offDiagMat looses some columns - and this is
9628:   reconstructed with MatSetValues()

9630:   Level: advanced

9632:   Concepts: subcommunicator
9633:   Concepts: submatrices

9635: .seealso: MatGetSubMatrices()
9636: @*/
9637: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9638: {
9640:   PetscMPIInt    commsize,subCommSize;

9643:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9644:   MPI_Comm_size(subComm,&subCommSize);
9645:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

9647:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9648:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9649:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9650:   return(0);
9651: }

9655: /*@
9656:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

9658:    Not Collective

9660:    Input Arguments:
9661:    mat - matrix to extract local submatrix from
9662:    isrow - local row indices for submatrix
9663:    iscol - local column indices for submatrix

9665:    Output Arguments:
9666:    submat - the submatrix

9668:    Level: intermediate

9670:    Notes:
9671:    The submat should be returned with MatRestoreLocalSubMatrix().

9673:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9674:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

9676:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9677:    MatSetValuesBlockedLocal() will also be implemented.

9679: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9680: @*/
9681: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9682: {


9692:   if (mat->ops->getlocalsubmatrix) {
9693:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9694:   } else {
9695:     MatCreateLocalRef(mat,isrow,iscol,submat);
9696:   }
9697:   return(0);
9698: }

9702: /*@
9703:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

9705:    Not Collective

9707:    Input Arguments:
9708:    mat - matrix to extract local submatrix from
9709:    isrow - local row indices for submatrix
9710:    iscol - local column indices for submatrix
9711:    submat - the submatrix

9713:    Level: intermediate

9715: .seealso: MatGetLocalSubMatrix()
9716: @*/
9717: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9718: {

9727:   if (*submat) {
9729:   }

9731:   if (mat->ops->restorelocalsubmatrix) {
9732:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9733:   } else {
9734:     MatDestroy(submat);
9735:   }
9736:   *submat = NULL;
9737:   return(0);
9738: }

9740: /* --------------------------------------------------------*/
9743: /*@
9744:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

9746:    Collective on Mat

9748:    Input Parameter:
9749: .  mat - the matrix

9751:    Output Parameter:
9752: .  is - if any rows have zero diagonals this contains the list of them

9754:    Level: developer

9756:    Concepts: matrix-vector product

9758: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9759: @*/
9760: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9761: {

9767:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9768:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9770:   if (!mat->ops->findzerodiagonals) {
9771:     Vec                diag;
9772:     const PetscScalar *a;
9773:     PetscInt          *rows;
9774:     PetscInt           rStart, rEnd, r, nrow = 0;

9776:     MatCreateVecs(mat, &diag, NULL);
9777:     MatGetDiagonal(mat, diag);
9778:     MatGetOwnershipRange(mat, &rStart, &rEnd);
9779:     VecGetArrayRead(diag, &a);
9780:     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
9781:     PetscMalloc1(nrow, &rows);
9782:     nrow = 0;
9783:     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
9784:     VecRestoreArrayRead(diag, &a);
9785:     VecDestroy(&diag);
9786:     ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);
9787:   } else {
9788:     (*mat->ops->findzerodiagonals)(mat, is);
9789:   }
9790:   return(0);
9791: }

9795: /*@
9796:    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)

9798:    Collective on Mat

9800:    Input Parameter:
9801: .  mat - the matrix

9803:    Output Parameter:
9804: .  is - contains the list of rows with off block diagonal entries

9806:    Level: developer

9808:    Concepts: matrix-vector product

9810: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9811: @*/
9812: PetscErrorCode  MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
9813: {

9819:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9820:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9822:   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
9823:   (*mat->ops->findoffblockdiagonalentries)(mat,is);
9824:   return(0);
9825: }

9829: /*@C
9830:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

9832:   Collective on Mat

9834:   Input Parameters:
9835: . mat - the matrix

9837:   Output Parameters:
9838: . values - the block inverses in column major order (FORTRAN-like)

9840:    Note:
9841:    This routine is not available from Fortran.

9843:   Level: advanced
9844: @*/
9845: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9846: {

9851:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9852:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9853:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9854:   (*mat->ops->invertblockdiagonal)(mat,values);
9855:   return(0);
9856: }

9860: /*@C
9861:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9862:     via MatTransposeColoringCreate().

9864:     Collective on MatTransposeColoring

9866:     Input Parameter:
9867: .   c - coloring context

9869:     Level: intermediate

9871: .seealso: MatTransposeColoringCreate()
9872: @*/
9873: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9874: {
9875:   PetscErrorCode       ierr;
9876:   MatTransposeColoring matcolor=*c;

9879:   if (!matcolor) return(0);
9880:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

9882:   PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
9883:   PetscFree(matcolor->rows);
9884:   PetscFree(matcolor->den2sp);
9885:   PetscFree(matcolor->colorforcol);
9886:   PetscFree(matcolor->columns);
9887:   if (matcolor->brows>0) {
9888:     PetscFree(matcolor->lstart);
9889:   }
9890:   PetscHeaderDestroy(c);
9891:   return(0);
9892: }

9896: /*@C
9897:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9898:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9899:     MatTransposeColoring to sparse B.

9901:     Collective on MatTransposeColoring

9903:     Input Parameters:
9904: +   B - sparse matrix B
9905: .   Btdense - symbolic dense matrix B^T
9906: -   coloring - coloring context created with MatTransposeColoringCreate()

9908:     Output Parameter:
9909: .   Btdense - dense matrix B^T

9911:     Options Database Keys:
9912: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9913: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9914: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

9916:     Level: intermediate

9918: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

9920: .keywords: coloring
9921: @*/
9922: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9923: {


9931:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9932:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9933:   return(0);
9934: }

9938: /*@C
9939:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9940:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9941:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9942:     Csp from Cden.

9944:     Collective on MatTransposeColoring

9946:     Input Parameters:
9947: +   coloring - coloring context created with MatTransposeColoringCreate()
9948: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

9950:     Output Parameter:
9951: .   Csp - sparse matrix

9953:     Options Database Keys:
9954: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9955: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9956: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

9958:     Level: intermediate

9960: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

9962: .keywords: coloring
9963: @*/
9964: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9965: {


9973:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9974:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9975:   return(0);
9976: }

9980: /*@C
9981:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

9983:    Collective on Mat

9985:    Input Parameters:
9986: +  mat - the matrix product C
9987: -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()

9989:     Output Parameter:
9990: .   color - the new coloring context

9992:     Level: intermediate

9994: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9995:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9996: @*/
9997: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9998: {
9999:   MatTransposeColoring c;
10000:   MPI_Comm             comm;
10001:   PetscErrorCode       ierr;

10004:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
10005:   PetscObjectGetComm((PetscObject)mat,&comm);
10006:   PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);

10008:   c->ctype = iscoloring->ctype;
10009:   if (mat->ops->transposecoloringcreate) {
10010:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
10011:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

10013:   *color = c;
10014:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
10015:   return(0);
10016: }

10020: /*@
10021:       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10022:         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10023:         same, otherwise it will be larger

10025:      Not Collective

10027:   Input Parameter:
10028: .    A  - the matrix

10030:   Output Parameter:
10031: .    state - the current state

10033:   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10034:          different matrices

10036:   Level: intermediate

10038: @*/
10039: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10040: {
10043:   *state = mat->nonzerostate;
10044:   return(0);
10045: }

10049: /*@
10050:       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10051:                  matrices from each processor

10053:     Collective on MPI_Comm

10055:    Input Parameters:
10056: +    comm - the communicators the parallel matrix will live on
10057: .    seqmat - the input sequential matrices
10058: .    n - number of local columns (or PETSC_DECIDE)
10059: -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

10061:    Output Parameter:
10062: .    mpimat - the parallel matrix generated

10064:     Level: advanced

10066:    Notes: The number of columns of the matrix in EACH processor MUST be the same.

10068: @*/
10069: PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10070: {
10072:   PetscMPIInt    size;

10075:   MPI_Comm_size(comm,&size);
10076:   if (size == 1) {
10077:     if (reuse == MAT_INITIAL_MATRIX) {
10078:       MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);
10079:     } else {
10080:       MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);
10081:     }
10082:     return(0);
10083:   }

10085:   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10086:   PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);
10087:   (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);
10088:   PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);
10089:   return(0);
10090: }

10094: /*@
10095:      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10096:                  ranks' ownership ranges.

10098:     Collective on A

10100:    Input Parameters:
10101: +    A   - the matrix to create subdomains from
10102: -    N   - requested number of subdomains


10105:    Output Parameters:
10106: +    n   - number of subdomains resulting on this rank
10107: -    iss - IS list with indices of subdomains on this rank

10109:     Level: advanced

10111:     Notes: number of subdomains must be smaller than the communicator size
10112: @*/
10113: PetscErrorCode  MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10114: {
10115:   MPI_Comm        comm,subcomm;
10116:   PetscMPIInt     size,rank,color,subsize,subrank;
10117:   PetscInt        rstart,rend,k;
10118:   PetscErrorCode  ierr;

10121:   PetscObjectGetComm((PetscObject)A,&comm);
10122:   MPI_Comm_size(comm,&size);
10123:   MPI_Comm_rank(comm,&rank);
10124:   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);
10125:   *n = 1;
10126:   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10127:   color = rank/k;
10128:   MPI_Comm_split(comm,color,rank,&subcomm);
10129:   MPI_Comm_size(subcomm,&subsize);
10130:   MPI_Comm_size(subcomm,&subrank);
10131:   PetscMalloc1(1,iss);
10132:   MatGetOwnershipRange(A,&rstart,&rend);
10133:   ISCreateStride(subcomm,rend-rstart,rstart,1,*iss);
10134:   return(0);
10135: }