Actual source code: matrix.c

petsc-3.4.4 2014-03-13
  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>

  9: /* Logging support */
 10: PetscClassId MAT_CLASSID;
 11: PetscClassId MAT_FDCOLORING_CLASSID;
 12: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;

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

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

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

 43:    Logically Collective on Vec

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

 50:    Output Parameter:
 51: .  x  - the vector

 53:    Example of Usage:
 54: .vb
 55:      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
 56:      VecSetRandom(x,rctx);
 57:      PetscRandomDestroy(rctx);
 58: .ve

 60:    Level: intermediate

 62:    Concepts: vector^setting to random
 63:    Concepts: random^vector

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


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

 85:   PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
 86:   (*x->ops->setrandom)(x,rctx);
 87:   PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);

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


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

100:   Input Parameter:
101: .    A  - the matrix

103:   Output Parameter:
104: .    keptrows - the rows that are not completely zero

106:   Level: intermediate

108:  @*/
109: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
110: {

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

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

127:    Not Collective

129:    Input Parameters:
130: .   A - the matrix

132:    Output Parameters:
133: .   a - the diagonal part (which is a SEQUENTIAL matrix)

135:    Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.

137:    Level: advanced

139: @*/
140: PetscErrorCode  MatGetDiagonalBlock(Mat A,Mat *a)
141: {
142:   PetscErrorCode ierr,(*f)(Mat,Mat*);
143:   PetscMPIInt    size;

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

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

171:    Collective on Mat

173:    Input Parameters:
174: .  mat - the matrix

176:    Output Parameter:
177: .   trace - the sum of the diagonal entries

179:    Level: advanced

181: @*/
182: PetscErrorCode  MatGetTrace(Mat mat,PetscScalar *trace)
183: {
185:   Vec            diag;

188:   MatGetVecs(mat,&diag,NULL);
189:   MatGetDiagonal(mat,diag);
190:   VecSum(diag,trace);
191:   VecDestroy(&diag);
192:   return(0);
193: }

197: /*@
198:    MatRealPart - Zeros out the imaginary part of the matrix

200:    Logically Collective on Mat

202:    Input Parameters:
203: .  mat - the matrix

205:    Level: advanced


208: .seealso: MatImaginaryPart()
209: @*/
210: PetscErrorCode  MatRealPart(Mat mat)
211: {

217:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
218:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
219:   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
220:   MatCheckPreallocated(mat,1);
221:   (*mat->ops->realpart)(mat);
222: #if defined(PETSC_HAVE_CUSP)
223:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
224:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
225:   }
226: #endif
227:   return(0);
228: }

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

235:    Collective on Mat

237:    Input Parameter:
238: .  mat - the matrix

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

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

246:    Level: advanced

248: @*/
249: PetscErrorCode  MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
250: {

256:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
257:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
258:   if (!mat->ops->getghosts) {
259:     if (nghosts) *nghosts = 0;
260:     if (ghosts) *ghosts = 0;
261:   } else {
262:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
263:   }
264:   return(0);
265: }


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

273:    Logically Collective on Mat

275:    Input Parameters:
276: .  mat - the matrix

278:    Level: advanced


281: .seealso: MatRealPart()
282: @*/
283: PetscErrorCode  MatImaginaryPart(Mat mat)
284: {

290:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
291:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
292:   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
293:   MatCheckPreallocated(mat,1);
294:   (*mat->ops->imaginarypart)(mat);
295: #if defined(PETSC_HAVE_CUSP)
296:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
297:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
298:   }
299: #endif
300:   return(0);
301: }

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

308:    Collective on Mat

310:    Input Parameter:
311: .  mat - the matrix

313:    Output Parameters:
314: +  missing - is any diagonal missing
315: -  dd - first diagonal entry that is missing (optional)

317:    Level: advanced


320: .seealso: MatRealPart()
321: @*/
322: PetscErrorCode  MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
323: {

329:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
330:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
331:   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
332:   (*mat->ops->missingdiagonal)(mat,missing,dd);
333:   return(0);
334: }

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

343:    Not Collective

345:    Input Parameters:
346: +  mat - the matrix
347: -  row - the row to get

349:    Output Parameters:
350: +  ncols -  if not NULL, the number of nonzeros in the row
351: .  cols - if not NULL, the column numbers
352: -  vals - if not NULL, the values

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

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

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

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

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

376:    Fortran Notes:
377:    The calling sequence from Fortran is
378: .vb
379:    MatGetRow(matrix,row,ncols,cols,values,ierr)
380:          Mat     matrix (input)
381:          integer row    (input)
382:          integer ncols  (output)
383:          integer cols(maxcols) (output)
384:          double precision (or double complex) values(maxcols) output
385: .ve
386:    where maxcols >= maximum nonzeros in any row of the matrix.


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

393:    Level: advanced

395:    Concepts: matrices^row access

397: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
398: @*/
399: PetscErrorCode  MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
400: {
402:   PetscInt       incols;

407:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
408:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
409:   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
410:   MatCheckPreallocated(mat,1);
411:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
412:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
413:   if (ncols) *ncols = incols;
414:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
415:   return(0);
416: }

420: /*@
421:    MatConjugate - replaces the matrix values with their complex conjugates

423:    Logically Collective on Mat

425:    Input Parameters:
426: .  mat - the matrix

428:    Level: advanced

430: .seealso:  VecConjugate()
431: @*/
432: PetscErrorCode  MatConjugate(Mat mat)
433: {
434: #if defined(PETSC_USE_COMPLEX)

439:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
440:   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");
441:   (*mat->ops->conjugate)(mat);
442: #if defined(PETSC_HAVE_CUSP)
443:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
444:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
445:   }
446: #endif
447:   return(0);
448: #else
449:   return 0;
450: #endif
451: }

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

458:    Not Collective

460:    Input Parameters:
461: +  mat - the matrix
462: .  row - the row to get
463: .  ncols, cols - the number of nonzeros and their columns
464: -  vals - if nonzero the column values

466:    Notes:
467:    This routine should be called after you have finished examining the entries.

469:    Fortran Notes:
470:    The calling sequence from Fortran is
471: .vb
472:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
473:       Mat     matrix (input)
474:       integer row    (input)
475:       integer ncols  (output)
476:       integer cols(maxcols) (output)
477:       double precision (or double complex) values(maxcols) output
478: .ve
479:    Where maxcols >= maximum nonzeros in any row of the matrix.

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

484:    Level: advanced

486: .seealso:  MatGetRow()
487: @*/
488: PetscErrorCode  MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
489: {

495:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
496:   if (!mat->ops->restorerow) return(0);
497:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
498:   if (ncols) *ncols = 0;
499:   if (cols)  *cols = NULL;
500:   if (vals)  *vals = NULL;
501:   return(0);
502: }

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

510:    Not Collective

512:    Input Parameters:
513: +  mat - the matrix

515:    Notes:
516:    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.

518:    Level: advanced

520:    Concepts: matrices^row access

522: .seealso: MatRestoreRowRowUpperTriangular()
523: @*/
524: PetscErrorCode  MatGetRowUpperTriangular(Mat mat)
525: {

531:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
532:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
533:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
534:   MatCheckPreallocated(mat,1);
535:   (*mat->ops->getrowuppertriangular)(mat);
536:   return(0);
537: }

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

544:    Not Collective

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

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


553:    Level: advanced

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

563:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
564:   if (!mat->ops->restorerowuppertriangular) return(0);
565:   (*mat->ops->restorerowuppertriangular)(mat);
566:   return(0);
567: }

571: /*@C
572:    MatSetOptionsPrefix - Sets the prefix used for searching for all
573:    Mat options in the database.

575:    Logically Collective on Mat

577:    Input Parameter:
578: +  A - the Mat context
579: -  prefix - the prefix to prepend to all option names

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

585:    Level: advanced

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

589: .seealso: MatSetFromOptions()
590: @*/
591: PetscErrorCode  MatSetOptionsPrefix(Mat A,const char prefix[])
592: {

597:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
598:   return(0);
599: }

603: /*@C
604:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
605:    Mat options in the database.

607:    Logically Collective on Mat

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

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

617:    Level: advanced

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

621: .seealso: MatGetOptionsPrefix()
622: @*/
623: PetscErrorCode  MatAppendOptionsPrefix(Mat A,const char prefix[])
624: {

629:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
630:   return(0);
631: }

635: /*@C
636:    MatGetOptionsPrefix - Sets the prefix used for searching for all
637:    Mat options in the database.

639:    Not Collective

641:    Input Parameter:
642: .  A - the Mat context

644:    Output Parameter:
645: .  prefix - pointer to the prefix string used

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

650:    Level: advanced

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

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

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

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

671:    Collective on Mat

673:    Input Parameters:
674: .  A - the Mat context

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

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

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

683:    Level: beginner

685: .keywords: Mat, setup

687: .seealso: MatCreate(), MatDestroy()
688: @*/
689: PetscErrorCode  MatSetUp(Mat A)
690: {
691:   PetscMPIInt    size;

696:   if (!((PetscObject)A)->type_name) {
697:     MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
698:     if (size == 1) {
699:       MatSetType(A, MATSEQAIJ);
700:     } else {
701:       MatSetType(A, MATMPIAIJ);
702:     }
703:   }
704:   if (!A->preallocated && A->ops->setup) {
705:     PetscInfo(A,"Warning not preallocating matrix storage\n");
706:     (*A->ops->setup)(A);
707:   }
708:   A->preallocated = PETSC_TRUE;
709:   return(0);
710: }

712: #if defined(PETSC_HAVE_AMS)
713: #include <petscviewerams.h>
714: #endif
717: /*@C
718:    MatView - Visualizes a matrix object.

720:    Collective on Mat

722:    Input Parameters:
723: +  mat - the matrix
724: -  viewer - visualization context

726:   Notes:
727:   The available visualization contexts include
728: +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
729: .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
730:         output where only the first processor opens
731:         the file.  All other processors send their
732:         data to the first processor to print.
733: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

735:    The user can open alternative visualization contexts with
736: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
737: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
738:          specified file; corresponding input uses MatLoad()
739: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
740:          an X window display
741: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
742:          Currently only the sequential dense and AIJ
743:          matrix types support the Socket viewer.

745:    The user can call PetscViewerSetFormat() to specify the output
746:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
747:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
748: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
749: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
750: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
751: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
752:          format common among all matrix types
753: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
754:          format (which is in many cases the same as the default)
755: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
756:          size and structure (not the matrix entries)
757: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
758:          the matrix structure

760:    Options Database Keys:
761: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
762: .  -mat_view ::ascii_info_detail - Prints more detailed info
763: .  -mat_view - Prints matrix in ASCII format
764: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
765: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
766: .  -display <name> - Sets display name (default is host)
767: .  -draw_pause <sec> - Sets number of seconds to pause after display
768: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see the <a href="../../docs/manual.pdf">users manual</a> for details).
769: .  -viewer_socket_machine <machine>
770: .  -viewer_socket_port <port>
771: .  -mat_view binary - save matrix to file in binary format
772: -  -viewer_binary_filename <name>
773:    Level: beginner

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

778:       See bin/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
779:       viewer is used.

781:       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
782:       And then use the following mouse functions:
783:           left mouse: zoom in
784:           middle mouse: zoom out
785:           right mouse: continue with the simulation

787:    Concepts: matrices^viewing
788:    Concepts: matrices^plotting
789:    Concepts: matrices^printing

791: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
792:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
793: @*/
794: PetscErrorCode  MatView(Mat mat,PetscViewer viewer)
795: {
796:   PetscErrorCode    ierr;
797:   PetscInt          rows,cols,bs;
798:   PetscBool         iascii;
799:   PetscViewerFormat format;
800: #if defined(PETSC_HAVE_AMS)
801:   PetscBool      isams;
802: #endif

807:   if (!viewer) {
808:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
809:   }
812:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
813:   MatCheckPreallocated(mat,1);

815:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
816:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
817: #if defined(PETSC_HAVE_AMS)
818:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERAMS,&isams);
819: #endif
820:   if (iascii) {
821:     PetscViewerGetFormat(viewer,&format);
822:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
823:       PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer,"Matrix Object");
824:       PetscViewerASCIIPushTab(viewer);
825:       MatGetSize(mat,&rows,&cols);
826:       MatGetBlockSize(mat,&bs);
827:       if (bs != 1) {
828:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,bs);
829:       } else {
830:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
831:       }
832:       if (mat->factortype) {
833:         const MatSolverPackage solver;
834:         MatFactorGetSolverPackage(mat,&solver);
835:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
836:       }
837:       if (mat->ops->getinfo) {
838:         MatInfo info;
839:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
840:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%lld, allocated nonzeros=%lld\n",(Petsc64bitInt)info.nz_used,(Petsc64bitInt)info.nz_allocated);
841:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
842:       }
843:     }
844: #if defined(PETSC_HAVE_AMS)
845:   } else if (isams) {
846:     if (((PetscObject)mat)->amsmem == -1) {
847:       PetscObjectViewAMS((PetscObject)mat,viewer);
848:     }
849: #endif
850:   }
851:   if (mat->ops->view) {
852:     PetscViewerASCIIPushTab(viewer);
853:     (*mat->ops->view)(mat,viewer);
854:     PetscViewerASCIIPopTab(viewer);
855:   } else if (!iascii) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
856:   if (iascii) {
857:     PetscViewerGetFormat(viewer,&format);
858:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
859:       PetscViewerASCIIPopTab(viewer);
860:     }
861:   }
862:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
863:   return(0);
864: }

866: #if defined(PETSC_USE_DEBUG)
867: #include <../src/sys/totalview/tv_data_display.h>
868: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
869: {
870:   TV_add_row("Local rows", "int", &mat->rmap->n);
871:   TV_add_row("Local columns", "int", &mat->cmap->n);
872:   TV_add_row("Global rows", "int", &mat->rmap->N);
873:   TV_add_row("Global columns", "int", &mat->cmap->N);
874:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
875:   return TV_format_OK;
876: }
877: #endif

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

887:    Collective on PetscViewer

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

894:    Options Database Keys:
895:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
896:    block size
897: .    -matload_block_size <bs>

899:    Level: beginner

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

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

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

914:    In parallel, each processor can load a subset of rows (or the
915:    entire matrix).  This routine is especially useful when a large
916:    matrix is stored on disk and only part of it is desired on each
917:    processor.  For example, a parallel solver may access only some of
918:    the rows from each processor.  The algorithm used here reads
919:    relatively small blocks of data rather than reading the entire
920:    matrix and then subsetting it.

922:    Notes for advanced users:
923:    Most users should not need to know the details of the binary storage
924:    format, since MatLoad() and MatView() completely hide these details.
925:    But for anyone who's interested, the standard binary matrix storage
926:    format is

928: $    int    MAT_FILE_CLASSID
929: $    int    number of rows
930: $    int    number of columns
931: $    int    total number of nonzeros
932: $    int    *number nonzeros in each row
933: $    int    *column indices of all nonzeros (starting index is zero)
934: $    PetscScalar *values of all nonzeros

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

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

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

946:  @*/
947: PetscErrorCode  MatLoad(Mat newmat,PetscViewer viewer)
948: {
950:   PetscBool      isbinary,flg;

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

958:   if (!((PetscObject)newmat)->type_name) {
959:     MatSetType(newmat,MATAIJ);
960:   }

962:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
963:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
964:   (*newmat->ops->load)(newmat,viewer);
965:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

967:   flg  = PETSC_FALSE;
968:   PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
969:   if (flg) {
970:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
971:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
972:   }
973:   flg  = PETSC_FALSE;
974:   PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
975:   if (flg) {
976:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
977:   }
978:   return(0);
979: }

983: /*@
984:    MatDestroy - Frees space taken by a matrix.

986:    Collective on Mat

988:    Input Parameter:
989: .  A - the matrix

991:    Level: beginner

993: @*/
994: PetscErrorCode  MatDestroy(Mat *A)
995: {

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

1003:   PetscViewerDestroy(&(*A)->viewonassembly);
1004:   /* if memory was published with AMS then destroy it */
1005:   PetscObjectAMSViewOff((PetscObject)*A);
1006:   if ((*A)->ops->destroy) {
1007:     (*(*A)->ops->destroy)(*A);
1008:   }
1009:   MatNullSpaceDestroy(&(*A)->nullsp);
1010:   MatNullSpaceDestroy(&(*A)->nearnullsp);
1011:   PetscLayoutDestroy(&(*A)->rmap);
1012:   PetscLayoutDestroy(&(*A)->cmap);
1013:   PetscHeaderDestroy(A);
1014:   return(0);
1015: }

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

1024:    Not Collective

1026:    Input Parameters:
1027: +  mat - the matrix
1028: .  v - a logically two-dimensional array of values
1029: .  m, idxm - the number of rows and their global indices
1030: .  n, idxn - the number of columns and their global indices
1031: -  addv - either ADD_VALUES or INSERT_VALUES, where
1032:    ADD_VALUES adds values to any existing entries, and
1033:    INSERT_VALUES replaces existing entries with new values

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

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

1041:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1042:    options cannot be mixed without intervening calls to the assembly
1043:    routines.

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

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

1053:    Efficiency Alert:
1054:    The routine MatSetValuesBlocked() may offer much better efficiency
1055:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1057:    Level: beginner

1059:    Concepts: matrices^putting entries in

1061: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1062:           InsertMode, INSERT_VALUES, ADD_VALUES
1063: @*/
1064: PetscErrorCode  MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1065: {
1067: #if defined(PETSC_USE_DEBUG)
1068:   PetscInt i,j;
1069: #endif

1074:   if (!m || !n) return(0); /* no values to insert */
1078:   MatCheckPreallocated(mat,1);
1079:   if (mat->insertmode == NOT_SET_VALUES) {
1080:     mat->insertmode = addv;
1081:   }
1082: #if defined(PETSC_USE_DEBUG)
1083:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1084:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1085:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);

1087:   if (v) {
1088:     for (i=0; i<m; i++) {
1089:       for (j=0; j<n; j++) {
1090:         if (PetscIsInfOrNanScalar(v[i*n+j]))
1091: #if defined(PETSC_USE_COMPLEX)
1092:           SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G+iG at matrix entry (%D,%D)",PetscRealPart(v[i*n+j]),PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1093: #else
1094:           SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G at matrix entry (%D,%D)",(PetscReal)v[i*n+j],idxm[i],idxn[j]);
1095: #endif
1096:       }
1097:     }
1098:   }
1099: #endif

1101:   if (mat->assembled) {
1102:     mat->was_assembled = PETSC_TRUE;
1103:     mat->assembled     = PETSC_FALSE;
1104:   }
1105:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1106:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1107:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1108: #if defined(PETSC_HAVE_CUSP)
1109:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1110:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1111:   }
1112: #endif
1113:   return(0);
1114: }


1119: /*@
1120:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1121:         values into a matrix

1123:    Not Collective

1125:    Input Parameters:
1126: +  mat - the matrix
1127: .  row - the (block) row to set
1128: -  v - a logically two-dimensional array of values

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

1133:    All the nonzeros in the row must be provided

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

1137:    The row must belong to this process

1139:    Level: intermediate

1141:    Concepts: matrices^putting entries in

1143: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1144:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1145: @*/
1146: PetscErrorCode  MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1147: {
1149:   PetscInt       globalrow;

1155:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1156:   MatSetValuesRow(mat,globalrow,v);
1157: #if defined(PETSC_HAVE_CUSP)
1158:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1159:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1160:   }
1161: #endif
1162:   return(0);
1163: }

1167: /*@
1168:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1169:         values into a matrix

1171:    Not Collective

1173:    Input Parameters:
1174: +  mat - the matrix
1175: .  row - the (block) row to set
1176: -  v - a logically two-dimensional array of values

1178:    Notes:
1179:    The values, v, are column-oriented for the block version.

1181:    All the nonzeros in the row must be provided

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

1185:    The row must belong to this process

1187:    Level: advanced

1189:    Concepts: matrices^putting entries in

1191: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1192:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1193: @*/
1194: PetscErrorCode  MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1195: {

1201:   MatCheckPreallocated(mat,1);
1203: #if defined(PETSC_USE_DEBUG)
1204:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1205:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1206: #endif
1207:   mat->insertmode = INSERT_VALUES;

1209:   if (mat->assembled) {
1210:     mat->was_assembled = PETSC_TRUE;
1211:     mat->assembled     = PETSC_FALSE;
1212:   }
1213:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1214:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1215:   (*mat->ops->setvaluesrow)(mat,row,v);
1216:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1217: #if defined(PETSC_HAVE_CUSP)
1218:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1219:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1220:   }
1221: #endif
1222:   return(0);
1223: }

1227: /*@
1228:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1229:      Using structured grid indexing

1231:    Not Collective

1233:    Input Parameters:
1234: +  mat - the matrix
1235: .  m - number of rows being entered
1236: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1237: .  n - number of columns being entered
1238: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1239: .  v - a logically two-dimensional array of values
1240: -  addv - either ADD_VALUES or INSERT_VALUES, where
1241:    ADD_VALUES adds values to any existing entries, and
1242:    INSERT_VALUES replaces existing entries with new values

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

1247:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1248:    options cannot be mixed without intervening calls to the assembly
1249:    routines.

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

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

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

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

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

1267:    In Fortran idxm and idxn should be declared as
1268: $     MatStencil idxm(4,m),idxn(4,n)
1269:    and the values inserted using
1270: $    idxm(MatStencil_i,1) = i
1271: $    idxm(MatStencil_j,1) = j
1272: $    idxm(MatStencil_k,1) = k
1273: $    idxm(MatStencil_c,1) = c
1274:    etc

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

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

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

1287:    Efficiency Alert:
1288:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1289:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1291:    Level: beginner

1293:    Concepts: matrices^putting entries in

1295: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1296:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1297: @*/
1298: PetscErrorCode  MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1299: {
1301:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1302:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1303:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1313:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1314:     jdxm = buf; jdxn = buf+m;
1315:   } else {
1316:     PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1317:     jdxm = bufm; jdxn = bufn;
1318:   }
1319:   for (i=0; i<m; i++) {
1320:     for (j=0; j<3-sdim; j++) dxm++;
1321:     tmp = *dxm++ - starts[0];
1322:     for (j=0; j<dim-1; j++) {
1323:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1324:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1325:     }
1326:     if (mat->stencil.noc) dxm++;
1327:     jdxm[i] = tmp;
1328:   }
1329:   for (i=0; i<n; i++) {
1330:     for (j=0; j<3-sdim; j++) dxn++;
1331:     tmp = *dxn++ - starts[0];
1332:     for (j=0; j<dim-1; j++) {
1333:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1334:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1335:     }
1336:     if (mat->stencil.noc) dxn++;
1337:     jdxn[i] = tmp;
1338:   }
1339:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1340:   PetscFree2(bufm,bufn);
1341:   return(0);
1342: }

1346: /*@
1347:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1348:      Using structured grid indexing

1350:    Not Collective

1352:    Input Parameters:
1353: +  mat - the matrix
1354: .  m - number of rows being entered
1355: .  idxm - grid coordinates for matrix rows being entered
1356: .  n - number of columns being entered
1357: .  idxn - grid coordinates for matrix columns being entered
1358: .  v - a logically two-dimensional array of values
1359: -  addv - either ADD_VALUES or INSERT_VALUES, where
1360:    ADD_VALUES adds values to any existing entries, and
1361:    INSERT_VALUES replaces existing entries with new values

1363:    Notes:
1364:    By default the values, v, are row-oriented and unsorted.
1365:    See MatSetOption() for other options.

1367:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1368:    options cannot be mixed without intervening calls to the assembly
1369:    routines.

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

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

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

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

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

1387:    In Fortran idxm and idxn should be declared as
1388: $     MatStencil idxm(4,m),idxn(4,n)
1389:    and the values inserted using
1390: $    idxm(MatStencil_i,1) = i
1391: $    idxm(MatStencil_j,1) = j
1392: $    idxm(MatStencil_k,1) = k
1393:    etc

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

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

1403:    Level: beginner

1405:    Concepts: matrices^putting entries in

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

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

1426:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1427:     jdxm = buf; jdxn = buf+m;
1428:   } else {
1429:     PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1430:     jdxm = bufm; jdxn = bufn;
1431:   }
1432:   for (i=0; i<m; i++) {
1433:     for (j=0; j<3-sdim; j++) dxm++;
1434:     tmp = *dxm++ - starts[0];
1435:     for (j=0; j<sdim-1; j++) {
1436:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1437:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1438:     }
1439:     dxm++;
1440:     jdxm[i] = tmp;
1441:   }
1442:   for (i=0; i<n; i++) {
1443:     for (j=0; j<3-sdim; j++) dxn++;
1444:     tmp = *dxn++ - starts[0];
1445:     for (j=0; j<sdim-1; j++) {
1446:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1447:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1448:     }
1449:     dxn++;
1450:     jdxn[i] = tmp;
1451:   }
1452:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1453:   PetscFree2(bufm,bufn);
1454: #if defined(PETSC_HAVE_CUSP)
1455:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1456:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1457:   }
1458: #endif
1459:   return(0);
1460: }

1464: /*@
1465:    MatSetStencil - Sets the grid information for setting values into a matrix via
1466:         MatSetValuesStencil()

1468:    Not Collective

1470:    Input Parameters:
1471: +  mat - the matrix
1472: .  dim - dimension of the grid 1, 2, or 3
1473: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1474: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1475: -  dof - number of degrees of freedom per node


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

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

1484:    Level: beginner

1486:    Concepts: matrices^putting entries in

1488: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1489:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1490: @*/
1491: PetscErrorCode  MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1492: {
1493:   PetscInt i;


1500:   mat->stencil.dim = dim + (dof > 1);
1501:   for (i=0; i<dim; i++) {
1502:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1503:     mat->stencil.starts[i] = starts[dim-i-1];
1504:   }
1505:   mat->stencil.dims[dim]   = dof;
1506:   mat->stencil.starts[dim] = 0;
1507:   mat->stencil.noc         = (PetscBool)(dof == 1);
1508:   return(0);
1509: }

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

1516:    Not Collective

1518:    Input Parameters:
1519: +  mat - the matrix
1520: .  v - a logically two-dimensional array of values
1521: .  m, idxm - the number of block rows and their global block indices
1522: .  n, idxn - the number of block columns and their global block indices
1523: -  addv - either ADD_VALUES or INSERT_VALUES, where
1524:    ADD_VALUES adds values to any existing entries, and
1525:    INSERT_VALUES replaces existing entries with new values

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

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

1537:    Note that you must call MatSetBlockSize() when constructing this matrix (after
1538:    preallocating it).

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

1543:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1544:    options cannot be mixed without intervening calls to the assembly
1545:    routines.

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

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

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

1561:    Example:
1562: $   Suppose m=n=2 and block size(bs) = 2 The array is
1563: $
1564: $   1  2  | 3  4
1565: $   5  6  | 7  8
1566: $   - - - | - - -
1567: $   9  10 | 11 12
1568: $   13 14 | 15 16
1569: $
1570: $   v[] should be passed in like
1571: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1572: $
1573: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1574: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

1576:    Level: intermediate

1578:    Concepts: matrices^putting entries in blocked

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

1589:   if (!m || !n) return(0); /* no values to insert */
1593:   MatCheckPreallocated(mat,1);
1594:   if (mat->insertmode == NOT_SET_VALUES) {
1595:     mat->insertmode = addv;
1596:   }
1597: #if defined(PETSC_USE_DEBUG)
1598:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1599:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1600:   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1601: #endif

1603:   if (mat->assembled) {
1604:     mat->was_assembled = PETSC_TRUE;
1605:     mat->assembled     = PETSC_FALSE;
1606:   }
1607:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1608:   if (mat->ops->setvaluesblocked) {
1609:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1610:   } else {
1611:     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1612:     PetscInt i,j,bs = mat->rmap->bs,cbs = mat->cmap->bs;
1613:     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1614:       iidxm = buf; iidxn = buf + m*bs;
1615:     } else {
1616:       PetscMalloc2(m*bs,PetscInt,&bufr,n*cbs,PetscInt,&bufc);
1617:       iidxm = bufr; iidxn = bufc;
1618:     }
1619:     for (i=0; i<m; i++) {
1620:       for (j=0; j<bs; j++) {
1621:         iidxm[i*bs+j] = bs*idxm[i] + j;
1622:       }
1623:     }
1624:     for (i=0; i<n; i++) {
1625:       for (j=0; j<cbs; j++) {
1626:         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1627:       }
1628:     }
1629:     MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1630:     PetscFree2(bufr,bufc);
1631:   }
1632:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1633: #if defined(PETSC_HAVE_CUSP)
1634:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1635:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1636:   }
1637: #endif
1638:   return(0);
1639: }

1643: /*@
1644:    MatGetValues - Gets a block of values from a matrix.

1646:    Not Collective; currently only returns a local block

1648:    Input Parameters:
1649: +  mat - the matrix
1650: .  v - a logically two-dimensional array for storing the values
1651: .  m, idxm - the number of rows and their global indices
1652: -  n, idxn - the number of columns and their global indices

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

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

1662:    MatGetValues() requires that the matrix has been assembled
1663:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1664:    MatSetValues() and MatGetValues() CANNOT be made in succession
1665:    without intermediate matrix assembly.

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

1670:    Level: advanced

1672:    Concepts: matrices^accessing values

1674: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1675: @*/
1676: PetscErrorCode  MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1677: {

1683:   if (!m || !n) return(0);
1687:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1688:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1689:   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1690:   MatCheckPreallocated(mat,1);

1692:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1693:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1694:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1695:   return(0);
1696: }

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

1704:   Not Collective

1706:   Input Parameters:
1707: + mat - the matrix
1708: . nb - the number of blocks
1709: . bs - the number of rows (and columns) in each block
1710: . rows - a concatenation of the rows for each block
1711: - v - a concatenation of logically two-dimensional arrays of values

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

1716:   Level: advanced

1718:   Concepts: matrices^putting entries in

1720: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1721:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1722: @*/
1723: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1724: {

1732: #if defined(PETSC_USE_DEBUG)
1733:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1734: #endif

1736:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1737:   if (mat->ops->setvaluesbatch) {
1738:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1739:   } else {
1740:     PetscInt b;
1741:     for (b = 0; b < nb; ++b) {
1742:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1743:     }
1744:   }
1745:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1746:   return(0);
1747: }

1751: /*@
1752:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1753:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1754:    using a local (per-processor) numbering.

1756:    Not Collective

1758:    Input Parameters:
1759: +  x - the matrix
1760: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()
1761:              or ISLocalToGlobalMappingCreateIS()
1762: - cmapping - column mapping

1764:    Level: intermediate

1766:    Concepts: matrices^local to global mapping
1767:    Concepts: local to global mapping^for matrices

1769: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1770: @*/
1771: PetscErrorCode  MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1772: {


1781:   if (x->ops->setlocaltoglobalmapping) {
1782:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1783:   } else {
1784:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1785:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1786:   }
1787:   return(0);
1788: }

1792: /*@
1793:    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1794:    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1795:    entries using a local (per-processor) numbering.

1797:    Not Collective

1799:    Input Parameters:
1800: +  x - the matrix
1801: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or
1802:              ISLocalToGlobalMappingCreateIS()
1803: - cmapping - column mapping

1805:    Level: intermediate

1807:    Concepts: matrices^local to global mapping blocked
1808:    Concepts: local to global mapping^for matrices, blocked

1810: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1811:            MatSetValuesBlocked(), MatSetValuesLocal()
1812: @*/
1813: PetscErrorCode  MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1814: {


1823:   PetscLayoutSetISLocalToGlobalMappingBlock(x->rmap,rmapping);
1824:   PetscLayoutSetISLocalToGlobalMappingBlock(x->cmap,cmapping);
1825:   return(0);
1826: }

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

1833:    Not Collective

1835:    Input Parameters:
1836: .  A - the matrix

1838:    Output Parameters:
1839: + rmapping - row mapping
1840: - cmapping - column mapping

1842:    Level: advanced

1844:    Concepts: matrices^local to global mapping
1845:    Concepts: local to global mapping^for matrices

1847: .seealso:  MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock()
1848: @*/
1849: PetscErrorCode  MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1850: {
1856:   if (rmapping) *rmapping = A->rmap->mapping;
1857:   if (cmapping) *cmapping = A->cmap->mapping;
1858:   return(0);
1859: }

1863: /*@
1864:    MatGetLocalToGlobalMappingBlock - Gets the local-to-global numbering set by MatSetLocalToGlobalMappingBlock()

1866:    Not Collective

1868:    Input Parameters:
1869: .  A - the matrix

1871:    Output Parameters:
1872: + rmapping - row mapping
1873: - cmapping - column mapping

1875:    Level: advanced

1877:    Concepts: matrices^local to global mapping blocked
1878:    Concepts: local to global mapping^for matrices, blocked

1880: .seealso:  MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping()
1881: @*/
1882: PetscErrorCode  MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1883: {
1889:   if (rmapping) *rmapping = A->rmap->bmapping;
1890:   if (cmapping) *cmapping = A->cmap->bmapping;
1891:   return(0);
1892: }

1896: /*@
1897:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1898:    using a local ordering of the nodes.

1900:    Not Collective

1902:    Input Parameters:
1903: +  x - the matrix
1904: .  nrow, irow - number of rows and their local indices
1905: .  ncol, icol - number of columns and their local indices
1906: .  y -  a logically two-dimensional array of values
1907: -  addv - either INSERT_VALUES or ADD_VALUES, where
1908:    ADD_VALUES adds values to any existing entries, and
1909:    INSERT_VALUES replaces existing entries with new values

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

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

1917:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1918:    options cannot be mixed without intervening calls to the assembly
1919:    routines.

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

1924:    Level: intermediate

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

1928: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1929:            MatSetValueLocal()
1930: @*/
1931: PetscErrorCode  MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1932: {

1938:   MatCheckPreallocated(mat,1);
1939:   if (!nrow || !ncol) return(0); /* no values to insert */
1943:   if (mat->insertmode == NOT_SET_VALUES) {
1944:     mat->insertmode = addv;
1945:   }
1946: #if defined(PETSC_USE_DEBUG)
1947:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1948:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1949:   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1950: #endif

1952:   if (mat->assembled) {
1953:     mat->was_assembled = PETSC_TRUE;
1954:     mat->assembled     = PETSC_FALSE;
1955:   }
1956:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1957:   if (mat->ops->setvalueslocal) {
1958:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1959:   } else {
1960:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1961:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1962:       irowm = buf; icolm = buf+nrow;
1963:     } else {
1964:       PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
1965:       irowm = bufr; icolm = bufc;
1966:     }
1967:     ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
1968:     ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
1969:     MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
1970:     PetscFree2(bufr,bufc);
1971:   }
1972:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1973: #if defined(PETSC_HAVE_CUSP)
1974:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1975:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1976:   }
1977: #endif
1978:   return(0);
1979: }

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

1987:    Not Collective

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

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

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

2005:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2006:    options cannot be mixed without intervening calls to the assembly
2007:    routines.

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

2012:    Level: intermediate

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

2016: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
2017:            MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
2018: @*/
2019: PetscErrorCode  MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2020: {

2026:   MatCheckPreallocated(mat,1);
2027:   if (!nrow || !ncol) return(0); /* no values to insert */
2031:   if (mat->insertmode == NOT_SET_VALUES) {
2032:     mat->insertmode = addv;
2033:   }
2034: #if defined(PETSC_USE_DEBUG)
2035:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2036:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2037:   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);
2038: #endif

2040:   if (mat->assembled) {
2041:     mat->was_assembled = PETSC_TRUE;
2042:     mat->assembled     = PETSC_FALSE;
2043:   }
2044:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2045:   if (mat->ops->setvaluesblockedlocal) {
2046:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2047:   } else {
2048:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2049:     if (mat->rmap->bmapping && mat->cmap->bmapping) {
2050:       if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2051:         irowm = buf; icolm = buf + nrow;
2052:       } else {
2053:         PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
2054:         irowm = bufr; icolm = bufc;
2055:       }
2056:       ISLocalToGlobalMappingApply(mat->rmap->bmapping,nrow,irow,irowm);
2057:       ISLocalToGlobalMappingApply(mat->cmap->bmapping,ncol,icol,icolm);
2058:       MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2059:       PetscFree2(bufr,bufc);
2060:     } else {
2061:       PetscInt i,j,bs = mat->rmap->bs,cbs = mat->cmap->bs;
2062:       if (nrow*bs+ncol*cbs <=(PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2063:         irowm = buf; icolm = buf + nrow;
2064:       } else {
2065:         PetscMalloc2(nrow*bs,PetscInt,&bufr,ncol*cbs,PetscInt,&bufc);
2066:         irowm = bufr; icolm = bufc;
2067:       }
2068:       for (i=0; i<nrow; i++) {
2069:         for (j=0; j<bs; j++) irowm[i*bs+j] = irow[i]*bs+j;
2070:       }
2071:       for (i=0; i<ncol; i++) {
2072:         for (j=0; j<cbs; j++) icolm[i*cbs+j] = icol[i]*cbs+j;
2073:       }
2074:       MatSetValuesLocal(mat,nrow*bs,irowm,ncol*cbs,icolm,y,addv);
2075:       PetscFree2(bufr,bufc);
2076:     }
2077:   }
2078:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2079: #if defined(PETSC_HAVE_CUSP)
2080:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2081:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2082:   }
2083: #endif
2084:   return(0);
2085: }

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

2092:    Collective on Mat and Vec

2094:    Input Parameters:
2095: +  mat - the matrix
2096: -  x   - the vector to be multiplied

2098:    Output Parameters:
2099: .  y - the result

2101:    Notes:
2102:    The vectors x and y cannot be the same.  I.e., one cannot
2103:    call MatMult(A,y,y).

2105:    Level: developer

2107:    Concepts: matrix-vector product

2109: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2110: @*/
2111: PetscErrorCode  MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2112: {


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

2126:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2127:   (*mat->ops->multdiagonalblock)(mat,x,y);
2128:   PetscObjectStateIncrease((PetscObject)y);
2129:   return(0);
2130: }

2132: /* --------------------------------------------------------*/
2135: /*@
2136:    MatMult - Computes the matrix-vector product, y = Ax.

2138:    Neighbor-wise Collective on Mat and Vec

2140:    Input Parameters:
2141: +  mat - the matrix
2142: -  x   - the vector to be multiplied

2144:    Output Parameters:
2145: .  y - the result

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

2151:    Level: beginner

2153:    Concepts: matrix-vector product

2155: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2156: @*/
2157: PetscErrorCode  MatMult(Mat mat,Vec x,Vec y)
2158: {

2166:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2167:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2168:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2169: #if !defined(PETSC_HAVE_CONSTRAINTS)
2170:   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);
2171:   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);
2172:   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);
2173: #endif
2174:   VecValidValues(x,2,PETSC_TRUE);
2175:   MatCheckPreallocated(mat,1);

2177:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2178:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2179:   (*mat->ops->mult)(mat,x,y);
2180:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2181:   VecValidValues(y,3,PETSC_FALSE);
2182:   return(0);
2183: }

2187: /*@
2188:    MatMultTranspose - Computes matrix transpose times a vector.

2190:    Neighbor-wise Collective on Mat and Vec

2192:    Input Parameters:
2193: +  mat - the matrix
2194: -  x   - the vector to be multilplied

2196:    Output Parameters:
2197: .  y - the result

2199:    Notes:
2200:    The vectors x and y cannot be the same.  I.e., one cannot
2201:    call MatMultTranspose(A,y,y).

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

2206:    Level: beginner

2208:    Concepts: matrix vector product^transpose

2210: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2211: @*/
2212: PetscErrorCode  MatMultTranspose(Mat mat,Vec x,Vec y)
2213: {


2222:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2223:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2224:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2225: #if !defined(PETSC_HAVE_CONSTRAINTS)
2226:   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);
2227:   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);
2228: #endif
2229:   VecValidValues(x,2,PETSC_TRUE);
2230:   MatCheckPreallocated(mat,1);

2232:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2233:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2234:   (*mat->ops->multtranspose)(mat,x,y);
2235:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2236:   PetscObjectStateIncrease((PetscObject)y);
2237:   VecValidValues(y,3,PETSC_FALSE);
2238:   return(0);
2239: }

2243: /*@
2244:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2246:    Neighbor-wise Collective on Mat and Vec

2248:    Input Parameters:
2249: +  mat - the matrix
2250: -  x   - the vector to be multilplied

2252:    Output Parameters:
2253: .  y - the result

2255:    Notes:
2256:    The vectors x and y cannot be the same.  I.e., one cannot
2257:    call MatMultHermitianTranspose(A,y,y).

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

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

2263:    Level: beginner

2265:    Concepts: matrix vector product^transpose

2267: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2268: @*/
2269: PetscErrorCode  MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2270: {
2272:   Vec            w;


2280:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2281:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2282:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2283: #if !defined(PETSC_HAVE_CONSTRAINTS)
2284:   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);
2285:   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);
2286: #endif
2287:   MatCheckPreallocated(mat,1);

2289:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2290:   if (mat->ops->multhermitiantranspose) {
2291:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2292:   } else {
2293:     VecDuplicate(x,&w);
2294:     VecCopy(x,w);
2295:     VecConjugate(w);
2296:     MatMultTranspose(mat,w,y);
2297:     VecDestroy(&w);
2298:     VecConjugate(y);
2299:   }
2300:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2301:   PetscObjectStateIncrease((PetscObject)y);
2302:   return(0);
2303: }

2307: /*@
2308:     MatMultAdd -  Computes v3 = v2 + A * v1.

2310:     Neighbor-wise Collective on Mat and Vec

2312:     Input Parameters:
2313: +   mat - the matrix
2314: -   v1, v2 - the vectors

2316:     Output Parameters:
2317: .   v3 - the result

2319:     Notes:
2320:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2321:     call MatMultAdd(A,v1,v2,v1).

2323:     Level: beginner

2325:     Concepts: matrix vector product^addition

2327: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2328: @*/
2329: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2330: {


2340:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2341:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2342:   if (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);
2343:   /* 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);
2344:      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); */
2345:   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);
2346:   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);
2347:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2348:   MatCheckPreallocated(mat,1);

2350:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2351:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2352:   (*mat->ops->multadd)(mat,v1,v2,v3);
2353:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2354:   PetscObjectStateIncrease((PetscObject)v3);
2355:   return(0);
2356: }

2360: /*@
2361:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2363:    Neighbor-wise Collective on Mat and Vec

2365:    Input Parameters:
2366: +  mat - the matrix
2367: -  v1, v2 - the vectors

2369:    Output Parameters:
2370: .  v3 - the result

2372:    Notes:
2373:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2374:    call MatMultTransposeAdd(A,v1,v2,v1).

2376:    Level: beginner

2378:    Concepts: matrix vector product^transpose and addition

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


2393:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2394:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2395:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2396:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2397:   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);
2398:   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);
2399:   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);
2400:   MatCheckPreallocated(mat,1);

2402:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2403:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2404:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2405:   PetscObjectStateIncrease((PetscObject)v3);
2406:   return(0);
2407: }

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

2414:    Neighbor-wise Collective on Mat and Vec

2416:    Input Parameters:
2417: +  mat - the matrix
2418: -  v1, v2 - the vectors

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

2423:    Notes:
2424:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2425:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2427:    Level: beginner

2429:    Concepts: matrix vector product^transpose and addition

2431: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2432: @*/
2433: PetscErrorCode  MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2434: {


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

2453:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2454:   (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2455:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2456:   PetscObjectStateIncrease((PetscObject)v3);
2457:   return(0);
2458: }

2462: /*@
2463:    MatMultConstrained - The inner multiplication routine for a
2464:    constrained matrix P^T A P.

2466:    Neighbor-wise Collective on Mat and Vec

2468:    Input Parameters:
2469: +  mat - the matrix
2470: -  x   - the vector to be multilplied

2472:    Output Parameters:
2473: .  y - the result

2475:    Notes:
2476:    The vectors x and y cannot be the same.  I.e., one cannot
2477:    call MatMult(A,y,y).

2479:    Level: beginner

2481: .keywords: matrix, multiply, matrix-vector product, constraint
2482: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2483: @*/
2484: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
2485: {

2492:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2493:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2494:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2495:   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);
2496:   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);
2497:   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);

2499:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2500:   (*mat->ops->multconstrained)(mat,x,y);
2501:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2502:   PetscObjectStateIncrease((PetscObject)y);
2503:   return(0);
2504: }

2508: /*@
2509:    MatMultTransposeConstrained - The inner multiplication routine for a
2510:    constrained matrix P^T A^T P.

2512:    Neighbor-wise Collective on Mat and Vec

2514:    Input Parameters:
2515: +  mat - the matrix
2516: -  x   - the vector to be multilplied

2518:    Output Parameters:
2519: .  y - the result

2521:    Notes:
2522:    The vectors x and y cannot be the same.  I.e., one cannot
2523:    call MatMult(A,y,y).

2525:    Level: beginner

2527: .keywords: matrix, multiply, matrix-vector product, constraint
2528: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2529: @*/
2530: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2531: {

2538:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2539:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2540:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2541:   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);
2542:   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);

2544:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2545:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2546:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2547:   PetscObjectStateIncrease((PetscObject)y);
2548:   return(0);
2549: }

2553: /*@C
2554:    MatGetFactorType - gets the type of factorization it is

2556:    Note Collective
2557:    as the flag

2559:    Input Parameters:
2560: .  mat - the matrix

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

2565:     Level: intermediate

2567: .seealso:    MatFactorType, MatGetFactor()
2568: @*/
2569: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
2570: {
2574:   *t = mat->factortype;
2575:   return(0);
2576: }

2578: /* ------------------------------------------------------------*/
2581: /*@C
2582:    MatGetInfo - Returns information about matrix storage (number of
2583:    nonzeros, memory, etc.).

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

2587:    Input Parameters:
2588: .  mat - the matrix

2590:    Output Parameters:
2591: +  flag - flag indicating the type of parameters to be returned
2592:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2593:    MAT_GLOBAL_SUM - sum over all processors)
2594: -  info - matrix information context

2596:    Notes:
2597:    The MatInfo context contains a variety of matrix data, including
2598:    number of nonzeros allocated and used, number of mallocs during
2599:    matrix assembly, etc.  Additional information for factored matrices
2600:    is provided (such as the fill ratio, number of mallocs during
2601:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2602:    when using the runtime options
2603: $       -info -mat_view ::ascii_info

2605:    Example for C/C++ Users:
2606:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2607:    data within the MatInfo context.  For example,
2608: .vb
2609:       MatInfo info;
2610:       Mat     A;
2611:       double  mal, nz_a, nz_u;

2613:       MatGetInfo(A,MAT_LOCAL,&info);
2614:       mal  = info.mallocs;
2615:       nz_a = info.nz_allocated;
2616: .ve

2618:    Example for Fortran Users:
2619:    Fortran users should declare info as a double precision
2620:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2621:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2622:    a complete list of parameter names.
2623: .vb
2624:       double  precision info(MAT_INFO_SIZE)
2625:       double  precision mal, nz_a
2626:       Mat     A
2627:       integer ierr

2629:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2630:       mal = info(MAT_INFO_MALLOCS)
2631:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2632: .ve

2634:     Level: intermediate

2636:     Concepts: matrices^getting information on

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

2641: .seealso: MatStashGetInfo()

2643: @*/
2644: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2645: {

2652:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2653:   MatCheckPreallocated(mat,1);
2654:   (*mat->ops->getinfo)(mat,flag,info);
2655:   return(0);
2656: }

2658: /* ----------------------------------------------------------*/

2662: /*@C
2663:    MatLUFactor - Performs in-place LU factorization of matrix.

2665:    Collective on Mat

2667:    Input Parameters:
2668: +  mat - the matrix
2669: .  row - row permutation
2670: .  col - column permutation
2671: -  info - options for factorization, includes
2672: $          fill - expected fill as ratio of original fill.
2673: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2674: $                   Run with the option -info to determine an optimal value to use

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

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

2684:    Level: developer

2686:    Concepts: matrices^LU factorization

2688: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2689:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2694: @*/
2695: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2696: {
2698:   MatFactorInfo  tinfo;

2706:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2707:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2708:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2709:   MatCheckPreallocated(mat,1);
2710:   if (!info) {
2711:     MatFactorInfoInitialize(&tinfo);
2712:     info = &tinfo;
2713:   }

2715:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2716:   (*mat->ops->lufactor)(mat,row,col,info);
2717:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2718:   PetscObjectStateIncrease((PetscObject)mat);
2719:   return(0);
2720: }

2724: /*@C
2725:    MatILUFactor - Performs in-place ILU factorization of matrix.

2727:    Collective on Mat

2729:    Input Parameters:
2730: +  mat - the matrix
2731: .  row - row permutation
2732: .  col - column permutation
2733: -  info - structure containing
2734: $      levels - number of levels of fill.
2735: $      expected fill - as ratio of original fill.
2736: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2737:                 missing diagonal entries)

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

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

2747:    Level: developer

2749:    Concepts: matrices^ILU factorization

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

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

2756: @*/
2757: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2758: {

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

2773:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2774:   (*mat->ops->ilufactor)(mat,row,col,info);
2775:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2776:   PetscObjectStateIncrease((PetscObject)mat);
2777:   return(0);
2778: }

2782: /*@C
2783:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2784:    Call this routine before calling MatLUFactorNumeric().

2786:    Collective on Mat

2788:    Input Parameters:
2789: +  fact - the factor matrix obtained with MatGetFactor()
2790: .  mat - the matrix
2791: .  row, col - row and column permutations
2792: -  info - options for factorization, includes
2793: $          fill - expected fill as ratio of original fill.
2794: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2795: $                   Run with the option -info to determine an optimal value to use


2798:    Notes:
2799:    See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
2800:    choosing the fill factor for better efficiency.

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

2806:    Level: developer

2808:    Concepts: matrices^LU symbolic factorization

2810: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

2815: @*/
2816: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2817: {

2827:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2828:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2829:   if (!(fact)->ops->lufactorsymbolic) {
2830:     const MatSolverPackage spackage;
2831:     MatFactorGetSolverPackage(fact,&spackage);
2832:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2833:   }
2834:   MatCheckPreallocated(mat,2);

2836:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2837:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2838:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2839:   PetscObjectStateIncrease((PetscObject)fact);
2840:   return(0);
2841: }

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

2849:    Collective on Mat

2851:    Input Parameters:
2852: +  fact - the factor matrix obtained with MatGetFactor()
2853: .  mat - the matrix
2854: -  info - options for factorization

2856:    Notes:
2857:    See MatLUFactor() for in-place factorization.  See
2858:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

2864:    Level: developer

2866:    Concepts: matrices^LU numeric factorization

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

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

2873: @*/
2874: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2875: {

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

2886:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2887:   MatCheckPreallocated(mat,2);
2888:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2889:   (fact->ops->lufactornumeric)(fact,mat,info);
2890:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);

2892:   if (fact->viewonassembly) {
2893:     PetscViewerPushFormat(fact->viewonassembly,fact->viewformatonassembly);
2894:     MatView(fact,fact->viewonassembly);
2895:     PetscViewerPopFormat(fact->viewonassembly);
2896:   }
2897:   PetscObjectStateIncrease((PetscObject)fact);
2898:   return(0);
2899: }

2903: /*@C
2904:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2905:    symmetric matrix.

2907:    Collective on Mat

2909:    Input Parameters:
2910: +  mat - the matrix
2911: .  perm - row and column permutations
2912: -  f - expected fill as ratio of original fill

2914:    Notes:
2915:    See MatLUFactor() for the nonsymmetric case.  See also
2916:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

2922:    Level: developer

2924:    Concepts: matrices^Cholesky factorization

2926: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2927:           MatGetOrdering()

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

2932: @*/
2933: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2934: {

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

2948:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2949:   (*mat->ops->choleskyfactor)(mat,perm,info);
2950:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2951:   PetscObjectStateIncrease((PetscObject)mat);
2952:   return(0);
2953: }

2957: /*@C
2958:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2959:    of a symmetric matrix.

2961:    Collective on Mat

2963:    Input Parameters:
2964: +  fact - the factor matrix obtained with MatGetFactor()
2965: .  mat - the matrix
2966: .  perm - row and column permutations
2967: -  info - options for factorization, includes
2968: $          fill - expected fill as ratio of original fill.
2969: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2970: $                   Run with the option -info to determine an optimal value to use

2972:    Notes:
2973:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2974:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

2980:    Level: developer

2982:    Concepts: matrices^Cholesky symbolic factorization

2984: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2985:           MatGetOrdering()

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

2990: @*/
2991: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2992: {

3001:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3002:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3003:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3004:   if (!(fact)->ops->choleskyfactorsymbolic) {
3005:     const MatSolverPackage spackage;
3006:     MatFactorGetSolverPackage(fact,&spackage);
3007:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3008:   }
3009:   MatCheckPreallocated(mat,2);

3011:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3012:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3013:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3014:   PetscObjectStateIncrease((PetscObject)fact);
3015:   return(0);
3016: }

3020: /*@C
3021:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3022:    of a symmetric matrix. Call this routine after first calling
3023:    MatCholeskyFactorSymbolic().

3025:    Collective on Mat

3027:    Input Parameters:
3028: +  fact - the factor matrix obtained with MatGetFactor()
3029: .  mat - the initial matrix
3030: .  info - options for factorization
3031: -  fact - the symbolic factor of mat


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

3039:    Level: developer

3041:    Concepts: matrices^Cholesky numeric factorization

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

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

3048: @*/
3049: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3050: {

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

3063:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3064:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3065:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);

3067:   if (fact->viewonassembly) {
3068:     PetscViewerPushFormat(fact->viewonassembly,fact->viewformatonassembly);
3069:     MatView(fact,fact->viewonassembly);
3070:     PetscViewerPopFormat(fact->viewonassembly);
3071:   }
3072:   PetscObjectStateIncrease((PetscObject)fact);
3073:   return(0);
3074: }

3076: /* ----------------------------------------------------------------*/
3079: /*@
3080:    MatSolve - Solves A x = b, given a factored matrix.

3082:    Neighbor-wise Collective on Mat and Vec

3084:    Input Parameters:
3085: +  mat - the factored matrix
3086: -  b - the right-hand-side vector

3088:    Output Parameter:
3089: .  x - the result vector

3091:    Notes:
3092:    The vectors b and x cannot be the same.  I.e., one cannot
3093:    call MatSolve(A,x,x).

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

3100:    Level: developer

3102:    Concepts: matrices^triangular solves

3104: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3105: @*/
3106: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
3107: {

3117:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3118:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3119:   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);
3120:   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);
3121:   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);
3122:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3123:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3124:   MatCheckPreallocated(mat,1);

3126:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3127:   (*mat->ops->solve)(mat,b,x);
3128:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3129:   PetscObjectStateIncrease((PetscObject)x);
3130:   return(0);
3131: }

3135: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
3136: {
3138:   Vec            b,x;
3139:   PetscInt       m,N,i;
3140:   PetscScalar    *bb,*xx;
3141:   PetscBool      flg;

3144:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3145:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3146:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3147:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3149:   MatDenseGetArray(B,&bb);
3150:   MatDenseGetArray(X,&xx);
3151:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3152:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3153:   MatGetVecs(A,&x,&b);
3154:   for (i=0; i<N; i++) {
3155:     VecPlaceArray(b,bb + i*m);
3156:     VecPlaceArray(x,xx + i*m);
3157:     MatSolve(A,b,x);
3158:     VecResetArray(x);
3159:     VecResetArray(b);
3160:   }
3161:   VecDestroy(&b);
3162:   VecDestroy(&x);
3163:   MatDenseRestoreArray(B,&bb);
3164:   MatDenseRestoreArray(X,&xx);
3165:   return(0);
3166: }

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

3173:    Neighbor-wise Collective on Mat

3175:    Input Parameters:
3176: +  mat - the factored matrix
3177: -  B - the right-hand-side matrix  (dense matrix)

3179:    Output Parameter:
3180: .  X - the result matrix (dense matrix)

3182:    Notes:
3183:    The matrices b and x cannot be the same.  I.e., one cannot
3184:    call MatMatSolve(A,x,x).

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

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

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

3197:    Level: developer

3199:    Concepts: matrices^triangular solves

3201: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3202: @*/
3203: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
3204: {

3214:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3215:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3216:   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);
3217:   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);
3218:   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);
3219:   if (!A->rmap->N && !A->cmap->N) return(0);
3220:   MatCheckPreallocated(A,1);

3222:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3223:   if (!A->ops->matsolve) {
3224:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3225:     MatMatSolve_Basic(A,B,X);
3226:   } else {
3227:     (*A->ops->matsolve)(A,B,X);
3228:   }
3229:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3230:   PetscObjectStateIncrease((PetscObject)X);
3231:   return(0);
3232: }


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

3241:    Neighbor-wise Collective on Mat and Vec

3243:    Input Parameters:
3244: +  mat - the factored matrix
3245: -  b - the right-hand-side vector

3247:    Output Parameter:
3248: .  x - the result vector

3250:    Notes:
3251:    MatSolve() should be used for most applications, as it performs
3252:    a forward solve followed by a backward solve.

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

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

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

3267:    Level: developer

3269:    Concepts: matrices^forward solves

3271: .seealso: MatSolve(), MatBackwardSolve()
3272: @*/
3273: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
3274: {

3284:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3285:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3286:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3287:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3288:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3289:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3290:   MatCheckPreallocated(mat,1);
3291:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3292:   (*mat->ops->forwardsolve)(mat,b,x);
3293:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3294:   PetscObjectStateIncrease((PetscObject)x);
3295:   return(0);
3296: }

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

3304:    Neighbor-wise Collective on Mat and Vec

3306:    Input Parameters:
3307: +  mat - the factored matrix
3308: -  b - the right-hand-side vector

3310:    Output Parameter:
3311: .  x - the result vector

3313:    Notes:
3314:    MatSolve() should be used for most applications, as it performs
3315:    a forward solve followed by a backward solve.

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

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

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

3330:    Level: developer

3332:    Concepts: matrices^backward solves

3334: .seealso: MatSolve(), MatForwardSolve()
3335: @*/
3336: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
3337: {

3347:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3348:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3349:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3350:   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);
3351:   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);
3352:   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);
3353:   MatCheckPreallocated(mat,1);

3355:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3356:   (*mat->ops->backwardsolve)(mat,b,x);
3357:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3358:   PetscObjectStateIncrease((PetscObject)x);
3359:   return(0);
3360: }

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

3367:    Neighbor-wise Collective on Mat and Vec

3369:    Input Parameters:
3370: +  mat - the factored matrix
3371: .  b - the right-hand-side vector
3372: -  y - the vector to be added to

3374:    Output Parameter:
3375: .  x - the result vector

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

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

3385:    Level: developer

3387:    Concepts: matrices^triangular solves

3389: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3390: @*/
3391: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3392: {
3393:   PetscScalar    one = 1.0;
3394:   Vec            tmp;

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

3415:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3416:   if (mat->ops->solveadd) {
3417:     (*mat->ops->solveadd)(mat,b,y,x);
3418:   } else {
3419:     /* do the solve then the add manually */
3420:     if (x != y) {
3421:       MatSolve(mat,b,x);
3422:       VecAXPY(x,one,y);
3423:     } else {
3424:       VecDuplicate(x,&tmp);
3425:       PetscLogObjectParent(mat,tmp);
3426:       VecCopy(x,tmp);
3427:       MatSolve(mat,b,x);
3428:       VecAXPY(x,one,tmp);
3429:       VecDestroy(&tmp);
3430:     }
3431:   }
3432:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3433:   PetscObjectStateIncrease((PetscObject)x);
3434:   return(0);
3435: }

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

3442:    Neighbor-wise Collective on Mat and Vec

3444:    Input Parameters:
3445: +  mat - the factored matrix
3446: -  b - the right-hand-side vector

3448:    Output Parameter:
3449: .  x - the result vector

3451:    Notes:
3452:    The vectors b and x cannot be the same.  I.e., one cannot
3453:    call MatSolveTranspose(A,x,x).

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

3459:    Level: developer

3461:    Concepts: matrices^triangular solves

3463: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3464: @*/
3465: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
3466: {

3476:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3477:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3478:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3479:   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);
3480:   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);
3481:   MatCheckPreallocated(mat,1);
3482:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3483:   (*mat->ops->solvetranspose)(mat,b,x);
3484:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3485:   PetscObjectStateIncrease((PetscObject)x);
3486:   return(0);
3487: }

3491: /*@
3492:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3493:                       factored matrix.

3495:    Neighbor-wise Collective on Mat and Vec

3497:    Input Parameters:
3498: +  mat - the factored matrix
3499: .  b - the right-hand-side vector
3500: -  y - the vector to be added to

3502:    Output Parameter:
3503: .  x - the result vector

3505:    Notes:
3506:    The vectors b and x cannot be the same.  I.e., one cannot
3507:    call MatSolveTransposeAdd(A,x,y,x).

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

3513:    Level: developer

3515:    Concepts: matrices^triangular solves

3517: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3518: @*/
3519: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3520: {
3521:   PetscScalar    one = 1.0;
3523:   Vec            tmp;

3534:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3535:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3536:   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);
3537:   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);
3538:   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);
3539:   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);
3540:   MatCheckPreallocated(mat,1);

3542:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3543:   if (mat->ops->solvetransposeadd) {
3544:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3545:   } else {
3546:     /* do the solve then the add manually */
3547:     if (x != y) {
3548:       MatSolveTranspose(mat,b,x);
3549:       VecAXPY(x,one,y);
3550:     } else {
3551:       VecDuplicate(x,&tmp);
3552:       PetscLogObjectParent(mat,tmp);
3553:       VecCopy(x,tmp);
3554:       MatSolveTranspose(mat,b,x);
3555:       VecAXPY(x,one,tmp);
3556:       VecDestroy(&tmp);
3557:     }
3558:   }
3559:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3560:   PetscObjectStateIncrease((PetscObject)x);
3561:   return(0);
3562: }
3563: /* ----------------------------------------------------------------*/

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

3570:    Neighbor-wise Collective on Mat and Vec

3572:    Input Parameters:
3573: +  mat - the matrix
3574: .  b - the right hand side
3575: .  omega - the relaxation factor
3576: .  flag - flag indicating the type of SOR (see below)
3577: .  shift -  diagonal shift
3578: .  its - the number of iterations
3579: -  lits - the number of local iterations

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

3584:    SOR Flags:
3585: .     SOR_FORWARD_SWEEP - forward SOR
3586: .     SOR_BACKWARD_SWEEP - backward SOR
3587: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3588: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3589: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3590: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3591: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3592:          upper/lower triangular part of matrix to
3593:          vector (with omega)
3594: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3596:    Notes:
3597:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3598:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3599:    on each processor.

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

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

3606:    Notes for Advanced Users:
3607:    The flags are implemented as bitwise inclusive or operations.
3608:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3609:    to specify a zero initial guess for SSOR.

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

3615:    Vectors x and b CANNOT be the same

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

3619:    Level: developer

3621:    Concepts: matrices^relaxation
3622:    Concepts: matrices^SOR
3623:    Concepts: matrices^Gauss-Seidel

3625: @*/
3626: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3627: {

3637:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3638:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3639:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3640:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3641:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3642:   if (mat->rmap->n != 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);
3643:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3644:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3645:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3647:   MatCheckPreallocated(mat,1);
3648:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3649:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3650:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3651:   PetscObjectStateIncrease((PetscObject)x);
3652:   return(0);
3653: }

3657: /*
3658:       Default matrix copy routine.
3659: */
3660: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3661: {
3662:   PetscErrorCode    ierr;
3663:   PetscInt          i,rstart = 0,rend = 0,nz;
3664:   const PetscInt    *cwork;
3665:   const PetscScalar *vwork;

3668:   if (B->assembled) {
3669:     MatZeroEntries(B);
3670:   }
3671:   MatGetOwnershipRange(A,&rstart,&rend);
3672:   for (i=rstart; i<rend; i++) {
3673:     MatGetRow(A,i,&nz,&cwork,&vwork);
3674:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3675:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3676:   }
3677:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3678:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3679:   PetscObjectStateIncrease((PetscObject)B);
3680:   return(0);
3681: }

3685: /*@
3686:    MatCopy - Copys a matrix to another matrix.

3688:    Collective on Mat

3690:    Input Parameters:
3691: +  A - the matrix
3692: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3694:    Output Parameter:
3695: .  B - where the copy is put

3697:    Notes:
3698:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3699:    same nonzero pattern or the routine will crash.

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

3705:    Level: intermediate

3707:    Concepts: matrices^copying

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

3711: @*/
3712: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3713: {
3715:   PetscInt       i;

3723:   MatCheckPreallocated(B,2);
3724:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3725:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3726:   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);
3727:   MatCheckPreallocated(A,1);

3729:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3730:   if (A->ops->copy) {
3731:     (*A->ops->copy)(A,B,str);
3732:   } else { /* generic conversion */
3733:     MatCopy_Basic(A,B,str);
3734:   }

3736:   B->stencil.dim = A->stencil.dim;
3737:   B->stencil.noc = A->stencil.noc;
3738:   for (i=0; i<=A->stencil.dim; i++) {
3739:     B->stencil.dims[i]   = A->stencil.dims[i];
3740:     B->stencil.starts[i] = A->stencil.starts[i];
3741:   }

3743:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3744:   PetscObjectStateIncrease((PetscObject)B);
3745:   return(0);
3746: }

3750: /*@C
3751:    MatConvert - Converts a matrix to another matrix, either of the same
3752:    or different type.

3754:    Collective on Mat

3756:    Input Parameters:
3757: +  mat - the matrix
3758: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3759:    same type as the original matrix.
3760: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3761:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3762:    MAT_INITIAL_MATRIX.

3764:    Output Parameter:
3765: .  M - pointer to place new matrix

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

3772:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3773:    the MPI communicator of the generated matrix is always the same as the communicator
3774:    of the input matrix.

3776:    Level: intermediate

3778:    Concepts: matrices^converting between storage formats

3780: .seealso: MatCopy(), MatDuplicate()
3781: @*/
3782: PetscErrorCode  MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3783: {
3785:   PetscBool      sametype,issame,flg;
3786:   char           convname[256],mtype[256];
3787:   Mat            B;

3793:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3794:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3795:   MatCheckPreallocated(mat,1);
3796:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

3798:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3799:   if (flg) {
3800:     newtype = mtype;
3801:   }
3802:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3803:   PetscStrcmp(newtype,"same",&issame);
3804:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");

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

3808:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3809:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3810:   } else {
3811:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3812:     const char     *prefix[3] = {"seq","mpi",""};
3813:     PetscInt       i;
3814:     /*
3815:        Order of precedence:
3816:        1) See if a specialized converter is known to the current matrix.
3817:        2) See if a specialized converter is known to the desired matrix class.
3818:        3) See if a good general converter is registered for the desired class
3819:           (as of 6/27/03 only MATMPIADJ falls into this category).
3820:        4) See if a good general converter is known for the current matrix.
3821:        5) Use a really basic converter.
3822:     */

3824:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3825:     for (i=0; i<3; i++) {
3826:       PetscStrcpy(convname,"MatConvert_");
3827:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3828:       PetscStrcat(convname,"_");
3829:       PetscStrcat(convname,prefix[i]);
3830:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3831:       PetscStrcat(convname,"_C");
3832:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3833:       if (conv) goto foundconv;
3834:     }

3836:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3837:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
3838:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3839:     MatSetType(B,newtype);
3840:     for (i=0; i<3; i++) {
3841:       PetscStrcpy(convname,"MatConvert_");
3842:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3843:       PetscStrcat(convname,"_");
3844:       PetscStrcat(convname,prefix[i]);
3845:       PetscStrcat(convname,newtype);
3846:       PetscStrcat(convname,"_C");
3847:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3848:       if (conv) {
3849:         MatDestroy(&B);
3850:         goto foundconv;
3851:       }
3852:     }

3854:     /* 3) See if a good general converter is registered for the desired class */
3855:     conv = B->ops->convertfrom;
3856:     MatDestroy(&B);
3857:     if (conv) goto foundconv;

3859:     /* 4) See if a good general converter is known for the current matrix */
3860:     if (mat->ops->convert) {
3861:       conv = mat->ops->convert;
3862:     }
3863:     if (conv) goto foundconv;

3865:     /* 5) Use a really basic converter. */
3866:     conv = MatConvert_Basic;

3868: foundconv:
3869:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3870:     (*conv)(mat,newtype,reuse,M);
3871:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3872:   }
3873:   PetscObjectStateIncrease((PetscObject)*M);

3875:   /* Copy Mat options */
3876:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3877:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3878:   return(0);
3879: }

3883: /*@C
3884:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3886:    Not Collective

3888:    Input Parameter:
3889: .  mat - the matrix, must be a factored matrix

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

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

3898:    Level: intermediate

3900: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3901: @*/
3902: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3903: {
3904:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

3909:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3910:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
3911:   if (!conv) {
3912:     *type = MATSOLVERPETSC;
3913:   } else {
3914:     (*conv)(mat,type);
3915:   }
3916:   return(0);
3917: }

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

3924:    Collective on Mat

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

3931:    Output Parameters:
3932: .  f - the factor matrix used with MatXXFactorSymbolic() calls

3934:    Notes:
3935:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3936:      such as pastix, superlu, mumps etc.

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

3940:    Level: intermediate

3942: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3943: @*/
3944: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3945: {
3946:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
3947:   char           convname[256];


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

3956:   PetscStrcpy(convname,"MatGetFactor_");
3957:   PetscStrcat(convname,type);
3958:   PetscStrcat(convname,"_C");
3959:   PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3960:   if (!conv) {
3961:     PetscBool flag;
3962:     MPI_Comm  comm;

3964:     PetscObjectGetComm((PetscObject)mat,&comm);
3965:     PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3966:     if (flag) SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3967:     else SETERRQ4(comm,PETSC_ERR_SUP,"Matrix format %s does not have a solver package %s for %s. Perhaps you must ./configure with --download-%s",((PetscObject)mat)->type_name,type,MatFactorTypes[ftype],type);
3968:   }
3969:   (*conv)(mat,ftype,f);
3970:   return(0);
3971: }

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

3978:    Not Collective

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

3985:    Output Parameter:
3986: .    flg - PETSC_TRUE if the factorization is available

3988:    Notes:
3989:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3990:      such as pastix, superlu, mumps etc.

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

3994:    Level: intermediate

3996: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3997: @*/
3998: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
3999: {
4000:   PetscErrorCode ierr, (*conv)(Mat,MatFactorType,PetscBool*);
4001:   char           convname[256];


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

4010:   PetscStrcpy(convname,"MatGetFactorAvailable_");
4011:   PetscStrcat(convname,type);
4012:   PetscStrcat(convname,"_C");
4013:   PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4014:   if (!conv) {
4015:     *flg = PETSC_FALSE;
4016:   } else {
4017:     (*conv)(mat,ftype,flg);
4018:   }
4019:   return(0);
4020: }


4025: /*@
4026:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4028:    Collective on Mat

4030:    Input Parameters:
4031: +  mat - the matrix
4032: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4033:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

4035:    Output Parameter:
4036: .  M - pointer to place new matrix

4038:    Level: intermediate

4040:    Concepts: matrices^duplicating

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

4044: .seealso: MatCopy(), MatConvert()
4045: @*/
4046: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4047: {
4049:   Mat            B;
4050:   PetscInt       i;

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

4060:   *M = 0;
4061:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4062:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4063:   (*mat->ops->duplicate)(mat,op,M);
4064:   B    = *M;

4066:   B->stencil.dim = mat->stencil.dim;
4067:   B->stencil.noc = mat->stencil.noc;
4068:   for (i=0; i<=mat->stencil.dim; i++) {
4069:     B->stencil.dims[i]   = mat->stencil.dims[i];
4070:     B->stencil.starts[i] = mat->stencil.starts[i];
4071:   }

4073:   B->nooffproczerorows = mat->nooffproczerorows;
4074:   B->nooffprocentries  = mat->nooffprocentries;

4076:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4077:   PetscObjectStateIncrease((PetscObject)B);
4078:   return(0);
4079: }

4083: /*@
4084:    MatGetDiagonal - Gets the diagonal of a matrix.

4086:    Logically Collective on Mat and Vec

4088:    Input Parameters:
4089: +  mat - the matrix
4090: -  v - the vector for storing the diagonal

4092:    Output Parameter:
4093: .  v - the diagonal of the matrix

4095:    Level: intermediate

4097:    Note:
4098:    Currently only correct in parallel for square matrices.

4100:    Concepts: matrices^accessing diagonals

4102: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4103: @*/
4104: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
4105: {

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

4116:   (*mat->ops->getdiagonal)(mat,v);
4117:   PetscObjectStateIncrease((PetscObject)v);
4118:   return(0);
4119: }

4123: /*@
4124:    MatGetRowMin - Gets the minimum value (of the real part) of each
4125:         row of the matrix

4127:    Logically Collective on Mat and Vec

4129:    Input Parameters:
4130: .  mat - the matrix

4132:    Output Parameter:
4133: +  v - the vector for storing the maximums
4134: -  idx - the indices of the column found for each row (optional)

4136:    Level: intermediate

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

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

4143:    Concepts: matrices^getting row maximums

4145: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4146:           MatGetRowMax()
4147: @*/
4148: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4149: {

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

4160:   (*mat->ops->getrowmin)(mat,v,idx);
4161:   PetscObjectStateIncrease((PetscObject)v);
4162:   return(0);
4163: }

4167: /*@
4168:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4169:         row of the matrix

4171:    Logically Collective on Mat and Vec

4173:    Input Parameters:
4174: .  mat - the matrix

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

4180:    Level: intermediate

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

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

4187:    Concepts: matrices^getting row maximums

4189: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4190: @*/
4191: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4192: {

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

4204:   (*mat->ops->getrowminabs)(mat,v,idx);
4205:   PetscObjectStateIncrease((PetscObject)v);
4206:   return(0);
4207: }

4211: /*@
4212:    MatGetRowMax - Gets the maximum value (of the real part) of each
4213:         row of the matrix

4215:    Logically Collective on Mat and Vec

4217:    Input Parameters:
4218: .  mat - the matrix

4220:    Output Parameter:
4221: +  v - the vector for storing the maximums
4222: -  idx - the indices of the column found for each row (optional)

4224:    Level: intermediate

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

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

4231:    Concepts: matrices^getting row maximums

4233: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4234: @*/
4235: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4236: {

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

4247:   (*mat->ops->getrowmax)(mat,v,idx);
4248:   PetscObjectStateIncrease((PetscObject)v);
4249:   return(0);
4250: }

4254: /*@
4255:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4256:         row of the matrix

4258:    Logically Collective on Mat and Vec

4260:    Input Parameters:
4261: .  mat - the matrix

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

4267:    Level: intermediate

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

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

4274:    Concepts: matrices^getting row maximums

4276: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4277: @*/
4278: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4279: {

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

4291:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4292:   PetscObjectStateIncrease((PetscObject)v);
4293:   return(0);
4294: }

4298: /*@
4299:    MatGetRowSum - Gets the sum of each row of the matrix

4301:    Logically Collective on Mat and Vec

4303:    Input Parameters:
4304: .  mat - the matrix

4306:    Output Parameter:
4307: .  v - the vector for storing the sum of rows

4309:    Level: intermediate

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

4313:    Concepts: matrices^getting row sums

4315: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4316: @*/
4317: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4318: {
4319:   PetscInt       start = 0, end = 0, row;
4320:   PetscScalar    *array;

4327:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4328:   MatCheckPreallocated(mat,1);
4329:   MatGetOwnershipRange(mat, &start, &end);
4330:   VecGetArray(v, &array);
4331:   for (row = start; row < end; ++row) {
4332:     PetscInt          ncols, col;
4333:     const PetscInt    *cols;
4334:     const PetscScalar *vals;

4336:     array[row - start] = 0.0;

4338:     MatGetRow(mat, row, &ncols, &cols, &vals);
4339:     for (col = 0; col < ncols; col++) {
4340:       array[row - start] += vals[col];
4341:     }
4342:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4343:   }
4344:   VecRestoreArray(v, &array);
4345:   PetscObjectStateIncrease((PetscObject) v);
4346:   return(0);
4347: }

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

4354:    Collective on Mat

4356:    Input Parameter:
4357: +  mat - the matrix to transpose
4358: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4360:    Output Parameters:
4361: .  B - the transpose

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

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

4368:    Level: intermediate

4370:    Concepts: matrices^transposing

4372: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4373: @*/
4374: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4375: {

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

4386:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4387:   (*mat->ops->transpose)(mat,reuse,B);
4388:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4389:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4390:   return(0);
4391: }

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

4399:    Collective on Mat

4401:    Input Parameter:
4402: +  A - the matrix to test
4403: -  B - the matrix to test against, this can equal the first parameter

4405:    Output Parameters:
4406: .  flg - the result

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

4413:    Level: intermediate

4415:    Concepts: matrices^transposing, matrix^symmetry

4417: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4418: @*/
4419: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4420: {
4421:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4427:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4428:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4429:   *flg = PETSC_FALSE;
4430:   if (f && g) {
4431:     if (f == g) {
4432:       (*f)(A,B,tol,flg);
4433:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4434:   } else {
4435:     MatType mattype;
4436:     if (!f) {
4437:       MatGetType(A,&mattype);
4438:     } else {
4439:       MatGetType(B,&mattype);
4440:     }
4441:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4442:   }
4443:   return(0);
4444: }

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

4451:    Collective on Mat

4453:    Input Parameter:
4454: +  mat - the matrix to transpose and complex conjugate
4455: -  reuse - store the transpose matrix in the provided B

4457:    Output Parameters:
4458: .  B - the Hermitian

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

4463:    Level: intermediate

4465:    Concepts: matrices^transposing, complex conjugatex

4467: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4468: @*/
4469: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4470: {

4474:   MatTranspose(mat,reuse,B);
4475: #if defined(PETSC_USE_COMPLEX)
4476:   MatConjugate(*B);
4477: #endif
4478:   return(0);
4479: }

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

4486:    Collective on Mat

4488:    Input Parameter:
4489: +  A - the matrix to test
4490: -  B - the matrix to test against, this can equal the first parameter

4492:    Output Parameters:
4493: .  flg - the result

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

4500:    Level: intermediate

4502:    Concepts: matrices^transposing, matrix^symmetry

4504: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4505: @*/
4506: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4507: {
4508:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4514:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4515:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4516:   if (f && g) {
4517:     if (f==g) {
4518:       (*f)(A,B,tol,flg);
4519:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4520:   }
4521:   return(0);
4522: }

4526: /*@
4527:    MatPermute - Creates a new matrix with rows and columns permuted from the
4528:    original.

4530:    Collective on Mat

4532:    Input Parameters:
4533: +  mat - the matrix to permute
4534: .  row - row permutation, each processor supplies only the permutation for its rows
4535: -  col - column permutation, each processor supplies only the permutation for its columns

4537:    Output Parameters:
4538: .  B - the permuted matrix

4540:    Level: advanced

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

4546:    Concepts: matrices^permuting

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

4550: @*/
4551: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4552: {

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

4566:   (*mat->ops->permute)(mat,row,col,B);
4567:   PetscObjectStateIncrease((PetscObject)*B);
4568:   return(0);
4569: }

4573: /*@
4574:    MatEqual - Compares two matrices.

4576:    Collective on Mat

4578:    Input Parameters:
4579: +  A - the first matrix
4580: -  B - the second matrix

4582:    Output Parameter:
4583: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4585:    Level: intermediate

4587:    Concepts: matrices^equality between
4588: @*/
4589: PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4590: {

4600:   MatCheckPreallocated(B,2);
4601:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4602:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4603:   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);
4604:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4605:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4606:   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);
4607:   MatCheckPreallocated(A,1);

4609:   (*A->ops->equal)(A,B,flg);
4610:   return(0);
4611: }

4615: /*@
4616:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4617:    matrices that are stored as vectors.  Either of the two scaling
4618:    matrices can be NULL.

4620:    Collective on Mat

4622:    Input Parameters:
4623: +  mat - the matrix to be scaled
4624: .  l - the left scaling vector (or NULL)
4625: -  r - the right scaling vector (or NULL)

4627:    Notes:
4628:    MatDiagonalScale() computes A = LAR, where
4629:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4630:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4632:    Level: intermediate

4634:    Concepts: matrices^diagonal scaling
4635:    Concepts: diagonal scaling of matrices

4637: .seealso: MatScale()
4638: @*/
4639: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4640: {

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

4653:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4654:   (*mat->ops->diagonalscale)(mat,l,r);
4655:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4656:   PetscObjectStateIncrease((PetscObject)mat);
4657: #if defined(PETSC_HAVE_CUSP)
4658:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4659:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4660:   }
4661: #endif
4662:   return(0);
4663: }

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

4670:     Logically Collective on Mat

4672:     Input Parameters:
4673: +   mat - the matrix to be scaled
4674: -   a  - the scaling value

4676:     Output Parameter:
4677: .   mat - the scaled matrix

4679:     Level: intermediate

4681:     Concepts: matrices^scaling all entries

4683: .seealso: MatDiagonalScale()
4684: @*/
4685: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4686: {

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

4698:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4699:   if (a != (PetscScalar)1.0) {
4700:     (*mat->ops->scale)(mat,a);
4701:     PetscObjectStateIncrease((PetscObject)mat);
4702:   }
4703:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4704: #if defined(PETSC_HAVE_CUSP)
4705:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4706:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4707:   }
4708: #endif
4709:   return(0);
4710: }

4714: /*@
4715:    MatNorm - Calculates various norms of a matrix.

4717:    Collective on Mat

4719:    Input Parameters:
4720: +  mat - the matrix
4721: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4723:    Output Parameters:
4724: .  nrm - the resulting norm

4726:    Level: intermediate

4728:    Concepts: matrices^norm
4729:    Concepts: norm^of matrix
4730: @*/
4731: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4732: {


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

4745:   (*mat->ops->norm)(mat,type,nrm);
4746:   return(0);
4747: }

4749: /*
4750:      This variable is used to prevent counting of MatAssemblyBegin() that
4751:    are called from within a MatAssemblyEnd().
4752: */
4753: static PetscInt MatAssemblyEnd_InUse = 0;
4756: /*@
4757:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4758:    be called after completing all calls to MatSetValues().

4760:    Collective on Mat

4762:    Input Parameters:
4763: +  mat - the matrix
4764: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4766:    Notes:
4767:    MatSetValues() generally caches the values.  The matrix is ready to
4768:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4769:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4770:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4771:    using the matrix.

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

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

4781:    Level: beginner

4783:    Concepts: matrices^assembling

4785: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4786: @*/
4787: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4788: {

4794:   MatCheckPreallocated(mat,1);
4795:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4796:   if (mat->assembled) {
4797:     mat->was_assembled = PETSC_TRUE;
4798:     mat->assembled     = PETSC_FALSE;
4799:   }
4800:   if (!MatAssemblyEnd_InUse) {
4801:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4802:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
4803:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4804:   } else if (mat->ops->assemblybegin) {
4805:     (*mat->ops->assemblybegin)(mat,type);
4806:   }
4807:   return(0);
4808: }

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

4816:    Not Collective

4818:    Input Parameter:
4819: .  mat - the matrix

4821:    Output Parameter:
4822: .  assembled - PETSC_TRUE or PETSC_FALSE

4824:    Level: advanced

4826:    Concepts: matrices^assembled?

4828: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4829: @*/
4830: PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
4831: {
4836:   *assembled = mat->assembled;
4837:   return(0);
4838: }

4842: /*
4843:   MatViewFromOptions - Processes command line options to determine if/how a matrix is to be viewed. Called from higher level packages.

4845:   Collective on Vec

4847:   Input Parameters:
4848: + mat   - the matrix
4849: . prefix - prefix to use for viewing, or NULL to use prefix of 'mat'
4850: - optionname - option to activate viewing

4852:   Level: intermediate

4854: .keywords: Mat, view, options, database
4855: .seealso: MatViewFromOptions()
4856: */
4857: PetscErrorCode MatViewFromOptions(Mat mat,const char prefix[],const char optionname[])
4858: {
4859:   PetscErrorCode    ierr;
4860:   PetscViewer       viewer;
4861:   PetscBool         flg;
4862:   static PetscBool  incall = PETSC_FALSE;
4863:   PetscViewerFormat format;

4866:   if (incall) return(0);
4867:   incall = PETSC_TRUE;
4868:   if (prefix) {
4869:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)mat),prefix,optionname,&viewer,&format,&flg);
4870:   } else {
4871:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)mat),((PetscObject)mat)->prefix,optionname,&viewer,&format,&flg);
4872:   }
4873:   if (flg) {
4874:     PetscViewerPushFormat(viewer,format);
4875:     MatView(mat,viewer);
4876:     PetscViewerPopFormat(viewer);
4877:     PetscViewerDestroy(&viewer);
4878:   }
4879:   incall = PETSC_FALSE;
4880:   return(0);
4881: }

4885: /*@
4886:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4887:    be called after MatAssemblyBegin().

4889:    Collective on Mat

4891:    Input Parameters:
4892: +  mat - the matrix
4893: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4895:    Options Database Keys:
4896: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
4897: .  -mat_view ::ascii_info_detail - Prints more detailed info
4898: .  -mat_view - Prints matrix in ASCII format
4899: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
4900: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4901: .  -display <name> - Sets display name (default is host)
4902: .  -draw_pause <sec> - Sets number of seconds to pause after display
4903: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4904: .  -viewer_socket_machine <machine>
4905: .  -viewer_socket_port <port>
4906: .  -mat_view binary - save matrix to file in binary format
4907: -  -viewer_binary_filename <name>

4909:    Notes:
4910:    MatSetValues() generally caches the values.  The matrix is ready to
4911:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4912:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4913:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4914:    using the matrix.

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

4920:    Level: beginner

4922: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4923: @*/
4924: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4925: {
4926:   PetscErrorCode  ierr;
4927:   static PetscInt inassm = 0;
4928:   PetscBool       flg    = PETSC_FALSE;


4934:   inassm++;
4935:   MatAssemblyEnd_InUse++;
4936:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4937:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4938:     if (mat->ops->assemblyend) {
4939:       (*mat->ops->assemblyend)(mat,type);
4940:     }
4941:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4942:   } else if (mat->ops->assemblyend) {
4943:     (*mat->ops->assemblyend)(mat,type);
4944:   }

4946:   /* Flush assembly is not a true assembly */
4947:   if (type != MAT_FLUSH_ASSEMBLY) {
4948:     mat->assembled = PETSC_TRUE; mat->num_ass++;
4949:   }
4950:   mat->insertmode = NOT_SET_VALUES;
4951:   MatAssemblyEnd_InUse--;
4952:   PetscObjectStateIncrease((PetscObject)mat);
4953:   if (!mat->symmetric_eternal) {
4954:     mat->symmetric_set              = PETSC_FALSE;
4955:     mat->hermitian_set              = PETSC_FALSE;
4956:     mat->structurally_symmetric_set = PETSC_FALSE;
4957:   }
4958: #if defined(PETSC_HAVE_CUSP)
4959:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4960:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4961:   }
4962: #endif
4963:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4964:     if (mat->viewonassembly) {
4965:       PetscViewerPushFormat(mat->viewonassembly,mat->viewformatonassembly);
4966:       MatView(mat,mat->viewonassembly);
4967:       PetscViewerPopFormat(mat->viewonassembly);
4968:     }

4970:     if (mat->checksymmetryonassembly) {
4971:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
4972:       if (flg) {
4973:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %G)\n",mat->checksymmetrytol);
4974:       } else {
4975:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %G)\n",mat->checksymmetrytol);
4976:       }
4977:     }
4978:     if (mat->nullsp && mat->checknullspaceonassembly) {
4979:       MatNullSpaceTest(mat->nullsp,mat,NULL);
4980:     }
4981:   }
4982:   inassm--;
4983:   return(0);
4984: }

4988: /*@
4989:    MatSetOption - Sets a parameter option for a matrix. Some options
4990:    may be specific to certain storage formats.  Some options
4991:    determine how values will be inserted (or added). Sorted,
4992:    row-oriented input will generally assemble the fastest. The default
4993:    is row-oriented.

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

4997:    Input Parameters:
4998: +  mat - the matrix
4999: .  option - the option, one of those listed below (and possibly others),
5000: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5002:   Options Describing Matrix Structure:
5003: +    MAT_SPD - symmetric positive definite
5004: -    MAT_SYMMETRIC - symmetric in terms of both structure and value
5005: .    MAT_HERMITIAN - transpose is the complex conjugation
5006: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5007: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5008:                             you set to be kept with all future use of the matrix
5009:                             including after MatAssemblyBegin/End() which could
5010:                             potentially change the symmetry structure, i.e. you
5011:                             KNOW the matrix will ALWAYS have the property you set.


5014:    Options For Use with MatSetValues():
5015:    Insert a logically dense subblock, which can be
5016: .    MAT_ROW_ORIENTED - row-oriented (default)

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

5022:    When (re)assembling a matrix, we can restrict the input for
5023:    efficiency/debugging purposes.  These options include
5024: +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
5025:         allowed if they generate a new nonzero
5026: .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5027: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5028: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5029: .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5030: +    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5031:         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5032:         performance for very large process counts.

5034:    Notes:
5035:    Some options are relevant only for particular matrix types and
5036:    are thus ignored by others.  Other options are not supported by
5037:    certain matrix types and will generate an error message if set.

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

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

5050:    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
5051:    that would generate a new entry in the nonzero structure instead produces
5052:    an error. (Currently supported for AIJ and BAIJ formats only.)
5053:    This is a useful flag when using SAME_NONZERO_PATTERN in calling
5054:    KSPSetOperators() to ensure that the nonzero pattern truely does
5055:    remain unchanged. Set after the first MatAssemblyEnd()

5057:    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
5058:    that would generate a new entry that has not been preallocated will
5059:    instead produce an error. (Currently supported for AIJ and BAIJ formats
5060:    only.) This is a useful flag when debugging matrix memory preallocation.

5062:    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
5063:    other processors should be dropped, rather than stashed.
5064:    This is useful if you know that the "owning" processor is also
5065:    always generating the correct matrix entries, so that PETSc need
5066:    not transfer duplicate entries generated on another processor.

5068:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5069:    searches during matrix assembly. When this flag is set, the hash table
5070:    is created during the first Matrix Assembly. This hash table is
5071:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5072:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5073:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5074:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5093:    Level: intermediate

5095:    Concepts: matrices^setting options

5097: .seealso:  MatOption, Mat

5099: @*/
5100: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool flg)
5101: {

5107:   if (op > 0) {
5110:   }

5112:   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);
5113:   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()");

5115:   switch (op) {
5116:   case MAT_NO_OFF_PROC_ENTRIES:
5117:     mat->nooffprocentries = flg;
5118:     return(0);
5119:     break;
5120:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5121:     mat->nooffproczerorows = flg;
5122:     return(0);
5123:     break;
5124:   case MAT_SPD:
5125:     mat->spd_set = PETSC_TRUE;
5126:     mat->spd     = flg;
5127:     if (flg) {
5128:       mat->symmetric                  = PETSC_TRUE;
5129:       mat->structurally_symmetric     = PETSC_TRUE;
5130:       mat->symmetric_set              = PETSC_TRUE;
5131:       mat->structurally_symmetric_set = PETSC_TRUE;
5132:     }
5133:     break;
5134:   case MAT_SYMMETRIC:
5135:     mat->symmetric = flg;
5136:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5137:     mat->symmetric_set              = PETSC_TRUE;
5138:     mat->structurally_symmetric_set = flg;
5139:     break;
5140:   case MAT_HERMITIAN:
5141:     mat->hermitian = flg;
5142:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5143:     mat->hermitian_set              = PETSC_TRUE;
5144:     mat->structurally_symmetric_set = flg;
5145:     break;
5146:   case MAT_STRUCTURALLY_SYMMETRIC:
5147:     mat->structurally_symmetric     = flg;
5148:     mat->structurally_symmetric_set = PETSC_TRUE;
5149:     break;
5150:   case MAT_SYMMETRY_ETERNAL:
5151:     mat->symmetric_eternal = flg;
5152:     break;
5153:   default:
5154:     break;
5155:   }
5156:   if (mat->ops->setoption) {
5157:     (*mat->ops->setoption)(mat,op,flg);
5158:   }
5159:   return(0);
5160: }

5164: /*@
5165:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5166:    this routine retains the old nonzero structure.

5168:    Logically Collective on Mat

5170:    Input Parameters:
5171: .  mat - the matrix

5173:    Level: intermediate

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

5178:    Concepts: matrices^zeroing

5180: .seealso: MatZeroRows()
5181: @*/
5182: PetscErrorCode  MatZeroEntries(Mat mat)
5183: {

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

5194:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5195:   (*mat->ops->zeroentries)(mat);
5196:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5197:   PetscObjectStateIncrease((PetscObject)mat);
5198: #if defined(PETSC_HAVE_CUSP)
5199:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5200:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5201:   }
5202: #endif
5203:   return(0);
5204: }

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

5212:    Collective on Mat

5214:    Input Parameters:
5215: +  mat - the matrix
5216: .  numRows - the number of rows to remove
5217: .  rows - the global row indices
5218: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5219: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5220: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5239:    Level: intermediate

5241:    Concepts: matrices^zeroing rows

5243: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5244: @*/
5245: PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5246: {

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

5258:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5259:   if (mat->viewonassembly) {
5260:     PetscViewerPushFormat(mat->viewonassembly,mat->viewformatonassembly);
5261:     MatView(mat,mat->viewonassembly);
5262:     PetscViewerPopFormat(mat->viewonassembly);
5263:   }
5264:   PetscObjectStateIncrease((PetscObject)mat);
5265: #if defined(PETSC_HAVE_CUSP)
5266:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5267:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5268:   }
5269: #endif
5270:   return(0);
5271: }

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

5279:    Collective on Mat

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

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

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

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

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

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

5305:    Level: intermediate

5307:    Concepts: matrices^zeroing rows

5309: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5310: @*/
5311: PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5312: {
5314:   PetscInt       numRows;
5315:   const PetscInt *rows;

5322:   ISGetLocalSize(is,&numRows);
5323:   ISGetIndices(is,&rows);
5324:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5325:   ISRestoreIndices(is,&rows);
5326:   return(0);
5327: }

5331: /*@C
5332:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5333:    of a set of rows of a matrix.

5335:    Collective on Mat

5337:    Input Parameters:
5338: +  mat - the matrix
5339: .  numRows - the number of rows to remove
5340: .  rows - the global row indices
5341: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5342: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5343: -  b - optional vector of right hand side, that will be adjusted by provided solution

5345:    Notes:
5346:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5347:    but does not release memory.  For the dense and block diagonal
5348:    formats this does not alter the nonzero structure.

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

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

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

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

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

5369:    Level: intermediate

5371:    Concepts: matrices^zeroing rows

5373: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5374: @*/
5375: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5376: {

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

5388:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5389:   if (mat->viewonassembly) {
5390:     PetscViewerPushFormat(mat->viewonassembly,mat->viewformatonassembly);
5391:     MatView(mat,mat->viewonassembly);
5392:     PetscViewerPopFormat(mat->viewonassembly);
5393:   }
5394:   PetscObjectStateIncrease((PetscObject)mat);
5395: #if defined(PETSC_HAVE_CUSP)
5396:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5397:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5398:   }
5399: #endif
5400:   return(0);
5401: }

5405: /*@C
5406:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5407:    of a set of rows of a matrix.

5409:    Collective on Mat

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

5418:    Notes:
5419:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5420:    but does not release memory.  For the dense and block diagonal
5421:    formats this does not alter the nonzero structure.

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

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

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

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

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

5442:    Level: intermediate

5444:    Concepts: matrices^zeroing rows

5446: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5447: @*/
5448: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5449: {
5450:   PetscInt       numRows;
5451:   const PetscInt *rows;

5458:   ISGetLocalSize(is,&numRows);
5459:   ISGetIndices(is,&rows);
5460:   MatZeroRows(mat,numRows,rows,diag,x,b);
5461:   ISRestoreIndices(is,&rows);
5462:   return(0);
5463: }

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

5471:    Collective on Mat

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

5481:    Notes:
5482:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5483:    but does not release memory.  For the dense and block diagonal
5484:    formats this does not alter the nonzero structure.

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

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

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

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

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

5504:    In Fortran idxm and idxn should be declared as
5505: $     MatStencil idxm(4,m)
5506:    and the values inserted using
5507: $    idxm(MatStencil_i,1) = i
5508: $    idxm(MatStencil_j,1) = j
5509: $    idxm(MatStencil_k,1) = k
5510: $    idxm(MatStencil_c,1) = c
5511:    etc

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

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

5521:    Level: intermediate

5523:    Concepts: matrices^zeroing rows

5525: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5526: @*/
5527: PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5528: {
5529:   PetscInt       dim     = mat->stencil.dim;
5530:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5531:   PetscInt       *dims   = mat->stencil.dims+1;
5532:   PetscInt       *starts = mat->stencil.starts;
5533:   PetscInt       *dxm    = (PetscInt*) rows;
5534:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5542:   PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5543:   for (i = 0; i < numRows; ++i) {
5544:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5545:     for (j = 0; j < 3-sdim; ++j) dxm++;
5546:     /* Local index in X dir */
5547:     tmp = *dxm++ - starts[0];
5548:     /* Loop over remaining dimensions */
5549:     for (j = 0; j < dim-1; ++j) {
5550:       /* If nonlocal, set index to be negative */
5551:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5552:       /* Update local index */
5553:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5554:     }
5555:     /* Skip component slot if necessary */
5556:     if (mat->stencil.noc) dxm++;
5557:     /* Local row number */
5558:     if (tmp >= 0) {
5559:       jdxm[numNewRows++] = tmp;
5560:     }
5561:   }
5562:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5563:   PetscFree(jdxm);
5564:   return(0);
5565: }

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

5573:    Collective on Mat

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

5583:    Notes:
5584:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5585:    but does not release memory.  For the dense and block diagonal
5586:    formats this does not alter the nonzero structure.

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

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

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

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

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

5606:    In Fortran idxm and idxn should be declared as
5607: $     MatStencil idxm(4,m)
5608:    and the values inserted using
5609: $    idxm(MatStencil_i,1) = i
5610: $    idxm(MatStencil_j,1) = j
5611: $    idxm(MatStencil_k,1) = k
5612: $    idxm(MatStencil_c,1) = c
5613:    etc

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

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

5623:    Level: intermediate

5625:    Concepts: matrices^zeroing rows

5627: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5628: @*/
5629: PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5630: {
5631:   PetscInt       dim     = mat->stencil.dim;
5632:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5633:   PetscInt       *dims   = mat->stencil.dims+1;
5634:   PetscInt       *starts = mat->stencil.starts;
5635:   PetscInt       *dxm    = (PetscInt*) rows;
5636:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5644:   PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5645:   for (i = 0; i < numRows; ++i) {
5646:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5647:     for (j = 0; j < 3-sdim; ++j) dxm++;
5648:     /* Local index in X dir */
5649:     tmp = *dxm++ - starts[0];
5650:     /* Loop over remaining dimensions */
5651:     for (j = 0; j < dim-1; ++j) {
5652:       /* If nonlocal, set index to be negative */
5653:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5654:       /* Update local index */
5655:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5656:     }
5657:     /* Skip component slot if necessary */
5658:     if (mat->stencil.noc) dxm++;
5659:     /* Local row number */
5660:     if (tmp >= 0) {
5661:       jdxm[numNewRows++] = tmp;
5662:     }
5663:   }
5664:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5665:   PetscFree(jdxm);
5666:   return(0);
5667: }

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

5675:    Collective on Mat

5677:    Input Parameters:
5678: +  mat - the matrix
5679: .  numRows - the number of rows to remove
5680: .  rows - the global row indices
5681: .  diag - value put in all diagonals of eliminated rows
5682: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5683: -  b - optional vector of right hand side, that will be adjusted by provided solution

5685:    Notes:
5686:    Before calling MatZeroRowsLocal(), the user must first set the
5687:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5689:    For the AIJ matrix formats this removes the old nonzero structure,
5690:    but does not release memory.  For the dense and block diagonal
5691:    formats this does not alter the nonzero structure.

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

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

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

5704:    Level: intermediate

5706:    Concepts: matrices^zeroing

5708: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5709: @*/
5710: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5711: {
5713:   PetscMPIInt    size;

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

5723:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
5724:   if (mat->ops->zerorowslocal) {
5725:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5726:   } else if (size == 1) {
5727:     (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5728:   } else {
5729:     IS             is, newis;
5730:     const PetscInt *newRows;

5732:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5733:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5734:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5735:     ISGetIndices(newis,&newRows);
5736:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5737:     ISRestoreIndices(newis,&newRows);
5738:     ISDestroy(&newis);
5739:     ISDestroy(&is);
5740:   }
5741:   PetscObjectStateIncrease((PetscObject)mat);
5742: #if defined(PETSC_HAVE_CUSP)
5743:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5744:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5745:   }
5746: #endif
5747:   return(0);
5748: }

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

5756:    Collective on Mat

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

5765:    Notes:
5766:    Before calling MatZeroRowsLocalIS(), the user must first set the
5767:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5769:    For the AIJ matrix formats this removes the old nonzero structure,
5770:    but does not release memory.  For the dense and block diagonal
5771:    formats this does not alter the nonzero structure.

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

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

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

5784:    Level: intermediate

5786:    Concepts: matrices^zeroing

5788: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5789: @*/
5790: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5791: {
5793:   PetscInt       numRows;
5794:   const PetscInt *rows;

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

5804:   ISGetLocalSize(is,&numRows);
5805:   ISGetIndices(is,&rows);
5806:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5807:   ISRestoreIndices(is,&rows);
5808:   return(0);
5809: }

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

5817:    Collective on Mat

5819:    Input Parameters:
5820: +  mat - the matrix
5821: .  numRows - the number of rows to remove
5822: .  rows - the global row indices
5823: .  diag - value put in all diagonals of eliminated rows
5824: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5825: -  b - optional vector of right hand side, that will be adjusted by provided solution

5827:    Notes:
5828:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5829:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5835:    Level: intermediate

5837:    Concepts: matrices^zeroing

5839: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5840: @*/
5841: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5842: {
5844:   PetscMPIInt    size;

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

5854:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
5855:   if (size == 1) {
5856:     (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5857:   } else {
5858:     IS             is, newis;
5859:     const PetscInt *newRows;

5861:     if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5862:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5863:     ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5864:     ISGetIndices(newis,&newRows);
5865:     (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5866:     ISRestoreIndices(newis,&newRows);
5867:     ISDestroy(&newis);
5868:     ISDestroy(&is);
5869:   }
5870:   PetscObjectStateIncrease((PetscObject)mat);
5871: #if defined(PETSC_HAVE_CUSP)
5872:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5873:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5874:   }
5875: #endif
5876:   return(0);
5877: }

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

5885:    Collective on Mat

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

5894:    Notes:
5895:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5896:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5902:    Level: intermediate

5904:    Concepts: matrices^zeroing

5906: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5907: @*/
5908: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5909: {
5911:   PetscInt       numRows;
5912:   const PetscInt *rows;

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

5922:   ISGetLocalSize(is,&numRows);
5923:   ISGetIndices(is,&rows);
5924:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5925:   ISRestoreIndices(is,&rows);
5926:   return(0);
5927: }

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

5934:    Not Collective

5936:    Input Parameter:
5937: .  mat - the matrix

5939:    Output Parameters:
5940: +  m - the number of global rows
5941: -  n - the number of global columns

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

5945:    Level: beginner

5947:    Concepts: matrices^size

5949: .seealso: MatGetLocalSize()
5950: @*/
5951: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
5952: {
5955:   if (m) *m = mat->rmap->N;
5956:   if (n) *n = mat->cmap->N;
5957:   return(0);
5958: }

5962: /*@
5963:    MatGetLocalSize - Returns the number of rows and columns in a matrix
5964:    stored locally.  This information may be implementation dependent, so
5965:    use with care.

5967:    Not Collective

5969:    Input Parameters:
5970: .  mat - the matrix

5972:    Output Parameters:
5973: +  m - the number of local rows
5974: -  n - the number of local columns

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

5978:    Level: beginner

5980:    Concepts: matrices^local size

5982: .seealso: MatGetSize()
5983: @*/
5984: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
5985: {
5990:   if (m) *m = mat->rmap->n;
5991:   if (n) *n = mat->cmap->n;
5992:   return(0);
5993: }

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

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

6003:    Input Parameters:
6004: .  mat - the matrix

6006:    Output Parameters:
6007: +  m - the global index of the first local column
6008: -  n - one more than the global index of the last local column

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

6012:    Level: developer

6014:    Concepts: matrices^column ownership

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

6018: @*/
6019: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6020: {
6026:   MatCheckPreallocated(mat,1);
6027:   if (m) *m = mat->cmap->rstart;
6028:   if (n) *n = mat->cmap->rend;
6029:   return(0);
6030: }

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

6040:    Not Collective

6042:    Input Parameters:
6043: .  mat - the matrix

6045:    Output Parameters:
6046: +  m - the global index of the first local row
6047: -  n - one more than the global index of the last local row

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

6054:    Level: beginner

6056:    Concepts: matrices^row ownership

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

6060: @*/
6061: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6062: {
6068:   MatCheckPreallocated(mat,1);
6069:   if (m) *m = mat->rmap->rstart;
6070:   if (n) *n = mat->rmap->rend;
6071:   return(0);
6072: }

6076: /*@C
6077:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6078:    each process

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

6082:    Input Parameters:
6083: .  mat - the matrix

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

6088:    Level: beginner

6090:    Concepts: matrices^row ownership

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

6094: @*/
6095: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6096: {

6102:   MatCheckPreallocated(mat,1);
6103:   PetscLayoutGetRanges(mat->rmap,ranges);
6104:   return(0);
6105: }

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

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

6115:    Input Parameters:
6116: .  mat - the matrix

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

6121:    Level: beginner

6123:    Concepts: matrices^column ownership

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

6127: @*/
6128: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6129: {

6135:   MatCheckPreallocated(mat,1);
6136:   PetscLayoutGetRanges(mat->cmap,ranges);
6137:   return(0);
6138: }

6142: /*@C
6143:    MatGetOwnershipIS - Get row and column ownership as index sets

6145:    Not Collective

6147:    Input Arguments:
6148: .  A - matrix of type Elemental

6150:    Output Arguments:
6151: +  rows - rows in which this process owns elements
6152: .  cols - columns in which this process owns elements

6154:    Level: intermediate

6156: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6157: @*/
6158: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6159: {
6160:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6163:   MatCheckPreallocated(A,1);
6164:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6165:   if (f) {
6166:     (*f)(A,rows,cols);
6167:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6168:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6169:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6170:   }
6171:   return(0);
6172: }

6176: /*@C
6177:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6178:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6179:    to complete the factorization.

6181:    Collective on Mat

6183:    Input Parameters:
6184: +  mat - the matrix
6185: .  row - row permutation
6186: .  column - column permutation
6187: -  info - structure containing
6188: $      levels - number of levels of fill.
6189: $      expected fill - as ratio of original fill.
6190: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6191:                 missing diagonal entries)

6193:    Output Parameters:
6194: .  fact - new matrix that has been symbolically factored

6196:    Notes:
6197:    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
6198:    choosing the fill factor for better efficiency.

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

6204:    Level: developer

6206:   Concepts: matrices^symbolic LU factorization
6207:   Concepts: matrices^factorization
6208:   Concepts: LU^symbolic factorization

6210: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6211:           MatGetOrdering(), MatFactorInfo

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

6216: @*/
6217: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6218: {

6228:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6229:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6230:   if (!(fact)->ops->ilufactorsymbolic) {
6231:     const MatSolverPackage spackage;
6232:     MatFactorGetSolverPackage(fact,&spackage);
6233:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6234:   }
6235:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6236:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6237:   MatCheckPreallocated(mat,2);

6239:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6240:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6241:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6242:   return(0);
6243: }

6247: /*@C
6248:    MatICCFactorSymbolic - Performs symbolic incomplete
6249:    Cholesky factorization for a symmetric matrix.  Use
6250:    MatCholeskyFactorNumeric() to complete the factorization.

6252:    Collective on Mat

6254:    Input Parameters:
6255: +  mat - the matrix
6256: .  perm - row and column permutation
6257: -  info - structure containing
6258: $      levels - number of levels of fill.
6259: $      expected fill - as ratio of original fill.

6261:    Output Parameter:
6262: .  fact - the factored matrix

6264:    Notes:
6265:    Most users should employ the KSP interface for linear solvers
6266:    instead of working directly with matrix algebra routines such as this.
6267:    See, e.g., KSPCreate().

6269:    Level: developer

6271:   Concepts: matrices^symbolic incomplete Cholesky factorization
6272:   Concepts: matrices^factorization
6273:   Concepts: Cholsky^symbolic factorization

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

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

6280: @*/
6281: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6282: {

6291:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6292:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6293:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6294:   if (!(fact)->ops->iccfactorsymbolic) {
6295:     const MatSolverPackage spackage;
6296:     MatFactorGetSolverPackage(fact,&spackage);
6297:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6298:   }
6299:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6300:   MatCheckPreallocated(mat,2);

6302:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6303:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6304:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6305:   return(0);
6306: }

6310: /*@C
6311:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6312:    points to an array of valid matrices, they may be reused to store the new
6313:    submatrices.

6315:    Collective on Mat

6317:    Input Parameters:
6318: +  mat - the matrix
6319: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6320: .  irow, icol - index sets of rows and columns to extract (must be sorted)
6321: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6323:    Output Parameter:
6324: .  submat - the array of submatrices

6326:    Notes:
6327:    MatGetSubMatrices() can extract ONLY sequential submatrices
6328:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6329:    to extract a parallel submatrix.

6331:    Currently both row and column indices must be sorted to guarantee
6332:    correctness with all matrix types.

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

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

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

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

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

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

6356:    Level: advanced

6358:    Concepts: matrices^accessing submatrices
6359:    Concepts: submatrices

6361: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6362: @*/
6363: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6364: {
6366:   PetscInt       i;
6367:   PetscBool      eq;

6372:   if (n) {
6377:   }
6379:   if (n && scall == MAT_REUSE_MATRIX) {
6382:   }
6383:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6384:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6385:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6386:   MatCheckPreallocated(mat,1);

6388:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6389:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6390:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6391:   for (i=0; i<n; i++) {
6392:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6393:       ISEqual(irow[i],icol[i],&eq);
6394:       if (eq) {
6395:         if (mat->symmetric) {
6396:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6397:         } else if (mat->hermitian) {
6398:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6399:         } else if (mat->structurally_symmetric) {
6400:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6401:         }
6402:       }
6403:     }
6404:   }
6405:   return(0);
6406: }

6410: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6411: {
6413:   PetscInt       i;
6414:   PetscBool      eq;

6419:   if (n) {
6424:   }
6426:   if (n && scall == MAT_REUSE_MATRIX) {
6429:   }
6430:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6431:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6432:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6433:   MatCheckPreallocated(mat,1);

6435:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6436:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6437:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6438:   for (i=0; i<n; i++) {
6439:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6440:       ISEqual(irow[i],icol[i],&eq);
6441:       if (eq) {
6442:         if (mat->symmetric) {
6443:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6444:         } else if (mat->hermitian) {
6445:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6446:         } else if (mat->structurally_symmetric) {
6447:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6448:         }
6449:       }
6450:     }
6451:   }
6452:   return(0);
6453: }

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

6460:    Collective on Mat

6462:    Input Parameters:
6463: +  n - the number of local matrices
6464: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6465:                        sequence of MatGetSubMatrices())

6467:    Level: advanced

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

6472: .seealso: MatGetSubMatrices()
6473: @*/
6474: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6475: {
6477:   PetscInt       i;

6480:   if (!*mat) return(0);
6481:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6483:   for (i=0; i<n; i++) {
6484:     MatDestroy(&(*mat)[i]);
6485:   }
6486:   /* memory is allocated even if n = 0 */
6487:   PetscFree(*mat);
6488:   *mat = NULL;
6489:   return(0);
6490: }

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

6497:    Collective on Mat

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

6502:    Output Parameter:
6503: .  matstruct - the sequential matrix with the nonzero structure of mat

6505:   Level: intermediate

6507: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6508: @*/
6509: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6510: {


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

6521:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6522:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6523:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6524:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6525:   return(0);
6526: }

6530: /*@C
6531:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6533:    Collective on Mat

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

6539:    Level: advanced

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

6543: .seealso: MatGetSeqNonzeroStructure()
6544: @*/
6545: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6546: {

6551:   MatDestroy(mat);
6552:   return(0);
6553: }

6557: /*@
6558:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6559:    replaces the index sets by larger ones that represent submatrices with
6560:    additional overlap.

6562:    Collective on Mat

6564:    Input Parameters:
6565: +  mat - the matrix
6566: .  n   - the number of index sets
6567: .  is  - the array of index sets (these index sets will changed during the call)
6568: -  ov  - the additional overlap requested

6570:    Level: developer

6572:    Concepts: overlap
6573:    Concepts: ASM^computing overlap

6575: .seealso: MatGetSubMatrices()
6576: @*/
6577: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6578: {

6584:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6585:   if (n) {
6588:   }
6589:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6590:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6591:   MatCheckPreallocated(mat,1);

6593:   if (!ov) return(0);
6594:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6595:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6596:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6597:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6598:   return(0);
6599: }

6603: /*@
6604:    MatGetBlockSize - Returns the matrix block size; useful especially for the
6605:    block row and block diagonal formats.

6607:    Not Collective

6609:    Input Parameter:
6610: .  mat - the matrix

6612:    Output Parameter:
6613: .  bs - block size

6615:    Notes:
6616:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

6618:    Level: intermediate

6620:    Concepts: matrices^block size

6622: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6623: @*/
6624: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6625: {
6630:   MatCheckPreallocated(mat,1);
6631:   *bs = mat->rmap->bs;
6632:   return(0);
6633: }

6637: /*@
6638:    MatGetBlockSizes - Returns the matrix block row and column sizes;
6639:    useful especially for the block row and block diagonal formats.

6641:    Not Collective

6643:    Input Parameter:
6644: .  mat - the matrix

6646:    Output Parameter:
6647: .  rbs - row block size
6648: .  cbs - coumn block size

6650:    Notes:
6651:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

6653:    Level: intermediate

6655:    Concepts: matrices^block size

6657: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6658: @*/
6659: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6660: {
6666:   MatCheckPreallocated(mat,1);
6667:   if (rbs) *rbs = mat->rmap->bs;
6668:   if (cbs) *cbs = mat->cmap->bs;
6669:   return(0);
6670: }

6674: /*@
6675:    MatSetBlockSize - Sets the matrix block size.

6677:    Logically Collective on Mat

6679:    Input Parameters:
6680: +  mat - the matrix
6681: -  bs - block size

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

6686:    Level: intermediate

6688:    Concepts: matrices^block size

6690: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6691: @*/
6692: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6693: {

6699:   PetscLayoutSetBlockSize(mat->rmap,bs);
6700:   PetscLayoutSetBlockSize(mat->cmap,bs);
6701:   return(0);
6702: }

6706: /*@
6707:    MatSetBlockSizes - Sets the matrix block row and column sizes.

6709:    Logically Collective on Mat

6711:    Input Parameters:
6712: +  mat - the matrix
6713: -  rbs - row block size
6714: -  cbs - column block size

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

6719:    Level: intermediate

6721:    Concepts: matrices^block size

6723: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6724: @*/
6725: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6726: {

6733:   PetscLayoutSetBlockSize(mat->rmap,rbs);
6734:   PetscLayoutSetBlockSize(mat->cmap,cbs);
6735:   return(0);
6736: }

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

6743:    Collective on Mat

6745:     Input Parameters:
6746: +   mat - the matrix
6747: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6748: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6749: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6750:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6751:                  always used.

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

6760:     Level: developer

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

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

6766:     Fortran Node

6768:            In Fortran use
6769: $           PetscInt ia(1), ja(1)
6770: $           PetscOffset iia, jja
6771: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6772: $
6773: $          or
6774: $
6775: $           PetscScalar, pointer :: xx_v(:)
6776: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)


6779:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

6781: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6782: @*/
6783: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6784: {

6794:   MatCheckPreallocated(mat,1);
6795:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6796:   else {
6797:     *done = PETSC_TRUE;
6798:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6799:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6800:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6801:   }
6802:   return(0);
6803: }

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

6810:     Collective on Mat

6812:     Input Parameters:
6813: +   mat - the matrix
6814: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6815: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6816:                 symmetrized
6817: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6818:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6819:                  always used.

6821:     Output Parameters:
6822: +   n - number of columns in the (possibly compressed) matrix
6823: .   ia - the column pointers
6824: .   ja - the row indices
6825: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6827:     Level: developer

6829: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6830: @*/
6831: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6832: {

6842:   MatCheckPreallocated(mat,1);
6843:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6844:   else {
6845:     *done = PETSC_TRUE;
6846:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6847:   }
6848:   return(0);
6849: }

6853: /*@C
6854:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6855:     MatGetRowIJ().

6857:     Collective on Mat

6859:     Input Parameters:
6860: +   mat - the matrix
6861: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6862: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6863:                 symmetrized
6864: -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6865:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6866:                  always used.

6868:     Output Parameters:
6869: +   n - size of (possibly compressed) matrix
6870: .   ia - the row pointers
6871: .   ja - the column indices
6872: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6874:     Level: developer

6876: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6877: @*/
6878: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6879: {

6888:   MatCheckPreallocated(mat,1);

6890:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6891:   else {
6892:     *done = PETSC_TRUE;
6893:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6894:     if (n)  *n = 0;
6895:     if (ia) *ia = NULL;
6896:     if (ja) *ja = NULL;
6897:   }
6898:   return(0);
6899: }

6903: /*@C
6904:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6905:     MatGetColumnIJ().

6907:     Collective on Mat

6909:     Input Parameters:
6910: +   mat - the matrix
6911: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6912: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6913:                 symmetrized
6914: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6915:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6916:                  always used.

6918:     Output Parameters:
6919: +   n - size of (possibly compressed) matrix
6920: .   ia - the column pointers
6921: .   ja - the row indices
6922: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6924:     Level: developer

6926: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6927: @*/
6928: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6929: {

6938:   MatCheckPreallocated(mat,1);

6940:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6941:   else {
6942:     *done = PETSC_TRUE;
6943:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6944:     if (n)  *n = 0;
6945:     if (ia) *ia = NULL;
6946:     if (ja) *ja = NULL;
6947:   }
6948:   return(0);
6949: }

6953: /*@C
6954:     MatColoringPatch -Used inside matrix coloring routines that
6955:     use MatGetRowIJ() and/or MatGetColumnIJ().

6957:     Collective on Mat

6959:     Input Parameters:
6960: +   mat - the matrix
6961: .   ncolors - max color value
6962: .   n   - number of entries in colorarray
6963: -   colorarray - array indicating color for each column

6965:     Output Parameters:
6966: .   iscoloring - coloring generated using colorarray information

6968:     Level: developer

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

6972: @*/
6973: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6974: {

6982:   MatCheckPreallocated(mat,1);

6984:   if (!mat->ops->coloringpatch) {
6985:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);
6986:   } else {
6987:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6988:   }
6989:   return(0);
6990: }


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

6998:    Logically Collective on Mat

7000:    Input Parameter:
7001: .  mat - the factored matrix to be reset

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

7010:    Note that one can specify in-place ILU(0) factorization by calling
7011: .vb
7012:      PCType(pc,PCILU);
7013:      PCFactorSeUseInPlace(pc);
7014: .ve
7015:    or by using the options -pc_type ilu -pc_factor_in_place

7017:    In-place factorization ILU(0) can also be used as a local
7018:    solver for the blocks within the block Jacobi or additive Schwarz
7019:    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
7020:    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7021:    local solver options.

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

7027:    Level: developer

7029: .seealso: PCFactorSetUseInPlace()

7031:    Concepts: matrices^unfactored

7033: @*/
7034: PetscErrorCode  MatSetUnfactored(Mat mat)
7035: {

7041:   MatCheckPreallocated(mat,1);
7042:   mat->factortype = MAT_FACTOR_NONE;
7043:   if (!mat->ops->setunfactored) return(0);
7044:   (*mat->ops->setunfactored)(mat);
7045:   return(0);
7046: }

7048: /*MC
7049:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7051:     Synopsis:
7052:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7054:     Not collective

7056:     Input Parameter:
7057: .   x - matrix

7059:     Output Parameters:
7060: +   xx_v - the Fortran90 pointer to the array
7061: -   ierr - error code

7063:     Example of Usage:
7064: .vb
7065:       PetscScalar, pointer xx_v(:,:)
7066:       ....
7067:       call MatDenseGetArrayF90(x,xx_v,ierr)
7068:       a = xx_v(3)
7069:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7070: .ve

7072:     Level: advanced

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

7076:     Concepts: matrices^accessing array

7078: M*/

7080: /*MC
7081:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7082:     accessed with MatDenseGetArrayF90().

7084:     Synopsis:
7085:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7087:     Not collective

7089:     Input Parameters:
7090: +   x - matrix
7091: -   xx_v - the Fortran90 pointer to the array

7093:     Output Parameter:
7094: .   ierr - error code

7096:     Example of Usage:
7097: .vb
7098:        PetscScalar, pointer xx_v(:)
7099:        ....
7100:        call MatDenseGetArrayF90(x,xx_v,ierr)
7101:        a = xx_v(3)
7102:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7103: .ve

7105:     Level: advanced

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

7109: M*/


7112: /*MC
7113:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7115:     Synopsis:
7116:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7118:     Not collective

7120:     Input Parameter:
7121: .   x - matrix

7123:     Output Parameters:
7124: +   xx_v - the Fortran90 pointer to the array
7125: -   ierr - error code

7127:     Example of Usage:
7128: .vb
7129:       PetscScalar, pointer xx_v(:,:)
7130:       ....
7131:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7132:       a = xx_v(3)
7133:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7134: .ve

7136:     Level: advanced

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

7140:     Concepts: matrices^accessing array

7142: M*/

7144: /*MC
7145:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7146:     accessed with MatSeqAIJGetArrayF90().

7148:     Synopsis:
7149:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7151:     Not collective

7153:     Input Parameters:
7154: +   x - matrix
7155: -   xx_v - the Fortran90 pointer to the array

7157:     Output Parameter:
7158: .   ierr - error code

7160:     Example of Usage:
7161: .vb
7162:        PetscScalar, pointer xx_v(:)
7163:        ....
7164:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7165:        a = xx_v(3)
7166:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7167: .ve

7169:     Level: advanced

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

7173: M*/


7178: /*@
7179:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7180:                       as the original matrix.

7182:     Collective on Mat

7184:     Input Parameters:
7185: +   mat - the original matrix
7186: .   isrow - parallel IS containing the rows this processor should obtain
7187: .   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.
7188: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7190:     Output Parameter:
7191: .   newmat - the new submatrix, of the same type as the old

7193:     Level: advanced

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

7198:     The rows in isrow will be sorted into the same order as the original matrix on each process.

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

7206:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7207:     the input matrix.

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

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

7217: .vb
7218:             1  2  0  |  0  3  0  |  0  4
7219:     Proc0   0  5  6  |  7  0  0  |  8  0
7220:             9  0 10  | 11  0  0  | 12  0
7221:     -------------------------------------
7222:            13  0 14  | 15 16 17  |  0  0
7223:     Proc1   0 18  0  | 19 20 21  |  0  0
7224:             0  0  0  | 22 23  0  | 24  0
7225:     -------------------------------------
7226:     Proc2  25 26 27  |  0  0 28  | 29  0
7227:            30  0  0  | 31 32 33  |  0 34
7228: .ve

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

7232: .vb
7233:             2  0  |  0  3  0  |  0
7234:     Proc0   5  6  |  7  0  0  |  8
7235:     -------------------------------
7236:     Proc1  18  0  | 19 20 21  |  0
7237:     -------------------------------
7238:     Proc2  26 27  |  0  0 28  | 29
7239:             0  0  | 31 32 33  |  0
7240: .ve


7243:     Concepts: matrices^submatrices

7245: .seealso: MatGetSubMatrices()
7246: @*/
7247: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7248: {
7250:   PetscMPIInt    size;
7251:   Mat            *local;
7252:   IS             iscoltmp;

7261:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7262:   MatCheckPreallocated(mat,1);
7263:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7265:   if (!iscol) {
7266:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7267:   } else {
7268:     iscoltmp = iscol;
7269:   }

7271:   /* if original matrix is on just one processor then use submatrix generated */
7272:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7273:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7274:     if (!iscol) {ISDestroy(&iscoltmp);}
7275:     return(0);
7276:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7277:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7278:     *newmat = *local;
7279:     PetscFree(local);
7280:     if (!iscol) {ISDestroy(&iscoltmp);}
7281:     return(0);
7282:   } else if (!mat->ops->getsubmatrix) {
7283:     /* Create a new matrix type that implements the operation using the full matrix */
7284:     switch (cll) {
7285:     case MAT_INITIAL_MATRIX:
7286:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7287:       break;
7288:     case MAT_REUSE_MATRIX:
7289:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7290:       break;
7291:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7292:     }
7293:     if (!iscol) {ISDestroy(&iscoltmp);}
7294:     return(0);
7295:   }

7297:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7298:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7299:   if (!iscol) {ISDestroy(&iscoltmp);}
7300:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7301:   return(0);
7302: }

7306: /*@
7307:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7308:    used during the assembly process to store values that belong to
7309:    other processors.

7311:    Not Collective

7313:    Input Parameters:
7314: +  mat   - the matrix
7315: .  size  - the initial size of the stash.
7316: -  bsize - the initial size of the block-stash(if used).

7318:    Options Database Keys:
7319: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7320: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7322:    Level: intermediate

7324:    Notes:
7325:      The block-stash is used for values set with MatSetValuesBlocked() while
7326:      the stash is used for values set with MatSetValues()

7328:      Run with the option -info and look for output of the form
7329:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7330:      to determine the appropriate value, MM, to use for size and
7331:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7332:      to determine the value, BMM to use for bsize

7334:    Concepts: stash^setting matrix size
7335:    Concepts: matrices^stash

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

7339: @*/
7340: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7341: {

7347:   MatStashSetInitialSize_Private(&mat->stash,size);
7348:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7349:   return(0);
7350: }

7354: /*@
7355:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7356:      the matrix

7358:    Neighbor-wise Collective on Mat

7360:    Input Parameters:
7361: +  mat   - the matrix
7362: .  x,y - the vectors
7363: -  w - where the result is stored

7365:    Level: intermediate

7367:    Notes:
7368:     w may be the same vector as y.

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

7373:     Concepts: interpolation

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

7377: @*/
7378: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7379: {
7381:   PetscInt       M,N,Ny;

7389:   MatCheckPreallocated(A,1);
7390:   MatGetSize(A,&M,&N);
7391:   VecGetSize(y,&Ny);
7392:   if (M == Ny) {
7393:     MatMultAdd(A,x,y,w);
7394:   } else {
7395:     MatMultTransposeAdd(A,x,y,w);
7396:   }
7397:   return(0);
7398: }

7402: /*@
7403:    MatInterpolate - y = A*x or A'*x depending on the shape of
7404:      the matrix

7406:    Neighbor-wise Collective on Mat

7408:    Input Parameters:
7409: +  mat   - the matrix
7410: -  x,y - the vectors

7412:    Level: intermediate

7414:    Notes:
7415:     This allows one to use either the restriction or interpolation (its transpose)
7416:     matrix to do the interpolation

7418:    Concepts: matrices^interpolation

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

7422: @*/
7423: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7424: {
7426:   PetscInt       M,N,Ny;

7433:   MatCheckPreallocated(A,1);
7434:   MatGetSize(A,&M,&N);
7435:   VecGetSize(y,&Ny);
7436:   if (M == Ny) {
7437:     MatMult(A,x,y);
7438:   } else {
7439:     MatMultTranspose(A,x,y);
7440:   }
7441:   return(0);
7442: }

7446: /*@
7447:    MatRestrict - y = A*x or A'*x

7449:    Neighbor-wise Collective on Mat

7451:    Input Parameters:
7452: +  mat   - the matrix
7453: -  x,y - the vectors

7455:    Level: intermediate

7457:    Notes:
7458:     This allows one to use either the restriction or interpolation (its transpose)
7459:     matrix to do the restriction

7461:    Concepts: matrices^restriction

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

7465: @*/
7466: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7467: {
7469:   PetscInt       M,N,Ny;

7476:   MatCheckPreallocated(A,1);

7478:   MatGetSize(A,&M,&N);
7479:   VecGetSize(y,&Ny);
7480:   if (M == Ny) {
7481:     MatMult(A,x,y);
7482:   } else {
7483:     MatMultTranspose(A,x,y);
7484:   }
7485:   return(0);
7486: }

7490: /*@
7491:    MatGetNullSpace - retrieves the null space to a matrix.

7493:    Logically Collective on Mat and MatNullSpace

7495:    Input Parameters:
7496: +  mat - the matrix
7497: -  nullsp - the null space object

7499:    Level: developer

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

7504:    Concepts: null space^attaching to matrix

7506: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7507: @*/
7508: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7509: {
7514:   *nullsp = mat->nullsp;
7515:   return(0);
7516: }

7520: /*@
7521:    MatSetNullSpace - attaches a null space to a matrix.
7522:         This null space will be removed from the resulting vector whenever
7523:         MatMult() is called

7525:    Logically Collective on Mat and MatNullSpace

7527:    Input Parameters:
7528: +  mat - the matrix
7529: -  nullsp - the null space object

7531:    Level: advanced

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

7536:    Concepts: null space^attaching to matrix

7538: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7539: @*/
7540: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7541: {

7548:   MatCheckPreallocated(mat,1);
7549:   PetscObjectReference((PetscObject)nullsp);
7550:   MatNullSpaceDestroy(&mat->nullsp);

7552:   mat->nullsp = nullsp;
7553:   return(0);
7554: }

7558: /*@
7559:    MatSetNearNullSpace - attaches a null space to a matrix.
7560:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

7562:    Logically Collective on Mat and MatNullSpace

7564:    Input Parameters:
7565: +  mat - the matrix
7566: -  nullsp - the null space object

7568:    Level: advanced

7570:    Notes:
7571:       Overwrites any previous near null space that may have been attached

7573:    Concepts: null space^attaching to matrix

7575: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7576: @*/
7577: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7578: {

7585:   MatCheckPreallocated(mat,1);
7586:   PetscObjectReference((PetscObject)nullsp);
7587:   MatNullSpaceDestroy(&mat->nearnullsp);

7589:   mat->nearnullsp = nullsp;
7590:   return(0);
7591: }

7595: /*@
7596:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

7598:    Not Collective

7600:    Input Parameters:
7601: .  mat - the matrix

7603:    Output Parameters:
7604: .  nullsp - the null space object, NULL if not set

7606:    Level: developer

7608:    Concepts: null space^attaching to matrix

7610: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7611: @*/
7612: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7613: {
7618:   MatCheckPreallocated(mat,1);
7619:   *nullsp = mat->nearnullsp;
7620:   return(0);
7621: }

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

7628:    Collective on Mat

7630:    Input Parameters:
7631: +  mat - the matrix
7632: .  row - row/column permutation
7633: .  fill - expected fill factor >= 1.0
7634: -  level - level of fill, for ICC(k)

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

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

7644:    Level: developer

7646:    Concepts: matrices^incomplete Cholesky factorization
7647:    Concepts: Cholesky factorization

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

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

7654: @*/
7655: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7656: {

7664:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
7665:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7666:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7667:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7668:   MatCheckPreallocated(mat,1);
7669:   (*mat->ops->iccfactor)(mat,row,info);
7670:   PetscObjectStateIncrease((PetscObject)mat);
7671:   return(0);
7672: }

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

7679:    Not Collective

7681:    Input Parameters:
7682: +  mat - the matrix
7683: .  nl - leading dimension of v
7684: -  v - the values compute with ADIFOR

7686:    Level: developer

7688:    Notes:
7689:      Must call MatSetColoring() before using this routine. Also this matrix must already
7690:      have its nonzero pattern determined.

7692: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7693:           MatSetValues(), MatSetColoring()
7694: @*/
7695: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7696: {


7704:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7705:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7706:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7707:   (*mat->ops->setvaluesadifor)(mat,nl,v);
7708:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7709:   PetscObjectStateIncrease((PetscObject)mat);
7710:   return(0);
7711: }

7715: /*@
7716:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7717:          ghosted ones.

7719:    Not Collective

7721:    Input Parameters:
7722: +  mat - the matrix
7723: -  diag = the diagonal values, including ghost ones

7725:    Level: developer

7727:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

7729: .seealso: MatDiagonalScale()
7730: @*/
7731: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7732: {
7734:   PetscMPIInt    size;


7741:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7742:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7743:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7744:   if (size == 1) {
7745:     PetscInt n,m;
7746:     VecGetSize(diag,&n);
7747:     MatGetSize(mat,0,&m);
7748:     if (m == n) {
7749:       MatDiagonalScale(mat,0,diag);
7750:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7751:   } else {
7752:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7753:   }
7754:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7755:   PetscObjectStateIncrease((PetscObject)mat);
7756:   return(0);
7757: }

7761: /*@
7762:    MatGetInertia - Gets the inertia from a factored matrix

7764:    Collective on Mat

7766:    Input Parameter:
7767: .  mat - the matrix

7769:    Output Parameters:
7770: +   nneg - number of negative eigenvalues
7771: .   nzero - number of zero eigenvalues
7772: -   npos - number of positive eigenvalues

7774:    Level: advanced

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


7779: @*/
7780: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7781: {

7787:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7788:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7789:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7790:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7791:   return(0);
7792: }

7794: /* ----------------------------------------------------------------*/
7797: /*@C
7798:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

7800:    Neighbor-wise Collective on Mat and Vecs

7802:    Input Parameters:
7803: +  mat - the factored matrix
7804: -  b - the right-hand-side vectors

7806:    Output Parameter:
7807: .  x - the result vectors

7809:    Notes:
7810:    The vectors b and x cannot be the same.  I.e., one cannot
7811:    call MatSolves(A,x,x).

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

7818:    Level: developer

7820:    Concepts: matrices^triangular solves

7822: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7823: @*/
7824: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7825: {

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

7835:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7836:   MatCheckPreallocated(mat,1);
7837:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7838:   (*mat->ops->solves)(mat,b,x);
7839:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7840:   return(0);
7841: }

7845: /*@
7846:    MatIsSymmetric - Test whether a matrix is symmetric

7848:    Collective on Mat

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

7854:    Output Parameters:
7855: .  flg - the result

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

7859:    Level: intermediate

7861:    Concepts: matrix^symmetry

7863: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7864: @*/
7865: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7866: {


7873:   if (!A->symmetric_set) {
7874:     if (!A->ops->issymmetric) {
7875:       MatType mattype;
7876:       MatGetType(A,&mattype);
7877:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7878:     }
7879:     (*A->ops->issymmetric)(A,tol,flg);
7880:     if (!tol) {
7881:       A->symmetric_set = PETSC_TRUE;
7882:       A->symmetric     = *flg;
7883:       if (A->symmetric) {
7884:         A->structurally_symmetric_set = PETSC_TRUE;
7885:         A->structurally_symmetric     = PETSC_TRUE;
7886:       }
7887:     }
7888:   } else if (A->symmetric) {
7889:     *flg = PETSC_TRUE;
7890:   } else if (!tol) {
7891:     *flg = PETSC_FALSE;
7892:   } else {
7893:     if (!A->ops->issymmetric) {
7894:       MatType mattype;
7895:       MatGetType(A,&mattype);
7896:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7897:     }
7898:     (*A->ops->issymmetric)(A,tol,flg);
7899:   }
7900:   return(0);
7901: }

7905: /*@
7906:    MatIsHermitian - Test whether a matrix is Hermitian

7908:    Collective on Mat

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

7914:    Output Parameters:
7915: .  flg - the result

7917:    Level: intermediate

7919:    Concepts: matrix^symmetry

7921: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7922:           MatIsSymmetricKnown(), MatIsSymmetric()
7923: @*/
7924: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7925: {


7932:   if (!A->hermitian_set) {
7933:     if (!A->ops->ishermitian) {
7934:       MatType mattype;
7935:       MatGetType(A,&mattype);
7936:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7937:     }
7938:     (*A->ops->ishermitian)(A,tol,flg);
7939:     if (!tol) {
7940:       A->hermitian_set = PETSC_TRUE;
7941:       A->hermitian     = *flg;
7942:       if (A->hermitian) {
7943:         A->structurally_symmetric_set = PETSC_TRUE;
7944:         A->structurally_symmetric     = PETSC_TRUE;
7945:       }
7946:     }
7947:   } else if (A->hermitian) {
7948:     *flg = PETSC_TRUE;
7949:   } else if (!tol) {
7950:     *flg = PETSC_FALSE;
7951:   } else {
7952:     if (!A->ops->ishermitian) {
7953:       MatType mattype;
7954:       MatGetType(A,&mattype);
7955:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7956:     }
7957:     (*A->ops->ishermitian)(A,tol,flg);
7958:   }
7959:   return(0);
7960: }

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

7967:    Not Collective

7969:    Input Parameter:
7970: .  A - the matrix to check

7972:    Output Parameters:
7973: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7974: -  flg - the result

7976:    Level: advanced

7978:    Concepts: matrix^symmetry

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

7983: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7984: @*/
7985: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7986: {
7991:   if (A->symmetric_set) {
7992:     *set = PETSC_TRUE;
7993:     *flg = A->symmetric;
7994:   } else {
7995:     *set = PETSC_FALSE;
7996:   }
7997:   return(0);
7998: }

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

8005:    Not Collective

8007:    Input Parameter:
8008: .  A - the matrix to check

8010:    Output Parameters:
8011: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8012: -  flg - the result

8014:    Level: advanced

8016:    Concepts: matrix^symmetry

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

8021: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8022: @*/
8023: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8024: {
8029:   if (A->hermitian_set) {
8030:     *set = PETSC_TRUE;
8031:     *flg = A->hermitian;
8032:   } else {
8033:     *set = PETSC_FALSE;
8034:   }
8035:   return(0);
8036: }

8040: /*@
8041:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8043:    Collective on Mat

8045:    Input Parameter:
8046: .  A - the matrix to test

8048:    Output Parameters:
8049: .  flg - the result

8051:    Level: intermediate

8053:    Concepts: matrix^symmetry

8055: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8056: @*/
8057: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8058: {

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

8068:     A->structurally_symmetric_set = PETSC_TRUE;
8069:   }
8070:   *flg = A->structurally_symmetric;
8071:   return(0);
8072: }

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

8081:     Not collective

8083:    Input Parameter:
8084: .   vec - the vector

8086:    Output Parameters:
8087: +   nstash   - the size of the stash
8088: .   reallocs - the number of additional mallocs incurred.
8089: .   bnstash   - the size of the block stash
8090: -   breallocs - the number of additional mallocs incurred.in the block stash

8092:    Level: advanced

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

8096: @*/
8097: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8098: {

8102:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8103:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8104:   return(0);
8105: }

8109: /*@C
8110:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8111:      parallel layout

8113:    Collective on Mat

8115:    Input Parameter:
8116: .  mat - the matrix

8118:    Output Parameter:
8119: +   right - (optional) vector that the matrix can be multiplied against
8120: -   left - (optional) vector that the matrix vector product can be stored in

8122:   Level: advanced

8124: .seealso: MatCreate()
8125: @*/
8126: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8127: {

8133:   MatCheckPreallocated(mat,1);
8134:   if (mat->ops->getvecs) {
8135:     (*mat->ops->getvecs)(mat,right,left);
8136:   } else {
8137:     PetscMPIInt size;
8138:     MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8139:     if (right) {
8140:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8141:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8142:       VecSetBlockSize(*right,mat->rmap->bs);
8143:       VecSetType(*right,VECSTANDARD);
8144:       PetscLayoutReference(mat->cmap,&(*right)->map);
8145:     }
8146:     if (left) {
8147:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8148:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8149:       VecSetBlockSize(*left,mat->rmap->bs);
8150:       VecSetType(*left,VECSTANDARD);
8151:       PetscLayoutReference(mat->rmap,&(*left)->map);
8152:     }
8153:   }
8154:   return(0);
8155: }

8159: /*@C
8160:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8161:      with default values.

8163:    Not Collective

8165:    Input Parameters:
8166: .    info - the MatFactorInfo data structure


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

8172:    Level: developer

8174: .seealso: MatFactorInfo

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

8179: @*/

8181: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8182: {

8186:   PetscMemzero(info,sizeof(MatFactorInfo));
8187:   return(0);
8188: }

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

8195:    Neighbor-wise Collective on Mat

8197:    Input Parameters:
8198: +  A - the matrix
8199: .  P - the projection matrix
8200: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8201: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

8203:    Output Parameters:
8204: .  C - the product matrix

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

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

8212:    Level: intermediate

8214: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8215: @*/
8216: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8217: {
8219:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8220:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8221:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8222:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

8225:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8226:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

8230:   MatCheckPreallocated(A,1);
8231:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8232:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8235:   MatCheckPreallocated(P,2);
8236:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8237:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8239:   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);
8240:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

8242:   if (scall == MAT_REUSE_MATRIX) {
8245:     if (viatranspose || viamatmatmatmult) {
8246:       Mat Pt;
8247:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8248:       if (viamatmatmatmult) {
8249:         MatMatMatMult(Pt,A,P,scall,fill,C);
8250:       } else {
8251:         Mat AP;
8252:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8253:         MatMatMult(Pt,AP,scall,fill,C);
8254:         MatDestroy(&AP);
8255:       }
8256:       MatDestroy(&Pt);
8257:     } else {
8258:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8259:       (*(*C)->ops->ptapnumeric)(A,P,*C);
8260:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8261:     }
8262:     return(0);
8263:   }

8265:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8266:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

8268:   fA = A->ops->ptap;
8269:   fP = P->ops->ptap;
8270:   if (fP == fA) {
8271:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8272:     ptap = fA;
8273:   } else {
8274:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8275:     char ptapname[256];
8276:     PetscStrcpy(ptapname,"MatPtAP_");
8277:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
8278:     PetscStrcat(ptapname,"_");
8279:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
8280:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8281:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8282:     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);
8283:   }

8285:   if (viatranspose || viamatmatmatmult) {
8286:     Mat Pt;
8287:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8288:     if (viamatmatmatmult) {
8289:       MatMatMatMult(Pt,A,P,scall,fill,C);
8290:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8291:     } else {
8292:       Mat AP;
8293:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8294:       MatMatMult(Pt,AP,scall,fill,C);
8295:       MatDestroy(&AP);
8296:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8297:     }
8298:     MatDestroy(&Pt);
8299:   } else {
8300:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8301:     (*ptap)(A,P,scall,fill,C);
8302:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8303:   }
8304:   return(0);
8305: }

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

8312:    Neighbor-wise Collective on Mat

8314:    Input Parameters:
8315: +  A - the matrix
8316: -  P - the projection matrix

8318:    Output Parameters:
8319: .  C - the product matrix

8321:    Notes:
8322:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8323:    the user using MatDeatroy().

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

8328:    Level: intermediate

8330: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8331: @*/
8332: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8333: {

8339:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8340:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8343:   MatCheckPreallocated(P,2);
8344:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8345:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8348:   MatCheckPreallocated(C,3);
8349:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8350:   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);
8351:   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);
8352:   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);
8353:   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);
8354:   MatCheckPreallocated(A,1);

8356:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8357:   (*C->ops->ptapnumeric)(A,P,C);
8358:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8359:   return(0);
8360: }

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

8367:    Neighbor-wise Collective on Mat

8369:    Input Parameters:
8370: +  A - the matrix
8371: -  P - the projection matrix

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

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

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

8383:    Level: intermediate

8385: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8386: @*/
8387: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8388: {

8394:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8395:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8396:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8399:   MatCheckPreallocated(P,2);
8400:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8401:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8404:   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);
8405:   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);
8406:   MatCheckPreallocated(A,1);
8407:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8408:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8409:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

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

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

8420:    Neighbor-wise Collective on Mat

8422:    Input Parameters:
8423: +  A - the matrix
8424: .  R - the projection matrix
8425: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8426: -  fill - expected fill as ratio of nnz(C)/nnz(A)

8428:    Output Parameters:
8429: .  C - the product matrix

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

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

8437:    Level: intermediate

8439: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8440: @*/
8441: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8442: {

8448:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8449:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8452:   MatCheckPreallocated(R,2);
8453:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8454:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8456:   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);
8457:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8458:   MatCheckPreallocated(A,1);

8460:   if (!A->ops->rart) {
8461:     MatType mattype;
8462:     MatGetType(A,&mattype);
8463:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8464:   }
8465:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
8466:   (*A->ops->rart)(A,R,scall,fill,C);
8467:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
8468:   return(0);
8469: }

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

8476:    Neighbor-wise Collective on Mat

8478:    Input Parameters:
8479: +  A - the matrix
8480: -  R - the projection matrix

8482:    Output Parameters:
8483: .  C - the product matrix

8485:    Notes:
8486:    C must have been created by calling MatRARtSymbolic and must be destroyed by
8487:    the user using MatDeatroy().

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

8492:    Level: intermediate

8494: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8495: @*/
8496: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8497: {

8503:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8504:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8507:   MatCheckPreallocated(R,2);
8508:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8509:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8512:   MatCheckPreallocated(C,3);
8513:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8514:   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);
8515:   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);
8516:   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);
8517:   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);
8518:   MatCheckPreallocated(A,1);

8520:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8521:   (*A->ops->rartnumeric)(A,R,C);
8522:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8523:   return(0);
8524: }

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

8531:    Neighbor-wise Collective on Mat

8533:    Input Parameters:
8534: +  A - the matrix
8535: -  R - the projection matrix

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

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

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

8547:    Level: intermediate

8549: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8550: @*/
8551: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8552: {

8558:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8559:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8560:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8563:   MatCheckPreallocated(R,2);
8564:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8565:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8568:   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);
8569:   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);
8570:   MatCheckPreallocated(A,1);
8571:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8572:   (*A->ops->rartsymbolic)(A,R,fill,C);
8573:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

8575:   MatSetBlockSize(*C,A->rmap->bs);
8576:   return(0);
8577: }

8581: /*@
8582:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

8584:    Neighbor-wise Collective on Mat

8586:    Input Parameters:
8587: +  A - the left matrix
8588: .  B - the right matrix
8589: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8590: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8591:           if the result is a dense matrix this is irrelevent

8593:    Output Parameters:
8594: .  C - the product matrix

8596:    Notes:
8597:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

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

8604:    If you have many matrices with the same non-zero structure to multiply, you
8605:    should either
8606: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8607: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

8609:    Level: intermediate

8611: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8612: @*/
8613: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8614: {
8616:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8617:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8618:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

8623:   MatCheckPreallocated(A,1);
8624:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8625:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8628:   MatCheckPreallocated(B,2);
8629:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8630:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8632:   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);
8633:   if (scall == MAT_REUSE_MATRIX) {
8636:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8637:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8638:     (*(*C)->ops->matmultnumeric)(A,B,*C);
8639:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8640:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8641:     return(0);
8642:   }
8643:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8644:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

8646:   fA = A->ops->matmult;
8647:   fB = B->ops->matmult;
8648:   if (fB == fA) {
8649:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8650:     mult = fB;
8651:   } else {
8652:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8653:     char multname[256];
8654:     PetscStrcpy(multname,"MatMatMult_");
8655:     PetscStrcat(multname,((PetscObject)A)->type_name);
8656:     PetscStrcat(multname,"_");
8657:     PetscStrcat(multname,((PetscObject)B)->type_name);
8658:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8659:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
8660:     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);
8661:   }
8662:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8663:   (*mult)(A,B,scall,fill,C);
8664:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8665:   return(0);
8666: }

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

8674:    Neighbor-wise Collective on Mat

8676:    Input Parameters:
8677: +  A - the left matrix
8678: .  B - the right matrix
8679: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8680:       if C is a dense matrix this is irrelevent

8682:    Output Parameters:
8683: .  C - the product matrix

8685:    Notes:
8686:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

8691:    This routine is currently implemented for
8692:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8693:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8694:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8696:    Level: intermediate

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

8701: .seealso: MatMatMult(), MatMatMultNumeric()
8702: @*/
8703: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8704: {
8706:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
8707:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
8708:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

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

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

8723:   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);
8724:   if (fill == PETSC_DEFAULT) fill = 2.0;
8725:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8726:   MatCheckPreallocated(A,1);

8728:   Asymbolic = A->ops->matmultsymbolic;
8729:   Bsymbolic = B->ops->matmultsymbolic;
8730:   if (Asymbolic == Bsymbolic) {
8731:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8732:     symbolic = Bsymbolic;
8733:   } else { /* dispatch based on the type of A and B */
8734:     char symbolicname[256];
8735:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8736:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8737:     PetscStrcat(symbolicname,"_");
8738:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8739:     PetscStrcat(symbolicname,"_C");
8740:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
8741:     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);
8742:   }
8743:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8744:   (*symbolic)(A,B,fill,C);
8745:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8746:   return(0);
8747: }

8751: /*@
8752:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8753:    Call this routine after first calling MatMatMultSymbolic().

8755:    Neighbor-wise Collective on Mat

8757:    Input Parameters:
8758: +  A - the left matrix
8759: -  B - the right matrix

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

8764:    Notes:
8765:    C must have been created with MatMatMultSymbolic().

8767:    This routine is currently implemented for
8768:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8769:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8770:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8772:    Level: intermediate

8774: .seealso: MatMatMult(), MatMatMultSymbolic()
8775: @*/
8776: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8777: {

8781:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
8782:   return(0);
8783: }

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

8790:    Neighbor-wise Collective on Mat

8792:    Input Parameters:
8793: +  A - the left matrix
8794: .  B - the right matrix
8795: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8796: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8798:    Output Parameters:
8799: .  C - the product matrix

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

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

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

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

8811:    Level: intermediate

8813: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8814: @*/
8815: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8816: {
8818:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8819:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

8824:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8825:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8828:   MatCheckPreallocated(B,2);
8829:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8830:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8832:   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);
8833:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8834:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8835:   MatCheckPreallocated(A,1);

8837:   fA = A->ops->mattransposemult;
8838:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8839:   fB = B->ops->mattransposemult;
8840:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8841:   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);

8843:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
8844:   if (scall == MAT_INITIAL_MATRIX) {
8845:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8846:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8847:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8848:   }
8849:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8850:   (*A->ops->mattransposemultnumeric)(A,B,*C);
8851:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8852:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
8853:   return(0);
8854: }

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

8861:    Neighbor-wise Collective on Mat

8863:    Input Parameters:
8864: +  A - the left matrix
8865: .  B - the right matrix
8866: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8867: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8869:    Output Parameters:
8870: .  C - the product matrix

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

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

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

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

8883:    Level: intermediate

8885: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8886: @*/
8887: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8888: {
8890:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8891:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8892:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

8897:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8898:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8901:   MatCheckPreallocated(B,2);
8902:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8903:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8905:   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);
8906:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8907:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8908:   MatCheckPreallocated(A,1);

8910:   fA = A->ops->transposematmult;
8911:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8912:   fB = B->ops->transposematmult;
8913:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8914:   if (fB==fA) {
8915:     transposematmult = fA;
8916:   }
8917:   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);
8918:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8919:   (*transposematmult)(A,B,scall,fill,C);
8920:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8921:   return(0);
8922: }

8926: /*@
8927:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

8929:    Neighbor-wise Collective on Mat

8931:    Input Parameters:
8932: +  A - the left matrix
8933: .  B - the middle matrix
8934: .  C - the right matrix
8935: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8936: -  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
8937:           if the result is a dense matrix this is irrelevent

8939:    Output Parameters:
8940: .  D - the product matrix

8942:    Notes:
8943:    Unless scall is MAT_REUSE_MATRIX D will be created.

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

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

8950:    If you have many matrices with the same non-zero structure to multiply, you
8951:    should either
8952: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8953: $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed

8955:    Level: intermediate

8957: .seealso: MatMatMult, MatPtAP()
8958: @*/
8959: PetscErrorCode  MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
8960: {
8962:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8963:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8964:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8965:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

8970:   MatCheckPreallocated(A,1);
8971:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8972:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8975:   MatCheckPreallocated(B,2);
8976:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8977:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8980:   MatCheckPreallocated(C,3);
8981:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8982:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8983:   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);
8984:   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);
8985:   if (scall == MAT_REUSE_MATRIX) {
8988:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
8989:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
8990:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
8991:     return(0);
8992:   }
8993:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8994:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

8996:   fA = A->ops->matmatmult;
8997:   fB = B->ops->matmatmult;
8998:   fC = C->ops->matmatmult;
8999:   if (fA == fB && fA == fC) {
9000:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9001:     mult = fA;
9002:   } else {
9003:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9004:     char multname[256];
9005:     PetscStrcpy(multname,"MatMatMatMult_");
9006:     PetscStrcat(multname,((PetscObject)A)->type_name);
9007:     PetscStrcat(multname,"_");
9008:     PetscStrcat(multname,((PetscObject)B)->type_name);
9009:     PetscStrcat(multname,"_");
9010:     PetscStrcat(multname,((PetscObject)C)->type_name);
9011:     PetscStrcat(multname,"_C");
9012:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9013:     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);
9014:   }
9015:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9016:   (*mult)(A,B,C,scall,fill,D);
9017:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9018:   return(0);
9019: }

9023: /*@C
9024:    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

9026:    Collective on Mat

9028:    Input Parameters:
9029: +  mat - the matrix
9030: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9031: .  subcomm - MPI communicator split from the communicator where mat resides in
9032: .  mlocal_red - number of local rows of the redundant matrix
9033: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9035:    Output Parameter:
9036: .  matredundant - redundant matrix

9038:    Notes:
9039:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9040:    original matrix has not changed from that last call to MatGetRedundantMatrix().

9042:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9043:    calling it.

9045:    Only MPIAIJ matrix is supported.

9047:    Level: advanced

9049:    Concepts: subcommunicator
9050:    Concepts: duplicate matrix

9052: .seealso: MatDestroy()
9053: @*/
9054: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
9055: {

9060:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9063:   }
9064:   if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9065:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9066:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9067:   MatCheckPreallocated(mat,1);

9069:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
9070:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
9071:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
9072:   return(0);
9073: }

9077: /*@C
9078:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9079:    a given 'mat' object. Each submatrix can span multiple procs.

9081:    Collective on Mat

9083:    Input Parameters:
9084: +  mat - the matrix
9085: .  subcomm - the subcommunicator obtained by com_split(comm)
9086: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9088:    Output Parameter:
9089: .  subMat - 'parallel submatrices each spans a given subcomm

9091:   Notes:
9092:   The submatrix partition across processors is dictated by 'subComm' a
9093:   communicator obtained by com_split(comm). The comm_split
9094:   is not restriced to be grouped with consecutive original ranks.

9096:   Due the comm_split() usage, the parallel layout of the submatrices
9097:   map directly to the layout of the original matrix [wrt the local
9098:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9099:   into the 'DiagonalMat' of the subMat, hence it is used directly from
9100:   the subMat. However the offDiagMat looses some columns - and this is
9101:   reconstructed with MatSetValues()

9103:   Level: advanced

9105:   Concepts: subcommunicator
9106:   Concepts: submatrices

9108: .seealso: MatGetSubMatrices()
9109: @*/
9110: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9111: {
9113:   PetscMPIInt    commsize,subCommSize;

9116:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9117:   MPI_Comm_size(subComm,&subCommSize);
9118:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

9120:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9121:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9122:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9123:   return(0);
9124: }

9128: /*@
9129:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

9131:    Not Collective

9133:    Input Arguments:
9134:    mat - matrix to extract local submatrix from
9135:    isrow - local row indices for submatrix
9136:    iscol - local column indices for submatrix

9138:    Output Arguments:
9139:    submat - the submatrix

9141:    Level: intermediate

9143:    Notes:
9144:    The submat should be returned with MatRestoreLocalSubMatrix().

9146:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9147:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

9149:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9150:    MatSetValuesBlockedLocal() will also be implemented.

9152: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9153: @*/
9154: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9155: {


9165:   if (mat->ops->getlocalsubmatrix) {
9166:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9167:   } else {
9168:     MatCreateLocalRef(mat,isrow,iscol,submat);
9169:   }
9170:   return(0);
9171: }

9175: /*@
9176:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

9178:    Not Collective

9180:    Input Arguments:
9181:    mat - matrix to extract local submatrix from
9182:    isrow - local row indices for submatrix
9183:    iscol - local column indices for submatrix
9184:    submat - the submatrix

9186:    Level: intermediate

9188: .seealso: MatGetLocalSubMatrix()
9189: @*/
9190: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9191: {

9200:   if (*submat) {
9202:   }

9204:   if (mat->ops->restorelocalsubmatrix) {
9205:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9206:   } else {
9207:     MatDestroy(submat);
9208:   }
9209:   *submat = NULL;
9210:   return(0);
9211: }

9213: /* --------------------------------------------------------*/
9216: /*@
9217:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

9219:    Collective on Mat

9221:    Input Parameter:
9222: .  mat - the matrix

9224:    Output Parameter:
9225: .  is - if any rows have zero diagonals this contains the list of them

9227:    Level: developer

9229:    Concepts: matrix-vector product

9231: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9232: @*/
9233: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9234: {

9240:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9241:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9243:   if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9244:   (*mat->ops->findzerodiagonals)(mat,is);
9245:   return(0);
9246: }

9250: /*@C
9251:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

9253:   Collective on Mat

9255:   Input Parameters:
9256: . mat - the matrix

9258:   Output Parameters:
9259: . values - the block inverses in column major order (FORTRAN-like)

9261:    Note:
9262:    This routine is not available from Fortran.

9264:   Level: advanced
9265: @*/
9266: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9267: {

9272:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9273:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9274:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9275:   (*mat->ops->invertblockdiagonal)(mat,values);
9276:   return(0);
9277: }

9281: /*@C
9282:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9283:     via MatTransposeColoringCreate().

9285:     Collective on MatTransposeColoring

9287:     Input Parameter:
9288: .   c - coloring context

9290:     Level: intermediate

9292: .seealso: MatTransposeColoringCreate()
9293: @*/
9294: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9295: {
9296:   PetscErrorCode       ierr;
9297:   MatTransposeColoring matcolor=*c;

9300:   if (!matcolor) return(0);
9301:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

9303:   PetscFree(matcolor->ncolumns);
9304:   PetscFree(matcolor->nrows);
9305:   PetscFree(matcolor->colorforrow);
9306:   PetscFree2(matcolor->rows,matcolor->columnsforspidx);
9307:   PetscFree(matcolor->colorforcol);
9308:   PetscFree(matcolor->columns);
9309:   PetscHeaderDestroy(c);
9310:   return(0);
9311: }

9315: /*@C
9316:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9317:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9318:     MatTransposeColoring to sparse B.

9320:     Collective on MatTransposeColoring

9322:     Input Parameters:
9323: +   B - sparse matrix B
9324: .   Btdense - symbolic dense matrix B^T
9325: -   coloring - coloring context created with MatTransposeColoringCreate()

9327:     Output Parameter:
9328: .   Btdense - dense matrix B^T

9330:     Options Database Keys:
9331: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9332: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9333: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

9335:     Level: intermediate

9337: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

9339: .keywords: coloring
9340: @*/
9341: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9342: {


9350:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9351:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9352:   return(0);
9353: }

9357: /*@C
9358:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9359:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9360:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9361:     Csp from Cden.

9363:     Collective on MatTransposeColoring

9365:     Input Parameters:
9366: +   coloring - coloring context created with MatTransposeColoringCreate()
9367: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

9369:     Output Parameter:
9370: .   Csp - sparse matrix

9372:     Options Database Keys:
9373: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9374: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9375: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

9377:     Level: intermediate

9379: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

9381: .keywords: coloring
9382: @*/
9383: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9384: {


9392:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9393:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9394:   return(0);
9395: }

9399: /*@C
9400:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

9402:    Collective on Mat

9404:    Input Parameters:
9405: +  mat - the matrix product C
9406: -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()

9408:     Output Parameter:
9409: .   color - the new coloring context

9411:     Level: intermediate

9413: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9414:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9415: @*/
9416: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9417: {
9418:   MatTransposeColoring c;
9419:   MPI_Comm             comm;
9420:   PetscErrorCode       ierr;

9423:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9424:   PetscObjectGetComm((PetscObject)mat,&comm);
9425:   PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);

9427:   c->ctype = iscoloring->ctype;
9428:   if (mat->ops->transposecoloringcreate) {
9429:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9430:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

9432:   *color = c;
9433:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9434:   return(0);
9435: }