Actual source code: matrix.c

petsc-3.4.5 2014-06-29
  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: {

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

5722:   if (mat->ops->zerorowslocal) {
5723:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5724:   } else {
5725:     IS             is, newis;
5726:     const PetscInt *newRows;

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

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

5752:    Collective on Mat

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

5761:    Notes:
5762:    Before calling MatZeroRowsLocalIS(), the user must first set the
5763:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5765:    For the AIJ matrix formats this removes the old nonzero structure,
5766:    but does not release memory.  For the dense and block diagonal
5767:    formats this does not alter the nonzero structure.

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

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

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

5780:    Level: intermediate

5782:    Concepts: matrices^zeroing

5784: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5785: @*/
5786: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5787: {
5789:   PetscInt       numRows;
5790:   const PetscInt *rows;

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

5800:   ISGetLocalSize(is,&numRows);
5801:   ISGetIndices(is,&rows);
5802:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5803:   ISRestoreIndices(is,&rows);
5804:   return(0);
5805: }

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

5813:    Collective on Mat

5815:    Input Parameters:
5816: +  mat - the matrix
5817: .  numRows - the number of rows to remove
5818: .  rows - the global row indices
5819: .  diag - value put in all diagonals of eliminated rows
5820: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5821: -  b - optional vector of right hand side, that will be adjusted by provided solution

5823:    Notes:
5824:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5825:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5831:    Level: intermediate

5833:    Concepts: matrices^zeroing

5835: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5836: @*/
5837: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5838: {
5840:   IS             is, newis;
5841:   const PetscInt *newRows;

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

5851:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5852:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5853:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5854:   ISGetIndices(newis,&newRows);
5855:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5856:   ISRestoreIndices(newis,&newRows);
5857:   ISDestroy(&newis);
5858:   ISDestroy(&is);
5859:   PetscObjectStateIncrease((PetscObject)mat);
5860: #if defined(PETSC_HAVE_CUSP)
5861:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5862:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5863:   }
5864: #endif
5865:   return(0);
5866: }

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

5874:    Collective on Mat

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

5883:    Notes:
5884:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5885:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5891:    Level: intermediate

5893:    Concepts: matrices^zeroing

5895: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5896: @*/
5897: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5898: {
5900:   PetscInt       numRows;
5901:   const PetscInt *rows;

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

5911:   ISGetLocalSize(is,&numRows);
5912:   ISGetIndices(is,&rows);
5913:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5914:   ISRestoreIndices(is,&rows);
5915:   return(0);
5916: }

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

5923:    Not Collective

5925:    Input Parameter:
5926: .  mat - the matrix

5928:    Output Parameters:
5929: +  m - the number of global rows
5930: -  n - the number of global columns

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

5934:    Level: beginner

5936:    Concepts: matrices^size

5938: .seealso: MatGetLocalSize()
5939: @*/
5940: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
5941: {
5944:   if (m) *m = mat->rmap->N;
5945:   if (n) *n = mat->cmap->N;
5946:   return(0);
5947: }

5951: /*@
5952:    MatGetLocalSize - Returns the number of rows and columns in a matrix
5953:    stored locally.  This information may be implementation dependent, so
5954:    use with care.

5956:    Not Collective

5958:    Input Parameters:
5959: .  mat - the matrix

5961:    Output Parameters:
5962: +  m - the number of local rows
5963: -  n - the number of local columns

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

5967:    Level: beginner

5969:    Concepts: matrices^local size

5971: .seealso: MatGetSize()
5972: @*/
5973: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
5974: {
5979:   if (m) *m = mat->rmap->n;
5980:   if (n) *n = mat->cmap->n;
5981:   return(0);
5982: }

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

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

5992:    Input Parameters:
5993: .  mat - the matrix

5995:    Output Parameters:
5996: +  m - the global index of the first local column
5997: -  n - one more than the global index of the last local column

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

6001:    Level: developer

6003:    Concepts: matrices^column ownership

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

6007: @*/
6008: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6009: {
6015:   MatCheckPreallocated(mat,1);
6016:   if (m) *m = mat->cmap->rstart;
6017:   if (n) *n = mat->cmap->rend;
6018:   return(0);
6019: }

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

6029:    Not Collective

6031:    Input Parameters:
6032: .  mat - the matrix

6034:    Output Parameters:
6035: +  m - the global index of the first local row
6036: -  n - one more than the global index of the last local row

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

6043:    Level: beginner

6045:    Concepts: matrices^row ownership

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

6049: @*/
6050: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6051: {
6057:   MatCheckPreallocated(mat,1);
6058:   if (m) *m = mat->rmap->rstart;
6059:   if (n) *n = mat->rmap->rend;
6060:   return(0);
6061: }

6065: /*@C
6066:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6067:    each process

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

6071:    Input Parameters:
6072: .  mat - the matrix

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

6077:    Level: beginner

6079:    Concepts: matrices^row ownership

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

6083: @*/
6084: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6085: {

6091:   MatCheckPreallocated(mat,1);
6092:   PetscLayoutGetRanges(mat->rmap,ranges);
6093:   return(0);
6094: }

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

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

6104:    Input Parameters:
6105: .  mat - the matrix

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

6110:    Level: beginner

6112:    Concepts: matrices^column ownership

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

6116: @*/
6117: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6118: {

6124:   MatCheckPreallocated(mat,1);
6125:   PetscLayoutGetRanges(mat->cmap,ranges);
6126:   return(0);
6127: }

6131: /*@C
6132:    MatGetOwnershipIS - Get row and column ownership as index sets

6134:    Not Collective

6136:    Input Arguments:
6137: .  A - matrix of type Elemental

6139:    Output Arguments:
6140: +  rows - rows in which this process owns elements
6141: .  cols - columns in which this process owns elements

6143:    Level: intermediate

6145: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6146: @*/
6147: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6148: {
6149:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6152:   MatCheckPreallocated(A,1);
6153:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6154:   if (f) {
6155:     (*f)(A,rows,cols);
6156:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6157:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6158:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6159:   }
6160:   return(0);
6161: }

6165: /*@C
6166:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6167:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6168:    to complete the factorization.

6170:    Collective on Mat

6172:    Input Parameters:
6173: +  mat - the matrix
6174: .  row - row permutation
6175: .  column - column permutation
6176: -  info - structure containing
6177: $      levels - number of levels of fill.
6178: $      expected fill - as ratio of original fill.
6179: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6180:                 missing diagonal entries)

6182:    Output Parameters:
6183: .  fact - new matrix that has been symbolically factored

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

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

6193:    Level: developer

6195:   Concepts: matrices^symbolic LU factorization
6196:   Concepts: matrices^factorization
6197:   Concepts: LU^symbolic factorization

6199: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6200:           MatGetOrdering(), MatFactorInfo

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

6205: @*/
6206: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6207: {

6217:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6218:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6219:   if (!(fact)->ops->ilufactorsymbolic) {
6220:     const MatSolverPackage spackage;
6221:     MatFactorGetSolverPackage(fact,&spackage);
6222:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6223:   }
6224:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6225:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6226:   MatCheckPreallocated(mat,2);

6228:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6229:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6230:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6231:   return(0);
6232: }

6236: /*@C
6237:    MatICCFactorSymbolic - Performs symbolic incomplete
6238:    Cholesky factorization for a symmetric matrix.  Use
6239:    MatCholeskyFactorNumeric() to complete the factorization.

6241:    Collective on Mat

6243:    Input Parameters:
6244: +  mat - the matrix
6245: .  perm - row and column permutation
6246: -  info - structure containing
6247: $      levels - number of levels of fill.
6248: $      expected fill - as ratio of original fill.

6250:    Output Parameter:
6251: .  fact - the factored matrix

6253:    Notes:
6254:    Most users should employ the KSP interface for linear solvers
6255:    instead of working directly with matrix algebra routines such as this.
6256:    See, e.g., KSPCreate().

6258:    Level: developer

6260:   Concepts: matrices^symbolic incomplete Cholesky factorization
6261:   Concepts: matrices^factorization
6262:   Concepts: Cholsky^symbolic factorization

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

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

6269: @*/
6270: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6271: {

6280:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6281:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6282:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6283:   if (!(fact)->ops->iccfactorsymbolic) {
6284:     const MatSolverPackage spackage;
6285:     MatFactorGetSolverPackage(fact,&spackage);
6286:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6287:   }
6288:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6289:   MatCheckPreallocated(mat,2);

6291:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6292:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6293:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6294:   return(0);
6295: }

6299: /*@C
6300:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6301:    points to an array of valid matrices, they may be reused to store the new
6302:    submatrices.

6304:    Collective on Mat

6306:    Input Parameters:
6307: +  mat - the matrix
6308: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6309: .  irow, icol - index sets of rows and columns to extract (must be sorted)
6310: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6312:    Output Parameter:
6313: .  submat - the array of submatrices

6315:    Notes:
6316:    MatGetSubMatrices() can extract ONLY sequential submatrices
6317:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6318:    to extract a parallel submatrix.

6320:    Currently both row and column indices must be sorted to guarantee
6321:    correctness with all matrix types.

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

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

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

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

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

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

6345:    Level: advanced

6347:    Concepts: matrices^accessing submatrices
6348:    Concepts: submatrices

6350: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6351: @*/
6352: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6353: {
6355:   PetscInt       i;
6356:   PetscBool      eq;

6361:   if (n) {
6366:   }
6368:   if (n && scall == MAT_REUSE_MATRIX) {
6371:   }
6372:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6373:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6374:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6375:   MatCheckPreallocated(mat,1);

6377:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6378:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6379:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6380:   for (i=0; i<n; i++) {
6381:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6382:       ISEqual(irow[i],icol[i],&eq);
6383:       if (eq) {
6384:         if (mat->symmetric) {
6385:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6386:         } else if (mat->hermitian) {
6387:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6388:         } else if (mat->structurally_symmetric) {
6389:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6390:         }
6391:       }
6392:     }
6393:   }
6394:   return(0);
6395: }

6399: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6400: {
6402:   PetscInt       i;
6403:   PetscBool      eq;

6408:   if (n) {
6413:   }
6415:   if (n && scall == MAT_REUSE_MATRIX) {
6418:   }
6419:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6420:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6421:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6422:   MatCheckPreallocated(mat,1);

6424:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6425:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6426:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6427:   for (i=0; i<n; i++) {
6428:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6429:       ISEqual(irow[i],icol[i],&eq);
6430:       if (eq) {
6431:         if (mat->symmetric) {
6432:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6433:         } else if (mat->hermitian) {
6434:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6435:         } else if (mat->structurally_symmetric) {
6436:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6437:         }
6438:       }
6439:     }
6440:   }
6441:   return(0);
6442: }

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

6449:    Collective on Mat

6451:    Input Parameters:
6452: +  n - the number of local matrices
6453: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6454:                        sequence of MatGetSubMatrices())

6456:    Level: advanced

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

6461: .seealso: MatGetSubMatrices()
6462: @*/
6463: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6464: {
6466:   PetscInt       i;

6469:   if (!*mat) return(0);
6470:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6472:   for (i=0; i<n; i++) {
6473:     MatDestroy(&(*mat)[i]);
6474:   }
6475:   /* memory is allocated even if n = 0 */
6476:   PetscFree(*mat);
6477:   *mat = NULL;
6478:   return(0);
6479: }

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

6486:    Collective on Mat

6488:    Input Parameters:
6489: .  mat - the matrix

6491:    Output Parameter:
6492: .  matstruct - the sequential matrix with the nonzero structure of mat

6494:   Level: intermediate

6496: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6497: @*/
6498: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6499: {


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

6510:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6511:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6512:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6513:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6514:   return(0);
6515: }

6519: /*@C
6520:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6522:    Collective on Mat

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

6528:    Level: advanced

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

6532: .seealso: MatGetSeqNonzeroStructure()
6533: @*/
6534: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6535: {

6540:   MatDestroy(mat);
6541:   return(0);
6542: }

6546: /*@
6547:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6548:    replaces the index sets by larger ones that represent submatrices with
6549:    additional overlap.

6551:    Collective on Mat

6553:    Input Parameters:
6554: +  mat - the matrix
6555: .  n   - the number of index sets
6556: .  is  - the array of index sets (these index sets will changed during the call)
6557: -  ov  - the additional overlap requested

6559:    Level: developer

6561:    Concepts: overlap
6562:    Concepts: ASM^computing overlap

6564: .seealso: MatGetSubMatrices()
6565: @*/
6566: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6567: {

6573:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6574:   if (n) {
6577:   }
6578:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6579:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6580:   MatCheckPreallocated(mat,1);

6582:   if (!ov) return(0);
6583:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6584:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6585:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6586:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6587:   return(0);
6588: }

6592: /*@
6593:    MatGetBlockSize - Returns the matrix block size; useful especially for the
6594:    block row and block diagonal formats.

6596:    Not Collective

6598:    Input Parameter:
6599: .  mat - the matrix

6601:    Output Parameter:
6602: .  bs - block size

6604:    Notes:
6605:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

6607:    Level: intermediate

6609:    Concepts: matrices^block size

6611: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6612: @*/
6613: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6614: {
6619:   MatCheckPreallocated(mat,1);
6620:   *bs = mat->rmap->bs;
6621:   return(0);
6622: }

6626: /*@
6627:    MatGetBlockSizes - Returns the matrix block row and column sizes;
6628:    useful especially for the block row and block diagonal formats.

6630:    Not Collective

6632:    Input Parameter:
6633: .  mat - the matrix

6635:    Output Parameter:
6636: .  rbs - row block size
6637: .  cbs - coumn block size

6639:    Notes:
6640:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

6642:    Level: intermediate

6644:    Concepts: matrices^block size

6646: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6647: @*/
6648: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6649: {
6655:   MatCheckPreallocated(mat,1);
6656:   if (rbs) *rbs = mat->rmap->bs;
6657:   if (cbs) *cbs = mat->cmap->bs;
6658:   return(0);
6659: }

6663: /*@
6664:    MatSetBlockSize - Sets the matrix block size.

6666:    Logically Collective on Mat

6668:    Input Parameters:
6669: +  mat - the matrix
6670: -  bs - block size

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

6675:    Level: intermediate

6677:    Concepts: matrices^block size

6679: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6680: @*/
6681: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6682: {

6688:   PetscLayoutSetBlockSize(mat->rmap,bs);
6689:   PetscLayoutSetBlockSize(mat->cmap,bs);
6690:   return(0);
6691: }

6695: /*@
6696:    MatSetBlockSizes - Sets the matrix block row and column sizes.

6698:    Logically Collective on Mat

6700:    Input Parameters:
6701: +  mat - the matrix
6702: -  rbs - row block size
6703: -  cbs - column block size

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

6708:    Level: intermediate

6710:    Concepts: matrices^block size

6712: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6713: @*/
6714: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6715: {

6722:   PetscLayoutSetBlockSize(mat->rmap,rbs);
6723:   PetscLayoutSetBlockSize(mat->cmap,cbs);
6724:   return(0);
6725: }

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

6732:    Collective on Mat

6734:     Input Parameters:
6735: +   mat - the matrix
6736: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6737: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6738: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6739:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6740:                  always used.

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

6749:     Level: developer

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

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

6755:     Fortran Node

6757:            In Fortran use
6758: $           PetscInt ia(1), ja(1)
6759: $           PetscOffset iia, jja
6760: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6761: $
6762: $          or
6763: $
6764: $           PetscScalar, pointer :: xx_v(:)
6765: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)


6768:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

6770: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6771: @*/
6772: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6773: {

6783:   MatCheckPreallocated(mat,1);
6784:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6785:   else {
6786:     *done = PETSC_TRUE;
6787:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6788:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6789:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6790:   }
6791:   return(0);
6792: }

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

6799:     Collective on Mat

6801:     Input Parameters:
6802: +   mat - the matrix
6803: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6804: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6805:                 symmetrized
6806: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6807:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6808:                  always used.

6810:     Output Parameters:
6811: +   n - number of columns in the (possibly compressed) matrix
6812: .   ia - the column pointers
6813: .   ja - the row indices
6814: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6816:     Level: developer

6818: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6819: @*/
6820: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6821: {

6831:   MatCheckPreallocated(mat,1);
6832:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6833:   else {
6834:     *done = PETSC_TRUE;
6835:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6836:   }
6837:   return(0);
6838: }

6842: /*@C
6843:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6844:     MatGetRowIJ().

6846:     Collective on Mat

6848:     Input Parameters:
6849: +   mat - the matrix
6850: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6851: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6852:                 symmetrized
6853: -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6854:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6855:                  always used.

6857:     Output Parameters:
6858: +   n - size of (possibly compressed) matrix
6859: .   ia - the row pointers
6860: .   ja - the column indices
6861: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6863:     Level: developer

6865: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6866: @*/
6867: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6868: {

6877:   MatCheckPreallocated(mat,1);

6879:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6880:   else {
6881:     *done = PETSC_TRUE;
6882:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6883:     if (n)  *n = 0;
6884:     if (ia) *ia = NULL;
6885:     if (ja) *ja = NULL;
6886:   }
6887:   return(0);
6888: }

6892: /*@C
6893:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6894:     MatGetColumnIJ().

6896:     Collective on Mat

6898:     Input Parameters:
6899: +   mat - the matrix
6900: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6901: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6902:                 symmetrized
6903: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6904:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6905:                  always used.

6907:     Output Parameters:
6908: +   n - size of (possibly compressed) matrix
6909: .   ia - the column pointers
6910: .   ja - the row indices
6911: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6913:     Level: developer

6915: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6916: @*/
6917: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
6918: {

6927:   MatCheckPreallocated(mat,1);

6929:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6930:   else {
6931:     *done = PETSC_TRUE;
6932:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6933:     if (n)  *n = 0;
6934:     if (ia) *ia = NULL;
6935:     if (ja) *ja = NULL;
6936:   }
6937:   return(0);
6938: }

6942: /*@C
6943:     MatColoringPatch -Used inside matrix coloring routines that
6944:     use MatGetRowIJ() and/or MatGetColumnIJ().

6946:     Collective on Mat

6948:     Input Parameters:
6949: +   mat - the matrix
6950: .   ncolors - max color value
6951: .   n   - number of entries in colorarray
6952: -   colorarray - array indicating color for each column

6954:     Output Parameters:
6955: .   iscoloring - coloring generated using colorarray information

6957:     Level: developer

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

6961: @*/
6962: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6963: {

6971:   MatCheckPreallocated(mat,1);

6973:   if (!mat->ops->coloringpatch) {
6974:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);
6975:   } else {
6976:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6977:   }
6978:   return(0);
6979: }


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

6987:    Logically Collective on Mat

6989:    Input Parameter:
6990: .  mat - the factored matrix to be reset

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

6999:    Note that one can specify in-place ILU(0) factorization by calling
7000: .vb
7001:      PCType(pc,PCILU);
7002:      PCFactorSeUseInPlace(pc);
7003: .ve
7004:    or by using the options -pc_type ilu -pc_factor_in_place

7006:    In-place factorization ILU(0) can also be used as a local
7007:    solver for the blocks within the block Jacobi or additive Schwarz
7008:    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
7009:    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7010:    local solver options.

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

7016:    Level: developer

7018: .seealso: PCFactorSetUseInPlace()

7020:    Concepts: matrices^unfactored

7022: @*/
7023: PetscErrorCode  MatSetUnfactored(Mat mat)
7024: {

7030:   MatCheckPreallocated(mat,1);
7031:   mat->factortype = MAT_FACTOR_NONE;
7032:   if (!mat->ops->setunfactored) return(0);
7033:   (*mat->ops->setunfactored)(mat);
7034:   return(0);
7035: }

7037: /*MC
7038:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7040:     Synopsis:
7041:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7043:     Not collective

7045:     Input Parameter:
7046: .   x - matrix

7048:     Output Parameters:
7049: +   xx_v - the Fortran90 pointer to the array
7050: -   ierr - error code

7052:     Example of Usage:
7053: .vb
7054:       PetscScalar, pointer xx_v(:,:)
7055:       ....
7056:       call MatDenseGetArrayF90(x,xx_v,ierr)
7057:       a = xx_v(3)
7058:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7059: .ve

7061:     Level: advanced

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

7065:     Concepts: matrices^accessing array

7067: M*/

7069: /*MC
7070:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7071:     accessed with MatDenseGetArrayF90().

7073:     Synopsis:
7074:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7076:     Not collective

7078:     Input Parameters:
7079: +   x - matrix
7080: -   xx_v - the Fortran90 pointer to the array

7082:     Output Parameter:
7083: .   ierr - error code

7085:     Example of Usage:
7086: .vb
7087:        PetscScalar, pointer xx_v(:)
7088:        ....
7089:        call MatDenseGetArrayF90(x,xx_v,ierr)
7090:        a = xx_v(3)
7091:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7092: .ve

7094:     Level: advanced

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

7098: M*/


7101: /*MC
7102:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7104:     Synopsis:
7105:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7107:     Not collective

7109:     Input Parameter:
7110: .   x - matrix

7112:     Output Parameters:
7113: +   xx_v - the Fortran90 pointer to the array
7114: -   ierr - error code

7116:     Example of Usage:
7117: .vb
7118:       PetscScalar, pointer xx_v(:,:)
7119:       ....
7120:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7121:       a = xx_v(3)
7122:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7123: .ve

7125:     Level: advanced

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

7129:     Concepts: matrices^accessing array

7131: M*/

7133: /*MC
7134:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7135:     accessed with MatSeqAIJGetArrayF90().

7137:     Synopsis:
7138:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7140:     Not collective

7142:     Input Parameters:
7143: +   x - matrix
7144: -   xx_v - the Fortran90 pointer to the array

7146:     Output Parameter:
7147: .   ierr - error code

7149:     Example of Usage:
7150: .vb
7151:        PetscScalar, pointer xx_v(:)
7152:        ....
7153:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7154:        a = xx_v(3)
7155:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7156: .ve

7158:     Level: advanced

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

7162: M*/


7167: /*@
7168:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7169:                       as the original matrix.

7171:     Collective on Mat

7173:     Input Parameters:
7174: +   mat - the original matrix
7175: .   isrow - parallel IS containing the rows this processor should obtain
7176: .   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.
7177: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7179:     Output Parameter:
7180: .   newmat - the new submatrix, of the same type as the old

7182:     Level: advanced

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

7187:     The rows in isrow will be sorted into the same order as the original matrix on each process.

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

7195:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7196:     the input matrix.

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

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

7206: .vb
7207:             1  2  0  |  0  3  0  |  0  4
7208:     Proc0   0  5  6  |  7  0  0  |  8  0
7209:             9  0 10  | 11  0  0  | 12  0
7210:     -------------------------------------
7211:            13  0 14  | 15 16 17  |  0  0
7212:     Proc1   0 18  0  | 19 20 21  |  0  0
7213:             0  0  0  | 22 23  0  | 24  0
7214:     -------------------------------------
7215:     Proc2  25 26 27  |  0  0 28  | 29  0
7216:            30  0  0  | 31 32 33  |  0 34
7217: .ve

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

7221: .vb
7222:             2  0  |  0  3  0  |  0
7223:     Proc0   5  6  |  7  0  0  |  8
7224:     -------------------------------
7225:     Proc1  18  0  | 19 20 21  |  0
7226:     -------------------------------
7227:     Proc2  26 27  |  0  0 28  | 29
7228:             0  0  | 31 32 33  |  0
7229: .ve


7232:     Concepts: matrices^submatrices

7234: .seealso: MatGetSubMatrices()
7235: @*/
7236: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7237: {
7239:   PetscMPIInt    size;
7240:   Mat            *local;
7241:   IS             iscoltmp;

7250:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7251:   MatCheckPreallocated(mat,1);
7252:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7254:   if (!iscol) {
7255:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7256:   } else {
7257:     iscoltmp = iscol;
7258:   }

7260:   /* if original matrix is on just one processor then use submatrix generated */
7261:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7262:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7263:     if (!iscol) {ISDestroy(&iscoltmp);}
7264:     return(0);
7265:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7266:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7267:     *newmat = *local;
7268:     PetscFree(local);
7269:     if (!iscol) {ISDestroy(&iscoltmp);}
7270:     return(0);
7271:   } else if (!mat->ops->getsubmatrix) {
7272:     /* Create a new matrix type that implements the operation using the full matrix */
7273:     switch (cll) {
7274:     case MAT_INITIAL_MATRIX:
7275:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7276:       break;
7277:     case MAT_REUSE_MATRIX:
7278:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7279:       break;
7280:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7281:     }
7282:     if (!iscol) {ISDestroy(&iscoltmp);}
7283:     return(0);
7284:   }

7286:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7287:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7288:   if (!iscol) {ISDestroy(&iscoltmp);}
7289:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7290:   return(0);
7291: }

7295: /*@
7296:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7297:    used during the assembly process to store values that belong to
7298:    other processors.

7300:    Not Collective

7302:    Input Parameters:
7303: +  mat   - the matrix
7304: .  size  - the initial size of the stash.
7305: -  bsize - the initial size of the block-stash(if used).

7307:    Options Database Keys:
7308: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7309: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7311:    Level: intermediate

7313:    Notes:
7314:      The block-stash is used for values set with MatSetValuesBlocked() while
7315:      the stash is used for values set with MatSetValues()

7317:      Run with the option -info and look for output of the form
7318:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7319:      to determine the appropriate value, MM, to use for size and
7320:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7321:      to determine the value, BMM to use for bsize

7323:    Concepts: stash^setting matrix size
7324:    Concepts: matrices^stash

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

7328: @*/
7329: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7330: {

7336:   MatStashSetInitialSize_Private(&mat->stash,size);
7337:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7338:   return(0);
7339: }

7343: /*@
7344:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7345:      the matrix

7347:    Neighbor-wise Collective on Mat

7349:    Input Parameters:
7350: +  mat   - the matrix
7351: .  x,y - the vectors
7352: -  w - where the result is stored

7354:    Level: intermediate

7356:    Notes:
7357:     w may be the same vector as y.

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

7362:     Concepts: interpolation

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

7366: @*/
7367: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7368: {
7370:   PetscInt       M,N,Ny;

7378:   MatCheckPreallocated(A,1);
7379:   MatGetSize(A,&M,&N);
7380:   VecGetSize(y,&Ny);
7381:   if (M == Ny) {
7382:     MatMultAdd(A,x,y,w);
7383:   } else {
7384:     MatMultTransposeAdd(A,x,y,w);
7385:   }
7386:   return(0);
7387: }

7391: /*@
7392:    MatInterpolate - y = A*x or A'*x depending on the shape of
7393:      the matrix

7395:    Neighbor-wise Collective on Mat

7397:    Input Parameters:
7398: +  mat   - the matrix
7399: -  x,y - the vectors

7401:    Level: intermediate

7403:    Notes:
7404:     This allows one to use either the restriction or interpolation (its transpose)
7405:     matrix to do the interpolation

7407:    Concepts: matrices^interpolation

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

7411: @*/
7412: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7413: {
7415:   PetscInt       M,N,Ny;

7422:   MatCheckPreallocated(A,1);
7423:   MatGetSize(A,&M,&N);
7424:   VecGetSize(y,&Ny);
7425:   if (M == Ny) {
7426:     MatMult(A,x,y);
7427:   } else {
7428:     MatMultTranspose(A,x,y);
7429:   }
7430:   return(0);
7431: }

7435: /*@
7436:    MatRestrict - y = A*x or A'*x

7438:    Neighbor-wise Collective on Mat

7440:    Input Parameters:
7441: +  mat   - the matrix
7442: -  x,y - the vectors

7444:    Level: intermediate

7446:    Notes:
7447:     This allows one to use either the restriction or interpolation (its transpose)
7448:     matrix to do the restriction

7450:    Concepts: matrices^restriction

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

7454: @*/
7455: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7456: {
7458:   PetscInt       M,N,Ny;

7465:   MatCheckPreallocated(A,1);

7467:   MatGetSize(A,&M,&N);
7468:   VecGetSize(y,&Ny);
7469:   if (M == Ny) {
7470:     MatMult(A,x,y);
7471:   } else {
7472:     MatMultTranspose(A,x,y);
7473:   }
7474:   return(0);
7475: }

7479: /*@
7480:    MatGetNullSpace - retrieves the null space to a matrix.

7482:    Logically Collective on Mat and MatNullSpace

7484:    Input Parameters:
7485: +  mat - the matrix
7486: -  nullsp - the null space object

7488:    Level: developer

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

7493:    Concepts: null space^attaching to matrix

7495: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7496: @*/
7497: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7498: {
7503:   *nullsp = mat->nullsp;
7504:   return(0);
7505: }

7509: /*@
7510:    MatSetNullSpace - attaches a null space to a matrix.
7511:         This null space will be removed from the resulting vector whenever
7512:         MatMult() is called

7514:    Logically Collective on Mat and MatNullSpace

7516:    Input Parameters:
7517: +  mat - the matrix
7518: -  nullsp - the null space object

7520:    Level: advanced

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

7525:    Concepts: null space^attaching to matrix

7527: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7528: @*/
7529: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7530: {

7537:   MatCheckPreallocated(mat,1);
7538:   PetscObjectReference((PetscObject)nullsp);
7539:   MatNullSpaceDestroy(&mat->nullsp);

7541:   mat->nullsp = nullsp;
7542:   return(0);
7543: }

7547: /*@
7548:    MatSetNearNullSpace - attaches a null space to a matrix.
7549:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

7551:    Logically Collective on Mat and MatNullSpace

7553:    Input Parameters:
7554: +  mat - the matrix
7555: -  nullsp - the null space object

7557:    Level: advanced

7559:    Notes:
7560:       Overwrites any previous near null space that may have been attached

7562:    Concepts: null space^attaching to matrix

7564: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7565: @*/
7566: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7567: {

7574:   MatCheckPreallocated(mat,1);
7575:   PetscObjectReference((PetscObject)nullsp);
7576:   MatNullSpaceDestroy(&mat->nearnullsp);

7578:   mat->nearnullsp = nullsp;
7579:   return(0);
7580: }

7584: /*@
7585:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

7587:    Not Collective

7589:    Input Parameters:
7590: .  mat - the matrix

7592:    Output Parameters:
7593: .  nullsp - the null space object, NULL if not set

7595:    Level: developer

7597:    Concepts: null space^attaching to matrix

7599: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7600: @*/
7601: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7602: {
7607:   MatCheckPreallocated(mat,1);
7608:   *nullsp = mat->nearnullsp;
7609:   return(0);
7610: }

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

7617:    Collective on Mat

7619:    Input Parameters:
7620: +  mat - the matrix
7621: .  row - row/column permutation
7622: .  fill - expected fill factor >= 1.0
7623: -  level - level of fill, for ICC(k)

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

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

7633:    Level: developer

7635:    Concepts: matrices^incomplete Cholesky factorization
7636:    Concepts: Cholesky factorization

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

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

7643: @*/
7644: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7645: {

7653:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
7654:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7655:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7656:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7657:   MatCheckPreallocated(mat,1);
7658:   (*mat->ops->iccfactor)(mat,row,info);
7659:   PetscObjectStateIncrease((PetscObject)mat);
7660:   return(0);
7661: }

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

7668:    Not Collective

7670:    Input Parameters:
7671: +  mat - the matrix
7672: .  nl - leading dimension of v
7673: -  v - the values compute with ADIFOR

7675:    Level: developer

7677:    Notes:
7678:      Must call MatSetColoring() before using this routine. Also this matrix must already
7679:      have its nonzero pattern determined.

7681: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7682:           MatSetValues(), MatSetColoring()
7683: @*/
7684: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7685: {


7693:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7694:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7695:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7696:   (*mat->ops->setvaluesadifor)(mat,nl,v);
7697:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7698:   PetscObjectStateIncrease((PetscObject)mat);
7699:   return(0);
7700: }

7704: /*@
7705:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7706:          ghosted ones.

7708:    Not Collective

7710:    Input Parameters:
7711: +  mat - the matrix
7712: -  diag = the diagonal values, including ghost ones

7714:    Level: developer

7716:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

7718: .seealso: MatDiagonalScale()
7719: @*/
7720: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7721: {
7723:   PetscMPIInt    size;


7730:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7731:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7732:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7733:   if (size == 1) {
7734:     PetscInt n,m;
7735:     VecGetSize(diag,&n);
7736:     MatGetSize(mat,0,&m);
7737:     if (m == n) {
7738:       MatDiagonalScale(mat,0,diag);
7739:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7740:   } else {
7741:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7742:   }
7743:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7744:   PetscObjectStateIncrease((PetscObject)mat);
7745:   return(0);
7746: }

7750: /*@
7751:    MatGetInertia - Gets the inertia from a factored matrix

7753:    Collective on Mat

7755:    Input Parameter:
7756: .  mat - the matrix

7758:    Output Parameters:
7759: +   nneg - number of negative eigenvalues
7760: .   nzero - number of zero eigenvalues
7761: -   npos - number of positive eigenvalues

7763:    Level: advanced

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


7768: @*/
7769: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7770: {

7776:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7777:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7778:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7779:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7780:   return(0);
7781: }

7783: /* ----------------------------------------------------------------*/
7786: /*@C
7787:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

7789:    Neighbor-wise Collective on Mat and Vecs

7791:    Input Parameters:
7792: +  mat - the factored matrix
7793: -  b - the right-hand-side vectors

7795:    Output Parameter:
7796: .  x - the result vectors

7798:    Notes:
7799:    The vectors b and x cannot be the same.  I.e., one cannot
7800:    call MatSolves(A,x,x).

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

7807:    Level: developer

7809:    Concepts: matrices^triangular solves

7811: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7812: @*/
7813: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7814: {

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

7824:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7825:   MatCheckPreallocated(mat,1);
7826:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7827:   (*mat->ops->solves)(mat,b,x);
7828:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7829:   return(0);
7830: }

7834: /*@
7835:    MatIsSymmetric - Test whether a matrix is symmetric

7837:    Collective on Mat

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

7843:    Output Parameters:
7844: .  flg - the result

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

7848:    Level: intermediate

7850:    Concepts: matrix^symmetry

7852: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7853: @*/
7854: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7855: {


7862:   if (!A->symmetric_set) {
7863:     if (!A->ops->issymmetric) {
7864:       MatType mattype;
7865:       MatGetType(A,&mattype);
7866:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7867:     }
7868:     (*A->ops->issymmetric)(A,tol,flg);
7869:     if (!tol) {
7870:       A->symmetric_set = PETSC_TRUE;
7871:       A->symmetric     = *flg;
7872:       if (A->symmetric) {
7873:         A->structurally_symmetric_set = PETSC_TRUE;
7874:         A->structurally_symmetric     = PETSC_TRUE;
7875:       }
7876:     }
7877:   } else if (A->symmetric) {
7878:     *flg = PETSC_TRUE;
7879:   } else if (!tol) {
7880:     *flg = PETSC_FALSE;
7881:   } else {
7882:     if (!A->ops->issymmetric) {
7883:       MatType mattype;
7884:       MatGetType(A,&mattype);
7885:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7886:     }
7887:     (*A->ops->issymmetric)(A,tol,flg);
7888:   }
7889:   return(0);
7890: }

7894: /*@
7895:    MatIsHermitian - Test whether a matrix is Hermitian

7897:    Collective on Mat

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

7903:    Output Parameters:
7904: .  flg - the result

7906:    Level: intermediate

7908:    Concepts: matrix^symmetry

7910: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7911:           MatIsSymmetricKnown(), MatIsSymmetric()
7912: @*/
7913: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7914: {


7921:   if (!A->hermitian_set) {
7922:     if (!A->ops->ishermitian) {
7923:       MatType mattype;
7924:       MatGetType(A,&mattype);
7925:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7926:     }
7927:     (*A->ops->ishermitian)(A,tol,flg);
7928:     if (!tol) {
7929:       A->hermitian_set = PETSC_TRUE;
7930:       A->hermitian     = *flg;
7931:       if (A->hermitian) {
7932:         A->structurally_symmetric_set = PETSC_TRUE;
7933:         A->structurally_symmetric     = PETSC_TRUE;
7934:       }
7935:     }
7936:   } else if (A->hermitian) {
7937:     *flg = PETSC_TRUE;
7938:   } else if (!tol) {
7939:     *flg = PETSC_FALSE;
7940:   } else {
7941:     if (!A->ops->ishermitian) {
7942:       MatType mattype;
7943:       MatGetType(A,&mattype);
7944:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7945:     }
7946:     (*A->ops->ishermitian)(A,tol,flg);
7947:   }
7948:   return(0);
7949: }

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

7956:    Not Collective

7958:    Input Parameter:
7959: .  A - the matrix to check

7961:    Output Parameters:
7962: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7963: -  flg - the result

7965:    Level: advanced

7967:    Concepts: matrix^symmetry

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

7972: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7973: @*/
7974: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7975: {
7980:   if (A->symmetric_set) {
7981:     *set = PETSC_TRUE;
7982:     *flg = A->symmetric;
7983:   } else {
7984:     *set = PETSC_FALSE;
7985:   }
7986:   return(0);
7987: }

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

7994:    Not Collective

7996:    Input Parameter:
7997: .  A - the matrix to check

7999:    Output Parameters:
8000: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8001: -  flg - the result

8003:    Level: advanced

8005:    Concepts: matrix^symmetry

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

8010: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8011: @*/
8012: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8013: {
8018:   if (A->hermitian_set) {
8019:     *set = PETSC_TRUE;
8020:     *flg = A->hermitian;
8021:   } else {
8022:     *set = PETSC_FALSE;
8023:   }
8024:   return(0);
8025: }

8029: /*@
8030:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8032:    Collective on Mat

8034:    Input Parameter:
8035: .  A - the matrix to test

8037:    Output Parameters:
8038: .  flg - the result

8040:    Level: intermediate

8042:    Concepts: matrix^symmetry

8044: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8045: @*/
8046: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8047: {

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

8057:     A->structurally_symmetric_set = PETSC_TRUE;
8058:   }
8059:   *flg = A->structurally_symmetric;
8060:   return(0);
8061: }

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

8070:     Not collective

8072:    Input Parameter:
8073: .   vec - the vector

8075:    Output Parameters:
8076: +   nstash   - the size of the stash
8077: .   reallocs - the number of additional mallocs incurred.
8078: .   bnstash   - the size of the block stash
8079: -   breallocs - the number of additional mallocs incurred.in the block stash

8081:    Level: advanced

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

8085: @*/
8086: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8087: {

8091:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8092:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8093:   return(0);
8094: }

8098: /*@C
8099:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8100:      parallel layout

8102:    Collective on Mat

8104:    Input Parameter:
8105: .  mat - the matrix

8107:    Output Parameter:
8108: +   right - (optional) vector that the matrix can be multiplied against
8109: -   left - (optional) vector that the matrix vector product can be stored in

8111:   Level: advanced

8113: .seealso: MatCreate()
8114: @*/
8115: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8116: {

8122:   MatCheckPreallocated(mat,1);
8123:   if (mat->ops->getvecs) {
8124:     (*mat->ops->getvecs)(mat,right,left);
8125:   } else {
8126:     PetscMPIInt size;
8127:     MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8128:     if (right) {
8129:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8130:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8131:       VecSetBlockSize(*right,mat->rmap->bs);
8132:       VecSetType(*right,VECSTANDARD);
8133:       PetscLayoutReference(mat->cmap,&(*right)->map);
8134:     }
8135:     if (left) {
8136:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8137:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8138:       VecSetBlockSize(*left,mat->rmap->bs);
8139:       VecSetType(*left,VECSTANDARD);
8140:       PetscLayoutReference(mat->rmap,&(*left)->map);
8141:     }
8142:   }
8143:   return(0);
8144: }

8148: /*@C
8149:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8150:      with default values.

8152:    Not Collective

8154:    Input Parameters:
8155: .    info - the MatFactorInfo data structure


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

8161:    Level: developer

8163: .seealso: MatFactorInfo

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

8168: @*/

8170: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8171: {

8175:   PetscMemzero(info,sizeof(MatFactorInfo));
8176:   return(0);
8177: }

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

8184:    Neighbor-wise Collective on Mat

8186:    Input Parameters:
8187: +  A - the matrix
8188: .  P - the projection matrix
8189: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8190: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

8192:    Output Parameters:
8193: .  C - the product matrix

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

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

8201:    Level: intermediate

8203: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8204: @*/
8205: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8206: {
8208:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8209:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8210:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8211:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

8214:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8215:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

8219:   MatCheckPreallocated(A,1);
8220:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8221:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8224:   MatCheckPreallocated(P,2);
8225:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8226:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8228:   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);
8229:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

8231:   if (scall == MAT_REUSE_MATRIX) {
8234:     if (viatranspose || viamatmatmatmult) {
8235:       Mat Pt;
8236:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8237:       if (viamatmatmatmult) {
8238:         MatMatMatMult(Pt,A,P,scall,fill,C);
8239:       } else {
8240:         Mat AP;
8241:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8242:         MatMatMult(Pt,AP,scall,fill,C);
8243:         MatDestroy(&AP);
8244:       }
8245:       MatDestroy(&Pt);
8246:     } else {
8247:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8248:       (*(*C)->ops->ptapnumeric)(A,P,*C);
8249:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8250:     }
8251:     return(0);
8252:   }

8254:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8255:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

8257:   fA = A->ops->ptap;
8258:   fP = P->ops->ptap;
8259:   if (fP == fA) {
8260:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8261:     ptap = fA;
8262:   } else {
8263:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8264:     char ptapname[256];
8265:     PetscStrcpy(ptapname,"MatPtAP_");
8266:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
8267:     PetscStrcat(ptapname,"_");
8268:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
8269:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8270:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8271:     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);
8272:   }

8274:   if (viatranspose || viamatmatmatmult) {
8275:     Mat Pt;
8276:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8277:     if (viamatmatmatmult) {
8278:       MatMatMatMult(Pt,A,P,scall,fill,C);
8279:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8280:     } else {
8281:       Mat AP;
8282:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8283:       MatMatMult(Pt,AP,scall,fill,C);
8284:       MatDestroy(&AP);
8285:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8286:     }
8287:     MatDestroy(&Pt);
8288:   } else {
8289:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8290:     (*ptap)(A,P,scall,fill,C);
8291:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8292:   }
8293:   return(0);
8294: }

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

8301:    Neighbor-wise Collective on Mat

8303:    Input Parameters:
8304: +  A - the matrix
8305: -  P - the projection matrix

8307:    Output Parameters:
8308: .  C - the product matrix

8310:    Notes:
8311:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8312:    the user using MatDeatroy().

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

8317:    Level: intermediate

8319: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8320: @*/
8321: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8322: {

8328:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8329:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8332:   MatCheckPreallocated(P,2);
8333:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8334:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8337:   MatCheckPreallocated(C,3);
8338:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8339:   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);
8340:   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);
8341:   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);
8342:   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);
8343:   MatCheckPreallocated(A,1);

8345:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8346:   (*C->ops->ptapnumeric)(A,P,C);
8347:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8348:   return(0);
8349: }

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

8356:    Neighbor-wise Collective on Mat

8358:    Input Parameters:
8359: +  A - the matrix
8360: -  P - the projection matrix

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

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

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

8372:    Level: intermediate

8374: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8375: @*/
8376: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8377: {

8383:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8384:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8385:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8388:   MatCheckPreallocated(P,2);
8389:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8390:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8393:   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);
8394:   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);
8395:   MatCheckPreallocated(A,1);
8396:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8397:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8398:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

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

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

8409:    Neighbor-wise Collective on Mat

8411:    Input Parameters:
8412: +  A - the matrix
8413: .  R - the projection matrix
8414: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8415: -  fill - expected fill as ratio of nnz(C)/nnz(A)

8417:    Output Parameters:
8418: .  C - the product matrix

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

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

8426:    Level: intermediate

8428: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8429: @*/
8430: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8431: {

8437:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8438:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8441:   MatCheckPreallocated(R,2);
8442:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8443:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8445:   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);
8446:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8447:   MatCheckPreallocated(A,1);

8449:   if (!A->ops->rart) {
8450:     MatType mattype;
8451:     MatGetType(A,&mattype);
8452:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8453:   }
8454:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
8455:   (*A->ops->rart)(A,R,scall,fill,C);
8456:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
8457:   return(0);
8458: }

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

8465:    Neighbor-wise Collective on Mat

8467:    Input Parameters:
8468: +  A - the matrix
8469: -  R - the projection matrix

8471:    Output Parameters:
8472: .  C - the product matrix

8474:    Notes:
8475:    C must have been created by calling MatRARtSymbolic and must be destroyed by
8476:    the user using MatDeatroy().

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

8481:    Level: intermediate

8483: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8484: @*/
8485: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8486: {

8492:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8493:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8496:   MatCheckPreallocated(R,2);
8497:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8498:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8501:   MatCheckPreallocated(C,3);
8502:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8503:   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);
8504:   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);
8505:   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);
8506:   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);
8507:   MatCheckPreallocated(A,1);

8509:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8510:   (*A->ops->rartnumeric)(A,R,C);
8511:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8512:   return(0);
8513: }

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

8520:    Neighbor-wise Collective on Mat

8522:    Input Parameters:
8523: +  A - the matrix
8524: -  R - the projection matrix

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

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

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

8536:    Level: intermediate

8538: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8539: @*/
8540: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8541: {

8547:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8548:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8549:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8552:   MatCheckPreallocated(R,2);
8553:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8554:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8557:   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);
8558:   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);
8559:   MatCheckPreallocated(A,1);
8560:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8561:   (*A->ops->rartsymbolic)(A,R,fill,C);
8562:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

8564:   MatSetBlockSize(*C,A->rmap->bs);
8565:   return(0);
8566: }

8570: /*@
8571:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

8573:    Neighbor-wise Collective on Mat

8575:    Input Parameters:
8576: +  A - the left matrix
8577: .  B - the right matrix
8578: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8579: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8580:           if the result is a dense matrix this is irrelevent

8582:    Output Parameters:
8583: .  C - the product matrix

8585:    Notes:
8586:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

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

8593:    If you have many matrices with the same non-zero structure to multiply, you
8594:    should either
8595: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8596: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

8598:    Level: intermediate

8600: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8601: @*/
8602: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8603: {
8605:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8606:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8607:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

8612:   MatCheckPreallocated(A,1);
8613:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8614:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8617:   MatCheckPreallocated(B,2);
8618:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8619:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8621:   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);
8622:   if (scall == MAT_REUSE_MATRIX) {
8625:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8626:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8627:     (*(*C)->ops->matmultnumeric)(A,B,*C);
8628:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8629:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8630:     return(0);
8631:   }
8632:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8633:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

8635:   fA = A->ops->matmult;
8636:   fB = B->ops->matmult;
8637:   if (fB == fA) {
8638:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8639:     mult = fB;
8640:   } else {
8641:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8642:     char multname[256];
8643:     PetscStrcpy(multname,"MatMatMult_");
8644:     PetscStrcat(multname,((PetscObject)A)->type_name);
8645:     PetscStrcat(multname,"_");
8646:     PetscStrcat(multname,((PetscObject)B)->type_name);
8647:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8648:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
8649:     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);
8650:   }
8651:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8652:   (*mult)(A,B,scall,fill,C);
8653:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8654:   return(0);
8655: }

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

8663:    Neighbor-wise Collective on Mat

8665:    Input Parameters:
8666: +  A - the left matrix
8667: .  B - the right matrix
8668: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8669:       if C is a dense matrix this is irrelevent

8671:    Output Parameters:
8672: .  C - the product matrix

8674:    Notes:
8675:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

8680:    This routine is currently implemented for
8681:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8682:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8683:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8685:    Level: intermediate

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

8690: .seealso: MatMatMult(), MatMatMultNumeric()
8691: @*/
8692: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8693: {
8695:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
8696:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
8697:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

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

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

8712:   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);
8713:   if (fill == PETSC_DEFAULT) fill = 2.0;
8714:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8715:   MatCheckPreallocated(A,1);

8717:   Asymbolic = A->ops->matmultsymbolic;
8718:   Bsymbolic = B->ops->matmultsymbolic;
8719:   if (Asymbolic == Bsymbolic) {
8720:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8721:     symbolic = Bsymbolic;
8722:   } else { /* dispatch based on the type of A and B */
8723:     char symbolicname[256];
8724:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8725:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8726:     PetscStrcat(symbolicname,"_");
8727:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8728:     PetscStrcat(symbolicname,"_C");
8729:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
8730:     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);
8731:   }
8732:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8733:   (*symbolic)(A,B,fill,C);
8734:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8735:   return(0);
8736: }

8740: /*@
8741:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8742:    Call this routine after first calling MatMatMultSymbolic().

8744:    Neighbor-wise Collective on Mat

8746:    Input Parameters:
8747: +  A - the left matrix
8748: -  B - the right matrix

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

8753:    Notes:
8754:    C must have been created with MatMatMultSymbolic().

8756:    This routine is currently implemented for
8757:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8758:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8759:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8761:    Level: intermediate

8763: .seealso: MatMatMult(), MatMatMultSymbolic()
8764: @*/
8765: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8766: {

8770:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
8771:   return(0);
8772: }

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

8779:    Neighbor-wise Collective on Mat

8781:    Input Parameters:
8782: +  A - the left matrix
8783: .  B - the right matrix
8784: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8785: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8787:    Output Parameters:
8788: .  C - the product matrix

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

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

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

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

8800:    Level: intermediate

8802: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8803: @*/
8804: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8805: {
8807:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8808:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

8813:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8814:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8817:   MatCheckPreallocated(B,2);
8818:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8819:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8821:   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);
8822:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8823:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8824:   MatCheckPreallocated(A,1);

8826:   fA = A->ops->mattransposemult;
8827:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8828:   fB = B->ops->mattransposemult;
8829:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8830:   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);

8832:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
8833:   if (scall == MAT_INITIAL_MATRIX) {
8834:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8835:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8836:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8837:   }
8838:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8839:   (*A->ops->mattransposemultnumeric)(A,B,*C);
8840:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8841:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
8842:   return(0);
8843: }

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

8850:    Neighbor-wise Collective on Mat

8852:    Input Parameters:
8853: +  A - the left matrix
8854: .  B - the right matrix
8855: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8856: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8858:    Output Parameters:
8859: .  C - the product matrix

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

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

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

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

8872:    Level: intermediate

8874: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8875: @*/
8876: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8877: {
8879:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8880:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8881:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

8886:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8887:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8890:   MatCheckPreallocated(B,2);
8891:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8892:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8894:   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);
8895:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8896:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8897:   MatCheckPreallocated(A,1);

8899:   fA = A->ops->transposematmult;
8900:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8901:   fB = B->ops->transposematmult;
8902:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8903:   if (fB==fA) {
8904:     transposematmult = fA;
8905:   }
8906:   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);
8907:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8908:   (*transposematmult)(A,B,scall,fill,C);
8909:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8910:   return(0);
8911: }

8915: /*@
8916:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

8918:    Neighbor-wise Collective on Mat

8920:    Input Parameters:
8921: +  A - the left matrix
8922: .  B - the middle matrix
8923: .  C - the right matrix
8924: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8925: -  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
8926:           if the result is a dense matrix this is irrelevent

8928:    Output Parameters:
8929: .  D - the product matrix

8931:    Notes:
8932:    Unless scall is MAT_REUSE_MATRIX D will be created.

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

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

8939:    If you have many matrices with the same non-zero structure to multiply, you
8940:    should either
8941: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8942: $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed

8944:    Level: intermediate

8946: .seealso: MatMatMult, MatPtAP()
8947: @*/
8948: PetscErrorCode  MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
8949: {
8951:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8952:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8953:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8954:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

8959:   MatCheckPreallocated(A,1);
8960:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8961:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8964:   MatCheckPreallocated(B,2);
8965:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8966:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8969:   MatCheckPreallocated(C,3);
8970:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8971:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8972:   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);
8973:   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);
8974:   if (scall == MAT_REUSE_MATRIX) {
8977:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
8978:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
8979:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
8980:     return(0);
8981:   }
8982:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8983:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

8985:   fA = A->ops->matmatmult;
8986:   fB = B->ops->matmatmult;
8987:   fC = C->ops->matmatmult;
8988:   if (fA == fB && fA == fC) {
8989:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8990:     mult = fA;
8991:   } else {
8992:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
8993:     char multname[256];
8994:     PetscStrcpy(multname,"MatMatMatMult_");
8995:     PetscStrcat(multname,((PetscObject)A)->type_name);
8996:     PetscStrcat(multname,"_");
8997:     PetscStrcat(multname,((PetscObject)B)->type_name);
8998:     PetscStrcat(multname,"_");
8999:     PetscStrcat(multname,((PetscObject)C)->type_name);
9000:     PetscStrcat(multname,"_C");
9001:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9002:     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);
9003:   }
9004:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9005:   (*mult)(A,B,C,scall,fill,D);
9006:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9007:   return(0);
9008: }

9012: /*@C
9013:    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

9015:    Collective on Mat

9017:    Input Parameters:
9018: +  mat - the matrix
9019: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9020: .  subcomm - MPI communicator split from the communicator where mat resides in
9021: .  mlocal_red - number of local rows of the redundant matrix
9022: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9024:    Output Parameter:
9025: .  matredundant - redundant matrix

9027:    Notes:
9028:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9029:    original matrix has not changed from that last call to MatGetRedundantMatrix().

9031:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9032:    calling it.

9034:    Only MPIAIJ matrix is supported.

9036:    Level: advanced

9038:    Concepts: subcommunicator
9039:    Concepts: duplicate matrix

9041: .seealso: MatDestroy()
9042: @*/
9043: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
9044: {

9049:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9052:   }
9053:   if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9054:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9055:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9056:   MatCheckPreallocated(mat,1);

9058:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
9059:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
9060:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
9061:   return(0);
9062: }

9066: /*@C
9067:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9068:    a given 'mat' object. Each submatrix can span multiple procs.

9070:    Collective on Mat

9072:    Input Parameters:
9073: +  mat - the matrix
9074: .  subcomm - the subcommunicator obtained by com_split(comm)
9075: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

9077:    Output Parameter:
9078: .  subMat - 'parallel submatrices each spans a given subcomm

9080:   Notes:
9081:   The submatrix partition across processors is dictated by 'subComm' a
9082:   communicator obtained by com_split(comm). The comm_split
9083:   is not restriced to be grouped with consecutive original ranks.

9085:   Due the comm_split() usage, the parallel layout of the submatrices
9086:   map directly to the layout of the original matrix [wrt the local
9087:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9088:   into the 'DiagonalMat' of the subMat, hence it is used directly from
9089:   the subMat. However the offDiagMat looses some columns - and this is
9090:   reconstructed with MatSetValues()

9092:   Level: advanced

9094:   Concepts: subcommunicator
9095:   Concepts: submatrices

9097: .seealso: MatGetSubMatrices()
9098: @*/
9099: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9100: {
9102:   PetscMPIInt    commsize,subCommSize;

9105:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9106:   MPI_Comm_size(subComm,&subCommSize);
9107:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

9109:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9110:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9111:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9112:   return(0);
9113: }

9117: /*@
9118:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

9120:    Not Collective

9122:    Input Arguments:
9123:    mat - matrix to extract local submatrix from
9124:    isrow - local row indices for submatrix
9125:    iscol - local column indices for submatrix

9127:    Output Arguments:
9128:    submat - the submatrix

9130:    Level: intermediate

9132:    Notes:
9133:    The submat should be returned with MatRestoreLocalSubMatrix().

9135:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9136:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

9138:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9139:    MatSetValuesBlockedLocal() will also be implemented.

9141: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9142: @*/
9143: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9144: {


9154:   if (mat->ops->getlocalsubmatrix) {
9155:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9156:   } else {
9157:     MatCreateLocalRef(mat,isrow,iscol,submat);
9158:   }
9159:   return(0);
9160: }

9164: /*@
9165:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

9167:    Not Collective

9169:    Input Arguments:
9170:    mat - matrix to extract local submatrix from
9171:    isrow - local row indices for submatrix
9172:    iscol - local column indices for submatrix
9173:    submat - the submatrix

9175:    Level: intermediate

9177: .seealso: MatGetLocalSubMatrix()
9178: @*/
9179: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9180: {

9189:   if (*submat) {
9191:   }

9193:   if (mat->ops->restorelocalsubmatrix) {
9194:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9195:   } else {
9196:     MatDestroy(submat);
9197:   }
9198:   *submat = NULL;
9199:   return(0);
9200: }

9202: /* --------------------------------------------------------*/
9205: /*@
9206:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

9208:    Collective on Mat

9210:    Input Parameter:
9211: .  mat - the matrix

9213:    Output Parameter:
9214: .  is - if any rows have zero diagonals this contains the list of them

9216:    Level: developer

9218:    Concepts: matrix-vector product

9220: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9221: @*/
9222: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9223: {

9229:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9230:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9232:   if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9233:   (*mat->ops->findzerodiagonals)(mat,is);
9234:   return(0);
9235: }

9239: /*@C
9240:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

9242:   Collective on Mat

9244:   Input Parameters:
9245: . mat - the matrix

9247:   Output Parameters:
9248: . values - the block inverses in column major order (FORTRAN-like)

9250:    Note:
9251:    This routine is not available from Fortran.

9253:   Level: advanced
9254: @*/
9255: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9256: {

9261:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9262:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9263:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9264:   (*mat->ops->invertblockdiagonal)(mat,values);
9265:   return(0);
9266: }

9270: /*@C
9271:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9272:     via MatTransposeColoringCreate().

9274:     Collective on MatTransposeColoring

9276:     Input Parameter:
9277: .   c - coloring context

9279:     Level: intermediate

9281: .seealso: MatTransposeColoringCreate()
9282: @*/
9283: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9284: {
9285:   PetscErrorCode       ierr;
9286:   MatTransposeColoring matcolor=*c;

9289:   if (!matcolor) return(0);
9290:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

9292:   PetscFree(matcolor->ncolumns);
9293:   PetscFree(matcolor->nrows);
9294:   PetscFree(matcolor->colorforrow);
9295:   PetscFree2(matcolor->rows,matcolor->columnsforspidx);
9296:   PetscFree(matcolor->colorforcol);
9297:   PetscFree(matcolor->columns);
9298:   PetscHeaderDestroy(c);
9299:   return(0);
9300: }

9304: /*@C
9305:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9306:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9307:     MatTransposeColoring to sparse B.

9309:     Collective on MatTransposeColoring

9311:     Input Parameters:
9312: +   B - sparse matrix B
9313: .   Btdense - symbolic dense matrix B^T
9314: -   coloring - coloring context created with MatTransposeColoringCreate()

9316:     Output Parameter:
9317: .   Btdense - dense matrix B^T

9319:     Options Database Keys:
9320: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9321: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9322: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

9324:     Level: intermediate

9326: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

9328: .keywords: coloring
9329: @*/
9330: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9331: {


9339:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9340:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9341:   return(0);
9342: }

9346: /*@C
9347:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9348:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9349:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9350:     Csp from Cden.

9352:     Collective on MatTransposeColoring

9354:     Input Parameters:
9355: +   coloring - coloring context created with MatTransposeColoringCreate()
9356: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

9358:     Output Parameter:
9359: .   Csp - sparse matrix

9361:     Options Database Keys:
9362: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9363: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9364: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

9366:     Level: intermediate

9368: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

9370: .keywords: coloring
9371: @*/
9372: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9373: {


9381:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9382:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9383:   return(0);
9384: }

9388: /*@C
9389:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

9391:    Collective on Mat

9393:    Input Parameters:
9394: +  mat - the matrix product C
9395: -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()

9397:     Output Parameter:
9398: .   color - the new coloring context

9400:     Level: intermediate

9402: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9403:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9404: @*/
9405: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9406: {
9407:   MatTransposeColoring c;
9408:   MPI_Comm             comm;
9409:   PetscErrorCode       ierr;

9412:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9413:   PetscObjectGetComm((PetscObject)mat,&comm);
9414:   PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);

9416:   c->ctype = iscoloring->ctype;
9417:   if (mat->ops->transposecoloringcreate) {
9418:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9419:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

9421:   *color = c;
9422:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9423:   return(0);
9424: }