Actual source code: matrix.c
 
   petsc-3.7.7 2017-09-25
   
  2: /*
  3:    This is where the abstract matrix operations are defined
  4: */
  6: #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
  7: #include <petsc/private/vecimpl.h>
  8: #include <petsc/private/isimpl.h>
 10: /* Logging support */
 11: PetscClassId MAT_CLASSID;
 12: PetscClassId MAT_COLORING_CLASSID;
 13: PetscClassId MAT_FDCOLORING_CLASSID;
 14: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
 16: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
 17: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
 18: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
 19: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
 20: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
 21: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
 22: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
 23: PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_GetSubMatrix;
 24: PetscLogEvent MAT_TransposeColoringCreate;
 25: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
 26: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
 27: PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
 28: PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
 29: PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
 30: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
 31: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
 32: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
 33: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
 34: PetscLogEvent MAT_GetMultiProcBlock;
 35: PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
 36: PetscLogEvent MAT_ViennaCLCopyToGPU;
 37: PetscLogEvent MAT_Merge,MAT_Residual;
 38: PetscLogEvent Mat_Coloring_Apply,Mat_Coloring_Comm,Mat_Coloring_Local,Mat_Coloring_ISCreate,Mat_Coloring_SetUp,Mat_Coloring_Weights;
 40: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
 44: /*@
 45:    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
 47:    Logically Collective on Vec
 49:    Input Parameters:
 50: +  x  - the vector
 51: -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
 52:           it will create one internally.
 54:    Output Parameter:
 55: .  x  - the vector
 57:    Example of Usage:
 58: .vb
 59:      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
 60:      VecSetRandom(x,rctx);
 61:      PetscRandomDestroy(rctx);
 62: .ve
 64:    Level: intermediate
 66:    Concepts: vector^setting to random
 67:    Concepts: random^vector
 69: .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
 70: @*/
 71: PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
 72: {
 74:   PetscRandom    randObj = NULL;
 81:   if (!rctx) {
 82:     MPI_Comm comm;
 83:     PetscObjectGetComm((PetscObject)x,&comm);
 84:     PetscRandomCreate(comm,&randObj);
 85:     PetscRandomSetFromOptions(randObj);
 86:     rctx = randObj;
 87:   }
 89:   PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
 90:   (*x->ops->setrandom)(x,rctx);
 91:   PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);
 93:   x->assembled = PETSC_TRUE;
 94:   PetscRandomDestroy(&randObj);
 95:   return(0);
 96: }
101: /*@
102:       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
104:   Input Parameter:
105: .    A  - the matrix
107:   Output Parameter:
108: .    keptrows - the rows that are not completely zero
110:   Level: intermediate
112:  @*/
113: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
114: {
119:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
120:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
121:   if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
122:   (*mat->ops->findnonzerorows)(mat,keptrows);
123:   return(0);
124: }
128: /*@
129:    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
131:    Not Collective
133:    Input Parameters:
134: .   A - the matrix
136:    Output Parameters:
137: .   a - the diagonal part (which is a SEQUENTIAL matrix)
139:    Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
140:           Use caution, as the reference count on the returned matrix is not incremented and it is used as
141:           part of the containing MPI Mat's normal operation.
143:    Level: advanced
145: @*/
146: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
147: {
148:   PetscErrorCode ierr,(*f)(Mat,Mat*);
149:   PetscMPIInt    size;
155:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
156:   MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
157:   PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);
158:   if (f) {
159:     (*f)(A,a);
160:     return(0);
161:   } else if (size == 1) {
162:     *a = A;
163:   } else {
164:     MatType mattype;
165:     MatGetType(A,&mattype);
166:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
167:   }
168:   return(0);
169: }
173: /*@
174:    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
176:    Collective on Mat
178:    Input Parameters:
179: .  mat - the matrix
181:    Output Parameter:
182: .   trace - the sum of the diagonal entries
184:    Level: advanced
186: @*/
187: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
188: {
190:   Vec            diag;
193:   MatCreateVecs(mat,&diag,NULL);
194:   MatGetDiagonal(mat,diag);
195:   VecSum(diag,trace);
196:   VecDestroy(&diag);
197:   return(0);
198: }
202: /*@
203:    MatRealPart - Zeros out the imaginary part of the matrix
205:    Logically Collective on Mat
207:    Input Parameters:
208: .  mat - the matrix
210:    Level: advanced
213: .seealso: MatImaginaryPart()
214: @*/
215: PetscErrorCode MatRealPart(Mat mat)
216: {
222:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
223:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
224:   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
225:   MatCheckPreallocated(mat,1);
226:   (*mat->ops->realpart)(mat);
227: #if defined(PETSC_HAVE_CUSP)
228:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
229:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
230:   }
231: #elif defined(PETSC_HAVE_VIENNACL)
232:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
233:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
234:   }
235: #elif defined(PETSC_HAVE_VECCUDA)
236:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
237:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
238:   }
239: #endif
240:   return(0);
241: }
245: /*@C
246:    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
248:    Collective on Mat
250:    Input Parameter:
251: .  mat - the matrix
253:    Output Parameters:
254: +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
255: -   ghosts - the global indices of the ghost points
257:    Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
259:    Level: advanced
261: @*/
262: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
263: {
269:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
270:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
271:   if (!mat->ops->getghosts) {
272:     if (nghosts) *nghosts = 0;
273:     if (ghosts) *ghosts = 0;
274:   } else {
275:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
276:   }
277:   return(0);
278: }
283: /*@
284:    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
286:    Logically Collective on Mat
288:    Input Parameters:
289: .  mat - the matrix
291:    Level: advanced
294: .seealso: MatRealPart()
295: @*/
296: PetscErrorCode MatImaginaryPart(Mat mat)
297: {
303:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
304:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
305:   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
306:   MatCheckPreallocated(mat,1);
307:   (*mat->ops->imaginarypart)(mat);
308: #if defined(PETSC_HAVE_CUSP)
309:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
310:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
311:   }
312: #elif defined(PETSC_HAVE_VIENNACL)
313:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
314:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
315:   }
316: #elif defined(PETSC_HAVE_VECCUDA)
317:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
318:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
319:   }
320: #endif
321:   return(0);
322: }
326: /*@
327:    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
329:    Collective on Mat
331:    Input Parameter:
332: .  mat - the matrix
334:    Output Parameters:
335: +  missing - is any diagonal missing
336: -  dd - first diagonal entry that is missing (optional)
338:    Level: advanced
341: .seealso: MatRealPart()
342: @*/
343: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
344: {
350:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
351:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
352:   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
353:   (*mat->ops->missingdiagonal)(mat,missing,dd);
354:   return(0);
355: }
359: /*@C
360:    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
361:    for each row that you get to ensure that your application does
362:    not bleed memory.
364:    Not Collective
366:    Input Parameters:
367: +  mat - the matrix
368: -  row - the row to get
370:    Output Parameters:
371: +  ncols -  if not NULL, the number of nonzeros in the row
372: .  cols - if not NULL, the column numbers
373: -  vals - if not NULL, the values
375:    Notes:
376:    This routine is provided for people who need to have direct access
377:    to the structure of a matrix.  We hope that we provide enough
378:    high-level matrix routines that few users will need it.
380:    MatGetRow() always returns 0-based column indices, regardless of
381:    whether the internal representation is 0-based (default) or 1-based.
383:    For better efficiency, set cols and/or vals to NULL if you do
384:    not wish to extract these quantities.
386:    The user can only examine the values extracted with MatGetRow();
387:    the values cannot be altered.  To change the matrix entries, one
388:    must use MatSetValues().
390:    You can only have one call to MatGetRow() outstanding for a particular
391:    matrix at a time, per processor. MatGetRow() can only obtain rows
392:    associated with the given processor, it cannot get rows from the
393:    other processors; for that we suggest using MatGetSubMatrices(), then
394:    MatGetRow() on the submatrix. The row indix passed to MatGetRows()
395:    is in the global number of rows.
397:    Fortran Notes:
398:    The calling sequence from Fortran is
399: .vb
400:    MatGetRow(matrix,row,ncols,cols,values,ierr)
401:          Mat     matrix (input)
402:          integer row    (input)
403:          integer ncols  (output)
404:          integer cols(maxcols) (output)
405:          double precision (or double complex) values(maxcols) output
406: .ve
407:    where maxcols >= maximum nonzeros in any row of the matrix.
410:    Caution:
411:    Do not try to change the contents of the output arrays (cols and vals).
412:    In some cases, this may corrupt the matrix.
414:    Level: advanced
416:    Concepts: matrices^row access
418: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
419: @*/
420: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
421: {
423:   PetscInt       incols;
428:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
429:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
430:   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
431:   MatCheckPreallocated(mat,1);
432:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
433:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
434:   if (ncols) *ncols = incols;
435:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
436:   return(0);
437: }
441: /*@
442:    MatConjugate - replaces the matrix values with their complex conjugates
444:    Logically Collective on Mat
446:    Input Parameters:
447: .  mat - the matrix
449:    Level: advanced
451: .seealso:  VecConjugate()
452: @*/
453: PetscErrorCode MatConjugate(Mat mat)
454: {
455: #if defined(PETSC_USE_COMPLEX)
460:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
461:   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");
462:   (*mat->ops->conjugate)(mat);
463: #if defined(PETSC_HAVE_CUSP)
464:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
465:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
466:   }
467: #elif defined(PETSC_HAVE_VIENNACL)
468:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
469:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
470:   }
471: #elif defined(PETSC_HAVE_VECCUDA)
472:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
473:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
474:   }
475: #endif
476:   return(0);
477: #else
478:   return 0;
479: #endif
480: }
484: /*@C
485:    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
487:    Not Collective
489:    Input Parameters:
490: +  mat - the matrix
491: .  row - the row to get
492: .  ncols, cols - the number of nonzeros and their columns
493: -  vals - if nonzero the column values
495:    Notes:
496:    This routine should be called after you have finished examining the entries.
498:    This routine zeros out ncols, cols, and vals. This is to prevent accidental
499:    us of the array after it has been restored. If you pass NULL, it will
500:    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
502:    Fortran Notes:
503:    The calling sequence from Fortran is
504: .vb
505:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
506:       Mat     matrix (input)
507:       integer row    (input)
508:       integer ncols  (output)
509:       integer cols(maxcols) (output)
510:       double precision (or double complex) values(maxcols) output
511: .ve
512:    Where maxcols >= maximum nonzeros in any row of the matrix.
514:    In Fortran MatRestoreRow() MUST be called after MatGetRow()
515:    before another call to MatGetRow() can be made.
517:    Level: advanced
519: .seealso:  MatGetRow()
520: @*/
521: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
522: {
528:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
529:   if (!mat->ops->restorerow) return(0);
530:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
531:   if (ncols) *ncols = 0;
532:   if (cols)  *cols = NULL;
533:   if (vals)  *vals = NULL;
534:   return(0);
535: }
539: /*@
540:    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
541:    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
543:    Not Collective
545:    Input Parameters:
546: +  mat - the matrix
548:    Notes:
549:    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.
551:    Level: advanced
553:    Concepts: matrices^row access
555: .seealso: MatRestoreRowRowUpperTriangular()
556: @*/
557: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
558: {
564:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
565:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
566:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
567:   MatCheckPreallocated(mat,1);
568:   (*mat->ops->getrowuppertriangular)(mat);
569:   return(0);
570: }
574: /*@
575:    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
577:    Not Collective
579:    Input Parameters:
580: +  mat - the matrix
582:    Notes:
583:    This routine should be called after you have finished MatGetRow/MatRestoreRow().
586:    Level: advanced
588: .seealso:  MatGetRowUpperTriangular()
589: @*/
590: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
591: {
596:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
597:   if (!mat->ops->restorerowuppertriangular) return(0);
598:   (*mat->ops->restorerowuppertriangular)(mat);
599:   return(0);
600: }
604: /*@C
605:    MatSetOptionsPrefix - Sets the prefix used for searching for all
606:    Mat options in the database.
608:    Logically Collective on Mat
610:    Input Parameter:
611: +  A - the Mat context
612: -  prefix - the prefix to prepend to all option names
614:    Notes:
615:    A hyphen (-) must NOT be given at the beginning of the prefix name.
616:    The first character of all runtime options is AUTOMATICALLY the hyphen.
618:    Level: advanced
620: .keywords: Mat, set, options, prefix, database
622: .seealso: MatSetFromOptions()
623: @*/
624: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
625: {
630:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
631:   return(0);
632: }
636: /*@C
637:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
638:    Mat options in the database.
640:    Logically Collective on Mat
642:    Input Parameters:
643: +  A - the Mat context
644: -  prefix - the prefix to prepend to all option names
646:    Notes:
647:    A hyphen (-) must NOT be given at the beginning of the prefix name.
648:    The first character of all runtime options is AUTOMATICALLY the hyphen.
650:    Level: advanced
652: .keywords: Mat, append, options, prefix, database
654: .seealso: MatGetOptionsPrefix()
655: @*/
656: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
657: {
662:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
663:   return(0);
664: }
668: /*@C
669:    MatGetOptionsPrefix - Sets the prefix used for searching for all
670:    Mat options in the database.
672:    Not Collective
674:    Input Parameter:
675: .  A - the Mat context
677:    Output Parameter:
678: .  prefix - pointer to the prefix string used
680:    Notes: On the fortran side, the user should pass in a string 'prefix' of
681:    sufficient length to hold the prefix.
683:    Level: advanced
685: .keywords: Mat, get, options, prefix, database
687: .seealso: MatAppendOptionsPrefix()
688: @*/
689: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
690: {
695:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
696:   return(0);
697: }
701: /*@
702:    MatSetUp - Sets up the internal matrix data structures for the later use.
704:    Collective on Mat
706:    Input Parameters:
707: .  A - the Mat context
709:    Notes:
710:    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
712:    If a suitable preallocation routine is used, this function does not need to be called.
714:    See the Performance chapter of the PETSc users manual for how to preallocate matrices
716:    Level: beginner
718: .keywords: Mat, setup
720: .seealso: MatCreate(), MatDestroy()
721: @*/
722: PetscErrorCode MatSetUp(Mat A)
723: {
724:   PetscMPIInt    size;
729:   if (!((PetscObject)A)->type_name) {
730:     MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
731:     if (size == 1) {
732:       MatSetType(A, MATSEQAIJ);
733:     } else {
734:       MatSetType(A, MATMPIAIJ);
735:     }
736:   }
737:   if (!A->preallocated && A->ops->setup) {
738:     PetscInfo(A,"Warning not preallocating matrix storage\n");
739:     (*A->ops->setup)(A);
740:   }
741:   A->preallocated = PETSC_TRUE;
742:   return(0);
743: }
745: #if defined(PETSC_HAVE_SAWS)
746: #include <petscviewersaws.h>
747: #endif
750: /*@C
751:    MatView - Visualizes a matrix object.
753:    Collective on Mat
755:    Input Parameters:
756: +  mat - the matrix
757: -  viewer - visualization context
759:   Notes:
760:   The available visualization contexts include
761: +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
762: .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
763: .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
764: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
766:    The user can open alternative visualization contexts with
767: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
768: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
769:          specified file; corresponding input uses MatLoad()
770: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
771:          an X window display
772: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
773:          Currently only the sequential dense and AIJ
774:          matrix types support the Socket viewer.
776:    The user can call PetscViewerPushFormat() to specify the output
777:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
778:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
779: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
780: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
781: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
782: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
783:          format common among all matrix types
784: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
785:          format (which is in many cases the same as the default)
786: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
787:          size and structure (not the matrix entries)
788: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
789:          the matrix structure
791:    Options Database Keys:
792: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
793: .  -mat_view ::ascii_info_detail - Prints more detailed info
794: .  -mat_view - Prints matrix in ASCII format
795: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
796: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
797: .  -display <name> - Sets display name (default is host)
798: .  -draw_pause <sec> - Sets number of seconds to pause after display
799: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 11 Using MATLAB with PETSc for details)
800: .  -viewer_socket_machine <machine> -
801: .  -viewer_socket_port <port> -
802: .  -mat_view binary - save matrix to file in binary format
803: -  -viewer_binary_filename <name> -
804:    Level: beginner
806:    Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
807:       viewer is used.
809:       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
810:       viewer is used.
812:       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
813:       And then use the following mouse functions:
814:           left mouse: zoom in
815:           middle mouse: zoom out
816:           right mouse: continue with the simulation
818:    Concepts: matrices^viewing
819:    Concepts: matrices^plotting
820:    Concepts: matrices^printing
822: .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
823:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
824: @*/
825: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
826: {
827:   PetscErrorCode    ierr;
828:   PetscInt          rows,cols,rbs,cbs;
829:   PetscBool         iascii,ibinary;
830:   PetscViewerFormat format;
831: #if defined(PETSC_HAVE_SAWS)
832:   PetscBool         issaws;
833: #endif
838:   if (!viewer) {
839:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
840:   }
843:   MatCheckPreallocated(mat,1);
844:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
845:   if (ibinary) {
846:     PetscBool mpiio;
847:     PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
848:     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
849:   }
851:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
852:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
853:   PetscViewerGetFormat(viewer,&format);
854:   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
855:     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
856:   }
858: #if defined(PETSC_HAVE_SAWS)
859:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
860: #endif
861:   if (iascii) {
862:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
863:     PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
864:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
865:       PetscViewerASCIIPushTab(viewer);
866:       MatGetSize(mat,&rows,&cols);
867:       MatGetBlockSizes(mat,&rbs,&cbs);
868:       if (rbs != 1 || cbs != 1) {
869:         if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
870:         else            {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
871:       } else {
872:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
873:       }
874:       if (mat->factortype) {
875:         const MatSolverPackage solver;
876:         MatFactorGetSolverPackage(mat,&solver);
877:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
878:       }
879:       if (mat->ops->getinfo) {
880:         MatInfo info;
881:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
882:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
883:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
884:       }
885:       if (mat->nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached null space\n");}
886:       if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");}
887:     }
888: #if defined(PETSC_HAVE_SAWS)
889:   } else if (issaws) {
890:     PetscMPIInt rank;
892:     PetscObjectName((PetscObject)mat);
893:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
894:     if (!((PetscObject)mat)->amsmem && !rank) {
895:       PetscObjectViewSAWs((PetscObject)mat,viewer);
896:     }
897: #endif
898:   }
899:   if (mat->ops->view) {
900:     PetscViewerASCIIPushTab(viewer);
901:     (*mat->ops->view)(mat,viewer);
902:     PetscViewerASCIIPopTab(viewer);
903:   }
904:   if (iascii) {
905:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
906:     PetscViewerGetFormat(viewer,&format);
907:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
908:       PetscViewerASCIIPopTab(viewer);
909:     }
910:   }
911:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
912:   return(0);
913: }
915: #if defined(PETSC_USE_DEBUG)
916: #include <../src/sys/totalview/tv_data_display.h>
917: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
918: {
919:   TV_add_row("Local rows", "int", &mat->rmap->n);
920:   TV_add_row("Local columns", "int", &mat->cmap->n);
921:   TV_add_row("Global rows", "int", &mat->rmap->N);
922:   TV_add_row("Global columns", "int", &mat->cmap->N);
923:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
924:   return TV_format_OK;
925: }
926: #endif
930: /*@C
931:    MatLoad - Loads a matrix that has been stored in binary format
932:    with MatView().  The matrix format is determined from the options database.
933:    Generates a parallel MPI matrix if the communicator has more than one
934:    processor.  The default matrix type is AIJ.
936:    Collective on PetscViewer
938:    Input Parameters:
939: +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
940:             or some related function before a call to MatLoad()
941: -  viewer - binary file viewer, created with PetscViewerBinaryOpen()
943:    Options Database Keys:
944:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
945:    block size
946: .    -matload_block_size <bs>
948:    Level: beginner
950:    Notes:
951:    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
952:    Mat before calling this routine if you wish to set it from the options database.
954:    MatLoad() automatically loads into the options database any options
955:    given in the file filename.info where filename is the name of the file
956:    that was passed to the PetscViewerBinaryOpen(). The options in the info
957:    file will be ignored if you use the -viewer_binary_skip_info option.
959:    If the type or size of newmat is not set before a call to MatLoad, PETSc
960:    sets the default matrix type AIJ and sets the local and global sizes.
961:    If type and/or size is already set, then the same are used.
963:    In parallel, each processor can load a subset of rows (or the
964:    entire matrix).  This routine is especially useful when a large
965:    matrix is stored on disk and only part of it is desired on each
966:    processor.  For example, a parallel solver may access only some of
967:    the rows from each processor.  The algorithm used here reads
968:    relatively small blocks of data rather than reading the entire
969:    matrix and then subsetting it.
971:    Notes for advanced users:
972:    Most users should not need to know the details of the binary storage
973:    format, since MatLoad() and MatView() completely hide these details.
974:    But for anyone who's interested, the standard binary matrix storage
975:    format is
977: $    int    MAT_FILE_CLASSID
978: $    int    number of rows
979: $    int    number of columns
980: $    int    total number of nonzeros
981: $    int    *number nonzeros in each row
982: $    int    *column indices of all nonzeros (starting index is zero)
983: $    PetscScalar *values of all nonzeros
985:    PETSc automatically does the byte swapping for
986: machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
987: linux, Windows and the paragon; thus if you write your own binary
988: read/write routines you have to swap the bytes; see PetscBinaryRead()
989: and PetscBinaryWrite() to see how this may be done.
991: .keywords: matrix, load, binary, input
993: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
995:  @*/
996: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
997: {
999:   PetscBool      isbinary,flg;
1004:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
1005:   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1007:   if (!((PetscObject)newmat)->type_name) {
1008:     MatSetType(newmat,MATAIJ);
1009:   }
1011:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1012:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1013:   (*newmat->ops->load)(newmat,viewer);
1014:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);
1016:   flg  = PETSC_FALSE;
1017:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1018:   if (flg) {
1019:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1020:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1021:   }
1022:   flg  = PETSC_FALSE;
1023:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1024:   if (flg) {
1025:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1026:   }
1027:   return(0);
1028: }
1032: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1033: {
1035:   Mat_Redundant  *redund = *redundant;
1036:   PetscInt       i;
1039:   if (redund){
1040:     if (redund->matseq) { /* via MatGetSubMatrices()  */
1041:       ISDestroy(&redund->isrow);
1042:       ISDestroy(&redund->iscol);
1043:       MatDestroy(&redund->matseq[0]);
1044:       PetscFree(redund->matseq);
1045:     } else {
1046:       PetscFree2(redund->send_rank,redund->recv_rank);
1047:       PetscFree(redund->sbuf_j);
1048:       PetscFree(redund->sbuf_a);
1049:       for (i=0; i<redund->nrecvs; i++) {
1050:         PetscFree(redund->rbuf_j[i]);
1051:         PetscFree(redund->rbuf_a[i]);
1052:       }
1053:       PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1054:     }
1056:     if (redund->subcomm) {
1057:       PetscCommDestroy(&redund->subcomm);
1058:     }
1059:     PetscFree(redund);
1060:   }
1061:   return(0);
1062: }
1066: /*@
1067:    MatDestroy - Frees space taken by a matrix.
1069:    Collective on Mat
1071:    Input Parameter:
1072: .  A - the matrix
1074:    Level: beginner
1076: @*/
1077: PetscErrorCode MatDestroy(Mat *A)
1078: {
1082:   if (!*A) return(0);
1084:   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; return(0);}
1086:   /* if memory was published with SAWs then destroy it */
1087:   PetscObjectSAWsViewOff((PetscObject)*A);
1088:   if ((*A)->ops->destroy) {
1089:     (*(*A)->ops->destroy)(*A);
1090:   }
1092:   PetscFree((*A)->solvertype);
1093:   MatDestroy_Redundant(&(*A)->redundant);
1094:   MatNullSpaceDestroy(&(*A)->nullsp);
1095:   MatNullSpaceDestroy(&(*A)->transnullsp);
1096:   MatNullSpaceDestroy(&(*A)->nearnullsp);
1097:   PetscLayoutDestroy(&(*A)->rmap);
1098:   PetscLayoutDestroy(&(*A)->cmap);
1099:   PetscHeaderDestroy(A);
1100:   return(0);
1101: }
1105: /*@
1106:    MatSetValues - Inserts or adds a block of values into a matrix.
1107:    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1108:    MUST be called after all calls to MatSetValues() have been completed.
1110:    Not Collective
1112:    Input Parameters:
1113: +  mat - the matrix
1114: .  v - a logically two-dimensional array of values
1115: .  m, idxm - the number of rows and their global indices
1116: .  n, idxn - the number of columns and their global indices
1117: -  addv - either ADD_VALUES or INSERT_VALUES, where
1118:    ADD_VALUES adds values to any existing entries, and
1119:    INSERT_VALUES replaces existing entries with new values
1121:    Notes:
1122:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1123:       MatSetUp() before using this routine
1125:    By default the values, v, are row-oriented. See MatSetOption() for other options.
1127:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1128:    options cannot be mixed without intervening calls to the assembly
1129:    routines.
1131:    MatSetValues() uses 0-based row and column numbers in Fortran
1132:    as well as in C.
1134:    Negative indices may be passed in idxm and idxn, these rows and columns are
1135:    simply ignored. This allows easily inserting element stiffness matrices
1136:    with homogeneous Dirchlet boundary conditions that you don't want represented
1137:    in the matrix.
1139:    Efficiency Alert:
1140:    The routine MatSetValuesBlocked() may offer much better efficiency
1141:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1143:    Level: beginner
1145:    Concepts: matrices^putting entries in
1147: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1148:           InsertMode, INSERT_VALUES, ADD_VALUES
1149: @*/
1150: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1151: {
1153: #if defined(PETSC_USE_DEBUG)
1154:   PetscInt       i,j;
1155: #endif
1160:   if (!m || !n) return(0); /* no values to insert */
1164:   MatCheckPreallocated(mat,1);
1165:   if (mat->insertmode == NOT_SET_VALUES) {
1166:     mat->insertmode = addv;
1167:   }
1168: #if defined(PETSC_USE_DEBUG)
1169:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1170:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1171:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1173:   for (i=0; i<m; i++) {
1174:     for (j=0; j<n; j++) {
1175:       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1176: #if defined(PETSC_USE_COMPLEX)
1177:         SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1178: #else
1179:         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1180: #endif
1181:     }
1182:   }
1183: #endif
1185:   if (mat->assembled) {
1186:     mat->was_assembled = PETSC_TRUE;
1187:     mat->assembled     = PETSC_FALSE;
1188:   }
1189:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1190:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1191:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1192: #if defined(PETSC_HAVE_CUSP)
1193:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1194:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1195:   }
1196: #elif defined(PETSC_HAVE_VIENNACL)
1197:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1198:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1199:   }
1200: #elif defined(PETSC_HAVE_VECCUDA)
1201:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1202:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1203:   }
1204: #endif
1205:   return(0);
1206: }
1211: /*@
1212:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1213:         values into a matrix
1215:    Not Collective
1217:    Input Parameters:
1218: +  mat - the matrix
1219: .  row - the (block) row to set
1220: -  v - a logically two-dimensional array of values
1222:    Notes:
1223:    By the values, v, are column-oriented (for the block version) and sorted
1225:    All the nonzeros in the row must be provided
1227:    The matrix must have previously had its column indices set
1229:    The row must belong to this process
1231:    Level: intermediate
1233:    Concepts: matrices^putting entries in
1235: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1236:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1237: @*/
1238: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1239: {
1241:   PetscInt       globalrow;
1247:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1248:   MatSetValuesRow(mat,globalrow,v);
1249: #if defined(PETSC_HAVE_CUSP)
1250:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1251:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1252:   }
1253: #elif defined(PETSC_HAVE_VIENNACL)
1254:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1255:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1256:   }
1257: #elif defined(PETSC_HAVE_VECCUDA)
1258:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1259:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1260:   }
1261: #endif
1262:   return(0);
1263: }
1267: /*@
1268:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1269:         values into a matrix
1271:    Not Collective
1273:    Input Parameters:
1274: +  mat - the matrix
1275: .  row - the (block) row to set
1276: -  v - a logically two-dimensional (column major) array of values for  block matrices with blocksize larger than one, otherwise a one dimensional array of values
1278:    Notes:
1279:    The values, v, are column-oriented for the block version.
1281:    All the nonzeros in the row must be provided
1283:    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1285:    The row must belong to this process
1287:    Level: advanced
1289:    Concepts: matrices^putting entries in
1291: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1292:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1293: @*/
1294: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1295: {
1301:   MatCheckPreallocated(mat,1);
1303: #if defined(PETSC_USE_DEBUG)
1304:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1305:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1306: #endif
1307:   mat->insertmode = INSERT_VALUES;
1309:   if (mat->assembled) {
1310:     mat->was_assembled = PETSC_TRUE;
1311:     mat->assembled     = PETSC_FALSE;
1312:   }
1313:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1314:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1315:   (*mat->ops->setvaluesrow)(mat,row,v);
1316:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1317: #if defined(PETSC_HAVE_CUSP)
1318:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1319:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1320:   }
1321: #elif defined(PETSC_HAVE_VIENNACL)
1322:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1323:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1324:   }
1325: #elif defined(PETSC_HAVE_VECCUDA)
1326:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1327:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1328:   }
1329: #endif
1330:   return(0);
1331: }
1335: /*@
1336:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1337:      Using structured grid indexing
1339:    Not Collective
1341:    Input Parameters:
1342: +  mat - the matrix
1343: .  m - number of rows being entered
1344: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1345: .  n - number of columns being entered
1346: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1347: .  v - a logically two-dimensional array of values
1348: -  addv - either ADD_VALUES or INSERT_VALUES, where
1349:    ADD_VALUES adds values to any existing entries, and
1350:    INSERT_VALUES replaces existing entries with new values
1352:    Notes:
1353:    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1355:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1356:    options cannot be mixed without intervening calls to the assembly
1357:    routines.
1359:    The grid coordinates are across the entire grid, not just the local portion
1361:    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1362:    as well as in C.
1364:    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1366:    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1367:    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1369:    The columns and rows in the stencil passed in MUST be contained within the
1370:    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1371:    if you create a DMDA with an overlap of one grid level and on a particular process its first
1372:    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1373:    first i index you can use in your column and row indices in MatSetStencil() is 5.
1375:    In Fortran idxm and idxn should be declared as
1376: $     MatStencil idxm(4,m),idxn(4,n)
1377:    and the values inserted using
1378: $    idxm(MatStencil_i,1) = i
1379: $    idxm(MatStencil_j,1) = j
1380: $    idxm(MatStencil_k,1) = k
1381: $    idxm(MatStencil_c,1) = c
1382:    etc
1384:    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1385:    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1386:    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1387:    DM_BOUNDARY_PERIODIC boundary type.
1389:    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
1390:    a single value per point) you can skip filling those indices.
1392:    Inspired by the structured grid interface to the HYPRE package
1393:    (http://www.llnl.gov/CASC/hypre)
1395:    Efficiency Alert:
1396:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1397:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1399:    Level: beginner
1401:    Concepts: matrices^putting entries in
1403: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1404:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1405: @*/
1406: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1407: {
1409:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1410:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1411:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1414:   if (!m || !n) return(0); /* no values to insert */
1421:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1422:     jdxm = buf; jdxn = buf+m;
1423:   } else {
1424:     PetscMalloc2(m,&bufm,n,&bufn);
1425:     jdxm = bufm; jdxn = bufn;
1426:   }
1427:   for (i=0; i<m; i++) {
1428:     for (j=0; j<3-sdim; j++) dxm++;
1429:     tmp = *dxm++ - starts[0];
1430:     for (j=0; j<dim-1; j++) {
1431:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1432:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1433:     }
1434:     if (mat->stencil.noc) dxm++;
1435:     jdxm[i] = tmp;
1436:   }
1437:   for (i=0; i<n; i++) {
1438:     for (j=0; j<3-sdim; j++) dxn++;
1439:     tmp = *dxn++ - starts[0];
1440:     for (j=0; j<dim-1; j++) {
1441:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1442:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1443:     }
1444:     if (mat->stencil.noc) dxn++;
1445:     jdxn[i] = tmp;
1446:   }
1447:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1448:   PetscFree2(bufm,bufn);
1449:   return(0);
1450: }
1454: /*@
1455:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1456:      Using structured grid indexing
1458:    Not Collective
1460:    Input Parameters:
1461: +  mat - the matrix
1462: .  m - number of rows being entered
1463: .  idxm - grid coordinates for matrix rows being entered
1464: .  n - number of columns being entered
1465: .  idxn - grid coordinates for matrix columns being entered
1466: .  v - a logically two-dimensional array of values
1467: -  addv - either ADD_VALUES or INSERT_VALUES, where
1468:    ADD_VALUES adds values to any existing entries, and
1469:    INSERT_VALUES replaces existing entries with new values
1471:    Notes:
1472:    By default the values, v, are row-oriented and unsorted.
1473:    See MatSetOption() for other options.
1475:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1476:    options cannot be mixed without intervening calls to the assembly
1477:    routines.
1479:    The grid coordinates are across the entire grid, not just the local portion
1481:    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1482:    as well as in C.
1484:    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1486:    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1487:    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1489:    The columns and rows in the stencil passed in MUST be contained within the
1490:    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1491:    if you create a DMDA with an overlap of one grid level and on a particular process its first
1492:    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1493:    first i index you can use in your column and row indices in MatSetStencil() is 5.
1495:    In Fortran idxm and idxn should be declared as
1496: $     MatStencil idxm(4,m),idxn(4,n)
1497:    and the values inserted using
1498: $    idxm(MatStencil_i,1) = i
1499: $    idxm(MatStencil_j,1) = j
1500: $    idxm(MatStencil_k,1) = k
1501:    etc
1503:    Negative indices may be passed in idxm and idxn, these rows and columns are
1504:    simply ignored. This allows easily inserting element stiffness matrices
1505:    with homogeneous Dirchlet boundary conditions that you don't want represented
1506:    in the matrix.
1508:    Inspired by the structured grid interface to the HYPRE package
1509:    (http://www.llnl.gov/CASC/hypre)
1511:    Level: beginner
1513:    Concepts: matrices^putting entries in
1515: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1516:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1517:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1518: @*/
1519: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1520: {
1522:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1523:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1524:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1527:   if (!m || !n) return(0); /* no values to insert */
1534:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1535:     jdxm = buf; jdxn = buf+m;
1536:   } else {
1537:     PetscMalloc2(m,&bufm,n,&bufn);
1538:     jdxm = bufm; jdxn = bufn;
1539:   }
1540:   for (i=0; i<m; i++) {
1541:     for (j=0; j<3-sdim; j++) dxm++;
1542:     tmp = *dxm++ - starts[0];
1543:     for (j=0; j<sdim-1; j++) {
1544:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1545:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1546:     }
1547:     dxm++;
1548:     jdxm[i] = tmp;
1549:   }
1550:   for (i=0; i<n; i++) {
1551:     for (j=0; j<3-sdim; j++) dxn++;
1552:     tmp = *dxn++ - starts[0];
1553:     for (j=0; j<sdim-1; j++) {
1554:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1555:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1556:     }
1557:     dxn++;
1558:     jdxn[i] = tmp;
1559:   }
1560:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1561:   PetscFree2(bufm,bufn);
1562: #if defined(PETSC_HAVE_CUSP)
1563:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1564:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1565:   }
1566: #elif defined(PETSC_HAVE_VIENNACL)
1567:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1568:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1569:   }
1570: #elif defined(PETSC_HAVE_VECCUDA)
1571:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1572:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1573:   }
1574: #endif
1575:   return(0);
1576: }
1580: /*@
1581:    MatSetStencil - Sets the grid information for setting values into a matrix via
1582:         MatSetValuesStencil()
1584:    Not Collective
1586:    Input Parameters:
1587: +  mat - the matrix
1588: .  dim - dimension of the grid 1, 2, or 3
1589: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1590: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1591: -  dof - number of degrees of freedom per node
1594:    Inspired by the structured grid interface to the HYPRE package
1595:    (www.llnl.gov/CASC/hyper)
1597:    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1598:    user.
1600:    Level: beginner
1602:    Concepts: matrices^putting entries in
1604: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1605:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1606: @*/
1607: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1608: {
1609:   PetscInt i;
1616:   mat->stencil.dim = dim + (dof > 1);
1617:   for (i=0; i<dim; i++) {
1618:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1619:     mat->stencil.starts[i] = starts[dim-i-1];
1620:   }
1621:   mat->stencil.dims[dim]   = dof;
1622:   mat->stencil.starts[dim] = 0;
1623:   mat->stencil.noc         = (PetscBool)(dof == 1);
1624:   return(0);
1625: }
1629: /*@
1630:    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1632:    Not Collective
1634:    Input Parameters:
1635: +  mat - the matrix
1636: .  v - a logically two-dimensional array of values
1637: .  m, idxm - the number of block rows and their global block indices
1638: .  n, idxn - the number of block columns and their global block indices
1639: -  addv - either ADD_VALUES or INSERT_VALUES, where
1640:    ADD_VALUES adds values to any existing entries, and
1641:    INSERT_VALUES replaces existing entries with new values
1643:    Notes:
1644:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1645:    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1647:    The m and n count the NUMBER of blocks in the row direction and column direction,
1648:    NOT the total number of rows/columns; for example, if the block size is 2 and
1649:    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1650:    The values in idxm would be 1 2; that is the first index for each block divided by
1651:    the block size.
1653:    Note that you must call MatSetBlockSize() when constructing this matrix (before
1654:    preallocating it).
1656:    By default the values, v, are row-oriented, so the layout of
1657:    v is the same as for MatSetValues(). See MatSetOption() for other options.
1659:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1660:    options cannot be mixed without intervening calls to the assembly
1661:    routines.
1663:    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1664:    as well as in C.
1666:    Negative indices may be passed in idxm and idxn, these rows and columns are
1667:    simply ignored. This allows easily inserting element stiffness matrices
1668:    with homogeneous Dirchlet boundary conditions that you don't want represented
1669:    in the matrix.
1671:    Each time an entry is set within a sparse matrix via MatSetValues(),
1672:    internal searching must be done to determine where to place the
1673:    data in the matrix storage space.  By instead inserting blocks of
1674:    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1675:    reduced.
1677:    Example:
1678: $   Suppose m=n=2 and block size(bs) = 2 The array is
1679: $
1680: $   1  2  | 3  4
1681: $   5  6  | 7  8
1682: $   - - - | - - -
1683: $   9  10 | 11 12
1684: $   13 14 | 15 16
1685: $
1686: $   v[] should be passed in like
1687: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1688: $
1689: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1690: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1692:    Level: intermediate
1694:    Concepts: matrices^putting entries in blocked
1696: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1697: @*/
1698: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1699: {
1705:   if (!m || !n) return(0); /* no values to insert */
1709:   MatCheckPreallocated(mat,1);
1710:   if (mat->insertmode == NOT_SET_VALUES) {
1711:     mat->insertmode = addv;
1712:   }
1713: #if defined(PETSC_USE_DEBUG)
1714:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1715:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1716:   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1717: #endif
1719:   if (mat->assembled) {
1720:     mat->was_assembled = PETSC_TRUE;
1721:     mat->assembled     = PETSC_FALSE;
1722:   }
1723:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1724:   if (mat->ops->setvaluesblocked) {
1725:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1726:   } else {
1727:     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1728:     PetscInt i,j,bs,cbs;
1729:     MatGetBlockSizes(mat,&bs,&cbs);
1730:     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1731:       iidxm = buf; iidxn = buf + m*bs;
1732:     } else {
1733:       PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1734:       iidxm = bufr; iidxn = bufc;
1735:     }
1736:     for (i=0; i<m; i++) {
1737:       for (j=0; j<bs; j++) {
1738:         iidxm[i*bs+j] = bs*idxm[i] + j;
1739:       }
1740:     }
1741:     for (i=0; i<n; i++) {
1742:       for (j=0; j<cbs; j++) {
1743:         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1744:       }
1745:     }
1746:     MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1747:     PetscFree2(bufr,bufc);
1748:   }
1749:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1750: #if defined(PETSC_HAVE_CUSP)
1751:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1752:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1753:   }
1754: #elif defined(PETSC_HAVE_VIENNACL)
1755:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1756:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1757:   }
1758: #elif defined(PETSC_HAVE_VECCUDA)
1759:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1760:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1761:   }
1762: #endif
1763:   return(0);
1764: }
1768: /*@
1769:    MatGetValues - Gets a block of values from a matrix.
1771:    Not Collective; currently only returns a local block
1773:    Input Parameters:
1774: +  mat - the matrix
1775: .  v - a logically two-dimensional array for storing the values
1776: .  m, idxm - the number of rows and their global indices
1777: -  n, idxn - the number of columns and their global indices
1779:    Notes:
1780:    The user must allocate space (m*n PetscScalars) for the values, v.
1781:    The values, v, are then returned in a row-oriented format,
1782:    analogous to that used by default in MatSetValues().
1784:    MatGetValues() uses 0-based row and column numbers in
1785:    Fortran as well as in C.
1787:    MatGetValues() requires that the matrix has been assembled
1788:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1789:    MatSetValues() and MatGetValues() CANNOT be made in succession
1790:    without intermediate matrix assembly.
1792:    Negative row or column indices will be ignored and those locations in v[] will be
1793:    left unchanged.
1795:    Level: advanced
1797:    Concepts: matrices^accessing values
1799: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1800: @*/
1801: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1802: {
1808:   if (!m || !n) return(0);
1812:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1813:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1814:   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1815:   MatCheckPreallocated(mat,1);
1817:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1818:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1819:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1820:   return(0);
1821: }
1825: /*@
1826:   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1827:   the same size. Currently, this can only be called once and creates the given matrix.
1829:   Not Collective
1831:   Input Parameters:
1832: + mat - the matrix
1833: . nb - the number of blocks
1834: . bs - the number of rows (and columns) in each block
1835: . rows - a concatenation of the rows for each block
1836: - v - a concatenation of logically two-dimensional arrays of values
1838:   Notes:
1839:   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1841:   Level: advanced
1843:   Concepts: matrices^putting entries in
1845: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1846:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1847: @*/
1848: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1849: {
1857: #if defined(PETSC_USE_DEBUG)
1858:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1859: #endif
1861:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1862:   if (mat->ops->setvaluesbatch) {
1863:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1864:   } else {
1865:     PetscInt b;
1866:     for (b = 0; b < nb; ++b) {
1867:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1868:     }
1869:   }
1870:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1871:   return(0);
1872: }
1876: /*@
1877:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1878:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1879:    using a local (per-processor) numbering.
1881:    Not Collective
1883:    Input Parameters:
1884: +  x - the matrix
1885: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1886: - cmapping - column mapping
1888:    Level: intermediate
1890:    Concepts: matrices^local to global mapping
1891:    Concepts: local to global mapping^for matrices
1893: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1894: @*/
1895: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1896: {
1905:   if (x->ops->setlocaltoglobalmapping) {
1906:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1907:   } else {
1908:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1909:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1910:   }
1911:   return(0);
1912: }
1917: /*@
1918:    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1920:    Not Collective
1922:    Input Parameters:
1923: .  A - the matrix
1925:    Output Parameters:
1926: + rmapping - row mapping
1927: - cmapping - column mapping
1929:    Level: advanced
1931:    Concepts: matrices^local to global mapping
1932:    Concepts: local to global mapping^for matrices
1934: .seealso:  MatSetValuesLocal()
1935: @*/
1936: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1937: {
1943:   if (rmapping) *rmapping = A->rmap->mapping;
1944:   if (cmapping) *cmapping = A->cmap->mapping;
1945:   return(0);
1946: }
1950: /*@
1951:    MatGetLayouts - Gets the PetscLayout objects for rows and columns
1953:    Not Collective
1955:    Input Parameters:
1956: .  A - the matrix
1958:    Output Parameters:
1959: + rmap - row layout
1960: - cmap - column layout
1962:    Level: advanced
1964: .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
1965: @*/
1966: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1967: {
1973:   if (rmap) *rmap = A->rmap;
1974:   if (cmap) *cmap = A->cmap;
1975:   return(0);
1976: }
1980: /*@
1981:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1982:    using a local ordering of the nodes.
1984:    Not Collective
1986:    Input Parameters:
1987: +  mat - the matrix
1988: .  nrow, irow - number of rows and their local indices
1989: .  ncol, icol - number of columns and their local indices
1990: .  y -  a logically two-dimensional array of values
1991: -  addv - either INSERT_VALUES or ADD_VALUES, where
1992:    ADD_VALUES adds values to any existing entries, and
1993:    INSERT_VALUES replaces existing entries with new values
1995:    Notes:
1996:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1997:       MatSetUp() before using this routine
1999:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2001:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2002:    options cannot be mixed without intervening calls to the assembly
2003:    routines.
2005:    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2006:    MUST be called after all calls to MatSetValuesLocal() have been completed.
2008:    Level: intermediate
2010:    Concepts: matrices^putting entries in with local numbering
2012: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2013:            MatSetValueLocal()
2014: @*/
2015: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2016: {
2022:   MatCheckPreallocated(mat,1);
2023:   if (!nrow || !ncol) return(0); /* no values to insert */
2027:   if (mat->insertmode == NOT_SET_VALUES) {
2028:     mat->insertmode = addv;
2029:   }
2030: #if defined(PETSC_USE_DEBUG)
2031:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2032:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2033:   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2034: #endif
2036:   if (mat->assembled) {
2037:     mat->was_assembled = PETSC_TRUE;
2038:     mat->assembled     = PETSC_FALSE;
2039:   }
2040:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2041:   if (mat->ops->setvalueslocal) {
2042:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
2043:   } else {
2044:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2045:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2046:       irowm = buf; icolm = buf+nrow;
2047:     } else {
2048:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2049:       irowm = bufr; icolm = bufc;
2050:     }
2051:     ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
2052:     ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
2053:     MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
2054:     PetscFree2(bufr,bufc);
2055:   }
2056:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2057: #if defined(PETSC_HAVE_CUSP)
2058:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2059:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2060:   }
2061: #elif defined(PETSC_HAVE_VIENNACL)
2062:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2063:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2064:   }
2065: #elif defined(PETSC_HAVE_VECCUDA)
2066:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2067:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2068:   }
2069: #endif
2070:   return(0);
2071: }
2075: /*@
2076:    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2077:    using a local ordering of the nodes a block at a time.
2079:    Not Collective
2081:    Input Parameters:
2082: +  x - the matrix
2083: .  nrow, irow - number of rows and their local indices
2084: .  ncol, icol - number of columns and their local indices
2085: .  y -  a logically two-dimensional array of values
2086: -  addv - either INSERT_VALUES or ADD_VALUES, where
2087:    ADD_VALUES adds values to any existing entries, and
2088:    INSERT_VALUES replaces existing entries with new values
2090:    Notes:
2091:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2092:       MatSetUp() before using this routine
2094:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2095:       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2097:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2098:    options cannot be mixed without intervening calls to the assembly
2099:    routines.
2101:    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2102:    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2104:    Level: intermediate
2106:    Concepts: matrices^putting blocked values in with local numbering
2108: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2109:            MatSetValuesLocal(),  MatSetValuesBlocked()
2110: @*/
2111: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2112: {
2118:   MatCheckPreallocated(mat,1);
2119:   if (!nrow || !ncol) return(0); /* no values to insert */
2123:   if (mat->insertmode == NOT_SET_VALUES) {
2124:     mat->insertmode = addv;
2125:   }
2126: #if defined(PETSC_USE_DEBUG)
2127:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2128:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2129:   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);
2130: #endif
2132:   if (mat->assembled) {
2133:     mat->was_assembled = PETSC_TRUE;
2134:     mat->assembled     = PETSC_FALSE;
2135:   }
2136:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2137:   if (mat->ops->setvaluesblockedlocal) {
2138:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2139:   } else {
2140:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2141:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2142:       irowm = buf; icolm = buf + nrow;
2143:     } else {
2144:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2145:       irowm = bufr; icolm = bufc;
2146:     }
2147:     ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2148:     ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2149:     MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2150:     PetscFree2(bufr,bufc);
2151:   }
2152:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2153: #if defined(PETSC_HAVE_CUSP)
2154:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2155:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2156:   }
2157: #elif defined(PETSC_HAVE_VIENNACL)
2158:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2159:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2160:   }
2161: #elif defined(PETSC_HAVE_VECCUDA)
2162:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2163:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2164:   }
2165: #endif
2166:   return(0);
2167: }
2171: /*@
2172:    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2174:    Collective on Mat and Vec
2176:    Input Parameters:
2177: +  mat - the matrix
2178: -  x   - the vector to be multiplied
2180:    Output Parameters:
2181: .  y - the result
2183:    Notes:
2184:    The vectors x and y cannot be the same.  I.e., one cannot
2185:    call MatMult(A,y,y).
2187:    Level: developer
2189:    Concepts: matrix-vector product
2191: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2192: @*/
2193: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2194: {
2203:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2204:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2205:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2206:   MatCheckPreallocated(mat,1);
2208:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2209:   (*mat->ops->multdiagonalblock)(mat,x,y);
2210:   PetscObjectStateIncrease((PetscObject)y);
2211:   return(0);
2212: }
2214: /* --------------------------------------------------------*/
2217: /*@
2218:    MatMult - Computes the matrix-vector product, y = Ax.
2220:    Neighbor-wise Collective on Mat and Vec
2222:    Input Parameters:
2223: +  mat - the matrix
2224: -  x   - the vector to be multiplied
2226:    Output Parameters:
2227: .  y - the result
2229:    Notes:
2230:    The vectors x and y cannot be the same.  I.e., one cannot
2231:    call MatMult(A,y,y).
2233:    Level: beginner
2235:    Concepts: matrix-vector product
2237: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2238: @*/
2239: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2240: {
2248:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2249:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2250:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2251: #if !defined(PETSC_HAVE_CONSTRAINTS)
2252:   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);
2253:   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);
2254:   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);
2255: #endif
2256:   VecLocked(y,3);
2257:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2258:   MatCheckPreallocated(mat,1);
2260:   VecLockPush(x);
2261:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2262:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2263:   (*mat->ops->mult)(mat,x,y);
2264:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2265:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2266:   VecLockPop(x);
2267:   return(0);
2268: }
2272: /*@
2273:    MatMultTranspose - Computes matrix transpose times a vector.
2275:    Neighbor-wise Collective on Mat and Vec
2277:    Input Parameters:
2278: +  mat - the matrix
2279: -  x   - the vector to be multilplied
2281:    Output Parameters:
2282: .  y - the result
2284:    Notes:
2285:    The vectors x and y cannot be the same.  I.e., one cannot
2286:    call MatMultTranspose(A,y,y).
2288:    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2289:    use MatMultHermitianTranspose()
2291:    Level: beginner
2293:    Concepts: matrix vector product^transpose
2295: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2296: @*/
2297: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2298: {
2307:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2308:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2309:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2310: #if !defined(PETSC_HAVE_CONSTRAINTS)
2311:   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);
2312:   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);
2313: #endif
2314:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2315:   MatCheckPreallocated(mat,1);
2317:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2318:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2319:   VecLockPush(x);
2320:   (*mat->ops->multtranspose)(mat,x,y);
2321:   VecLockPop(x);
2322:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2323:   PetscObjectStateIncrease((PetscObject)y);
2324:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2325:   return(0);
2326: }
2330: /*@
2331:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2333:    Neighbor-wise Collective on Mat and Vec
2335:    Input Parameters:
2336: +  mat - the matrix
2337: -  x   - the vector to be multilplied
2339:    Output Parameters:
2340: .  y - the result
2342:    Notes:
2343:    The vectors x and y cannot be the same.  I.e., one cannot
2344:    call MatMultHermitianTranspose(A,y,y).
2346:    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2348:    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2350:    Level: beginner
2352:    Concepts: matrix vector product^transpose
2354: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2355: @*/
2356: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2357: {
2359:   Vec            w;
2367:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2368:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2369:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2370: #if !defined(PETSC_HAVE_CONSTRAINTS)
2371:   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);
2372:   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);
2373: #endif
2374:   MatCheckPreallocated(mat,1);
2376:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2377:   if (mat->ops->multhermitiantranspose) {
2378:     VecLockPush(x);
2379:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2380:     VecLockPop(x);
2381:   } else {
2382:     VecDuplicate(x,&w);
2383:     VecCopy(x,w);
2384:     VecConjugate(w);
2385:     MatMultTranspose(mat,w,y);
2386:     VecDestroy(&w);
2387:     VecConjugate(y);
2388:   }
2389:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2390:   PetscObjectStateIncrease((PetscObject)y);
2391:   return(0);
2392: }
2396: /*@
2397:     MatMultAdd -  Computes v3 = v2 + A * v1.
2399:     Neighbor-wise Collective on Mat and Vec
2401:     Input Parameters:
2402: +   mat - the matrix
2403: -   v1, v2 - the vectors
2405:     Output Parameters:
2406: .   v3 - the result
2408:     Notes:
2409:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2410:     call MatMultAdd(A,v1,v2,v1).
2412:     Level: beginner
2414:     Concepts: matrix vector product^addition
2416: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2417: @*/
2418: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2419: {
2429:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2430:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2431:   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);
2432:   /* 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);
2433:      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); */
2434:   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);
2435:   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);
2436:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2437:   MatCheckPreallocated(mat,1);
2439:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2440:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2441:   VecLockPush(v1);
2442:   (*mat->ops->multadd)(mat,v1,v2,v3);
2443:   VecLockPop(v1);
2444:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2445:   PetscObjectStateIncrease((PetscObject)v3);
2446:   return(0);
2447: }
2451: /*@
2452:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2454:    Neighbor-wise Collective on Mat and Vec
2456:    Input Parameters:
2457: +  mat - the matrix
2458: -  v1, v2 - the vectors
2460:    Output Parameters:
2461: .  v3 - the result
2463:    Notes:
2464:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2465:    call MatMultTransposeAdd(A,v1,v2,v1).
2467:    Level: beginner
2469:    Concepts: matrix vector product^transpose and addition
2471: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2472: @*/
2473: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2474: {
2484:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2485:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2486:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2487:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2488:   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);
2489:   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);
2490:   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);
2491:   MatCheckPreallocated(mat,1);
2493:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2494:   VecLockPush(v1);
2495:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2496:   VecLockPop(v1);
2497:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2498:   PetscObjectStateIncrease((PetscObject)v3);
2499:   return(0);
2500: }
2504: /*@
2505:    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2507:    Neighbor-wise Collective on Mat and Vec
2509:    Input Parameters:
2510: +  mat - the matrix
2511: -  v1, v2 - the vectors
2513:    Output Parameters:
2514: .  v3 - the result
2516:    Notes:
2517:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2518:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2520:    Level: beginner
2522:    Concepts: matrix vector product^transpose and addition
2524: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2525: @*/
2526: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2527: {
2537:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2538:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2539:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2540:   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);
2541:   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);
2542:   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);
2543:   MatCheckPreallocated(mat,1);
2545:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2546:   VecLockPush(v1);
2547:   if (mat->ops->multhermitiantransposeadd) {
2548:     (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2549:    } else {
2550:     Vec w,z;
2551:     VecDuplicate(v1,&w);
2552:     VecCopy(v1,w);
2553:     VecConjugate(w);
2554:     VecDuplicate(v3,&z);
2555:     MatMultTranspose(mat,w,z);
2556:     VecDestroy(&w);
2557:     VecConjugate(z);
2558:     VecWAXPY(v3,1.0,v2,z);
2559:     VecDestroy(&z);
2560:   }
2561:   VecLockPop(v1);
2562:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2563:   PetscObjectStateIncrease((PetscObject)v3);
2564:   return(0);
2565: }
2569: /*@
2570:    MatMultConstrained - The inner multiplication routine for a
2571:    constrained matrix P^T A P.
2573:    Neighbor-wise Collective on Mat and Vec
2575:    Input Parameters:
2576: +  mat - the matrix
2577: -  x   - the vector to be multilplied
2579:    Output Parameters:
2580: .  y - the result
2582:    Notes:
2583:    The vectors x and y cannot be the same.  I.e., one cannot
2584:    call MatMult(A,y,y).
2586:    Level: beginner
2588: .keywords: matrix, multiply, matrix-vector product, constraint
2589: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2590: @*/
2591: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2592: {
2599:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2600:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2601:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2602:   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);
2603:   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);
2604:   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);
2606:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2607:   VecLockPush(x);
2608:   (*mat->ops->multconstrained)(mat,x,y);
2609:   VecLockPop(x);
2610:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2611:   PetscObjectStateIncrease((PetscObject)y);
2612:   return(0);
2613: }
2617: /*@
2618:    MatMultTransposeConstrained - The inner multiplication routine for a
2619:    constrained matrix P^T A^T P.
2621:    Neighbor-wise Collective on Mat and Vec
2623:    Input Parameters:
2624: +  mat - the matrix
2625: -  x   - the vector to be multilplied
2627:    Output Parameters:
2628: .  y - the result
2630:    Notes:
2631:    The vectors x and y cannot be the same.  I.e., one cannot
2632:    call MatMult(A,y,y).
2634:    Level: beginner
2636: .keywords: matrix, multiply, matrix-vector product, constraint
2637: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2638: @*/
2639: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2640: {
2647:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2648:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2649:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2650:   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);
2651:   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);
2653:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2654:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2655:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2656:   PetscObjectStateIncrease((PetscObject)y);
2657:   return(0);
2658: }
2662: /*@C
2663:    MatGetFactorType - gets the type of factorization it is
2665:    Note Collective
2666:    as the flag
2668:    Input Parameters:
2669: .  mat - the matrix
2671:    Output Parameters:
2672: .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2674:     Level: intermediate
2676: .seealso:    MatFactorType, MatGetFactor()
2677: @*/
2678: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2679: {
2683:   *t = mat->factortype;
2684:   return(0);
2685: }
2687: /* ------------------------------------------------------------*/
2690: /*@C
2691:    MatGetInfo - Returns information about matrix storage (number of
2692:    nonzeros, memory, etc.).
2694:    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2696:    Input Parameters:
2697: .  mat - the matrix
2699:    Output Parameters:
2700: +  flag - flag indicating the type of parameters to be returned
2701:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2702:    MAT_GLOBAL_SUM - sum over all processors)
2703: -  info - matrix information context
2705:    Notes:
2706:    The MatInfo context contains a variety of matrix data, including
2707:    number of nonzeros allocated and used, number of mallocs during
2708:    matrix assembly, etc.  Additional information for factored matrices
2709:    is provided (such as the fill ratio, number of mallocs during
2710:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2711:    when using the runtime options
2712: $       -info -mat_view ::ascii_info
2714:    Example for C/C++ Users:
2715:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2716:    data within the MatInfo context.  For example,
2717: .vb
2718:       MatInfo info;
2719:       Mat     A;
2720:       double  mal, nz_a, nz_u;
2722:       MatGetInfo(A,MAT_LOCAL,&info);
2723:       mal  = info.mallocs;
2724:       nz_a = info.nz_allocated;
2725: .ve
2727:    Example for Fortran Users:
2728:    Fortran users should declare info as a double precision
2729:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2730:    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2731:    a complete list of parameter names.
2732: .vb
2733:       double  precision info(MAT_INFO_SIZE)
2734:       double  precision mal, nz_a
2735:       Mat     A
2736:       integer ierr
2738:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2739:       mal = info(MAT_INFO_MALLOCS)
2740:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2741: .ve
2743:     Level: intermediate
2745:     Concepts: matrices^getting information on
2747:     Developer Note: fortran interface is not autogenerated as the f90
2748:     interface defintion cannot be generated correctly [due to MatInfo]
2750: .seealso: MatStashGetInfo()
2752: @*/
2753: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2754: {
2761:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2762:   MatCheckPreallocated(mat,1);
2763:   (*mat->ops->getinfo)(mat,flag,info);
2764:   return(0);
2765: }
2767: /* ----------------------------------------------------------*/
2771: /*@C
2772:    MatLUFactor - Performs in-place LU factorization of matrix.
2774:    Collective on Mat
2776:    Input Parameters:
2777: +  mat - the matrix
2778: .  row - row permutation
2779: .  col - column permutation
2780: -  info - options for factorization, includes
2781: $          fill - expected fill as ratio of original fill.
2782: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2783: $                   Run with the option -info to determine an optimal value to use
2785:    Notes:
2786:    Most users should employ the simplified KSP interface for linear solvers
2787:    instead of working directly with matrix algebra routines such as this.
2788:    See, e.g., KSPCreate().
2790:    This changes the state of the matrix to a factored matrix; it cannot be used
2791:    for example with MatSetValues() unless one first calls MatSetUnfactored().
2793:    Level: developer
2795:    Concepts: matrices^LU factorization
2797: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2798:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2800:     Developer Note: fortran interface is not autogenerated as the f90
2801:     interface defintion cannot be generated correctly [due to MatFactorInfo]
2803: @*/
2804: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2805: {
2807:   MatFactorInfo  tinfo;
2815:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2816:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2817:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2818:   MatCheckPreallocated(mat,1);
2819:   if (!info) {
2820:     MatFactorInfoInitialize(&tinfo);
2821:     info = &tinfo;
2822:   }
2824:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2825:   (*mat->ops->lufactor)(mat,row,col,info);
2826:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2827:   PetscObjectStateIncrease((PetscObject)mat);
2828:   return(0);
2829: }
2833: /*@C
2834:    MatILUFactor - Performs in-place ILU factorization of matrix.
2836:    Collective on Mat
2838:    Input Parameters:
2839: +  mat - the matrix
2840: .  row - row permutation
2841: .  col - column permutation
2842: -  info - structure containing
2843: $      levels - number of levels of fill.
2844: $      expected fill - as ratio of original fill.
2845: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2846:                 missing diagonal entries)
2848:    Notes:
2849:    Probably really in-place only when level of fill is zero, otherwise allocates
2850:    new space to store factored matrix and deletes previous memory.
2852:    Most users should employ the simplified KSP interface for linear solvers
2853:    instead of working directly with matrix algebra routines such as this.
2854:    See, e.g., KSPCreate().
2856:    Level: developer
2858:    Concepts: matrices^ILU factorization
2860: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2862:     Developer Note: fortran interface is not autogenerated as the f90
2863:     interface defintion cannot be generated correctly [due to MatFactorInfo]
2865: @*/
2866: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2867: {
2876:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2877:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2878:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2879:   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2880:   MatCheckPreallocated(mat,1);
2882:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2883:   (*mat->ops->ilufactor)(mat,row,col,info);
2884:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2885:   PetscObjectStateIncrease((PetscObject)mat);
2886:   return(0);
2887: }
2891: /*@C
2892:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2893:    Call this routine before calling MatLUFactorNumeric().
2895:    Collective on Mat
2897:    Input Parameters:
2898: +  fact - the factor matrix obtained with MatGetFactor()
2899: .  mat - the matrix
2900: .  row, col - row and column permutations
2901: -  info - options for factorization, includes
2902: $          fill - expected fill as ratio of original fill.
2903: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2904: $                   Run with the option -info to determine an optimal value to use
2907:    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2909:    Most users should employ the simplified KSP interface for linear solvers
2910:    instead of working directly with matrix algebra routines such as this.
2911:    See, e.g., KSPCreate().
2913:    Level: developer
2915:    Concepts: matrices^LU symbolic factorization
2917: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
2919:     Developer Note: fortran interface is not autogenerated as the f90
2920:     interface defintion cannot be generated correctly [due to MatFactorInfo]
2922: @*/
2923: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2924: {
2934:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2935:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2936:   if (!(fact)->ops->lufactorsymbolic) {
2937:     const MatSolverPackage spackage;
2938:     MatFactorGetSolverPackage(fact,&spackage);
2939:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2940:   }
2941:   MatCheckPreallocated(mat,2);
2943:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2944:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2945:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2946:   PetscObjectStateIncrease((PetscObject)fact);
2947:   return(0);
2948: }
2952: /*@C
2953:    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2954:    Call this routine after first calling MatLUFactorSymbolic().
2956:    Collective on Mat
2958:    Input Parameters:
2959: +  fact - the factor matrix obtained with MatGetFactor()
2960: .  mat - the matrix
2961: -  info - options for factorization
2963:    Notes:
2964:    See MatLUFactor() for in-place factorization.  See
2965:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2967:    Most users should employ the simplified KSP interface for linear solvers
2968:    instead of working directly with matrix algebra routines such as this.
2969:    See, e.g., KSPCreate().
2971:    Level: developer
2973:    Concepts: matrices^LU numeric factorization
2975: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2977:     Developer Note: fortran interface is not autogenerated as the f90
2978:     interface defintion cannot be generated correctly [due to MatFactorInfo]
2980: @*/
2981: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2982: {
2990:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2991:   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);
2993:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2994:   MatCheckPreallocated(mat,2);
2995:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2996:   (fact->ops->lufactornumeric)(fact,mat,info);
2997:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2998:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
2999:   PetscObjectStateIncrease((PetscObject)fact);
3000:   return(0);
3001: }
3005: /*@C
3006:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3007:    symmetric matrix.
3009:    Collective on Mat
3011:    Input Parameters:
3012: +  mat - the matrix
3013: .  perm - row and column permutations
3014: -  f - expected fill as ratio of original fill
3016:    Notes:
3017:    See MatLUFactor() for the nonsymmetric case.  See also
3018:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3020:    Most users should employ the simplified KSP interface for linear solvers
3021:    instead of working directly with matrix algebra routines such as this.
3022:    See, e.g., KSPCreate().
3024:    Level: developer
3026:    Concepts: matrices^Cholesky factorization
3028: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3029:           MatGetOrdering()
3031:     Developer Note: fortran interface is not autogenerated as the f90
3032:     interface defintion cannot be generated correctly [due to MatFactorInfo]
3034: @*/
3035: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3036: {
3044:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3045:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3046:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3047:   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3048:   MatCheckPreallocated(mat,1);
3050:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3051:   (*mat->ops->choleskyfactor)(mat,perm,info);
3052:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3053:   PetscObjectStateIncrease((PetscObject)mat);
3054:   return(0);
3055: }
3059: /*@C
3060:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3061:    of a symmetric matrix.
3063:    Collective on Mat
3065:    Input Parameters:
3066: +  fact - the factor matrix obtained with MatGetFactor()
3067: .  mat - the matrix
3068: .  perm - row and column permutations
3069: -  info - options for factorization, includes
3070: $          fill - expected fill as ratio of original fill.
3071: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3072: $                   Run with the option -info to determine an optimal value to use
3074:    Notes:
3075:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3076:    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3078:    Most users should employ the simplified KSP interface for linear solvers
3079:    instead of working directly with matrix algebra routines such as this.
3080:    See, e.g., KSPCreate().
3082:    Level: developer
3084:    Concepts: matrices^Cholesky symbolic factorization
3086: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3087:           MatGetOrdering()
3089:     Developer Note: fortran interface is not autogenerated as the f90
3090:     interface defintion cannot be generated correctly [due to MatFactorInfo]
3092: @*/
3093: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3094: {
3103:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3104:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3105:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3106:   if (!(fact)->ops->choleskyfactorsymbolic) {
3107:     const MatSolverPackage spackage;
3108:     MatFactorGetSolverPackage(fact,&spackage);
3109:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3110:   }
3111:   MatCheckPreallocated(mat,2);
3113:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3114:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3115:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3116:   PetscObjectStateIncrease((PetscObject)fact);
3117:   return(0);
3118: }
3122: /*@C
3123:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3124:    of a symmetric matrix. Call this routine after first calling
3125:    MatCholeskyFactorSymbolic().
3127:    Collective on Mat
3129:    Input Parameters:
3130: +  fact - the factor matrix obtained with MatGetFactor()
3131: .  mat - the initial matrix
3132: .  info - options for factorization
3133: -  fact - the symbolic factor of mat
3136:    Notes:
3137:    Most users should employ the simplified KSP interface for linear solvers
3138:    instead of working directly with matrix algebra routines such as this.
3139:    See, e.g., KSPCreate().
3141:    Level: developer
3143:    Concepts: matrices^Cholesky numeric factorization
3145: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3147:     Developer Note: fortran interface is not autogenerated as the f90
3148:     interface defintion cannot be generated correctly [due to MatFactorInfo]
3150: @*/
3151: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3152: {
3160:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3161:   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3162:   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);
3163:   MatCheckPreallocated(mat,2);
3165:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3166:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3167:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3168:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3169:   PetscObjectStateIncrease((PetscObject)fact);
3170:   return(0);
3171: }
3173: /* ----------------------------------------------------------------*/
3176: /*@
3177:    MatSolve - Solves A x = b, given a factored matrix.
3179:    Neighbor-wise Collective on Mat and Vec
3181:    Input Parameters:
3182: +  mat - the factored matrix
3183: -  b - the right-hand-side vector
3185:    Output Parameter:
3186: .  x - the result vector
3188:    Notes:
3189:    The vectors b and x cannot be the same.  I.e., one cannot
3190:    call MatSolve(A,x,x).
3192:    Notes:
3193:    Most users should employ the simplified KSP interface for linear solvers
3194:    instead of working directly with matrix algebra routines such as this.
3195:    See, e.g., KSPCreate().
3197:    Level: developer
3199:    Concepts: matrices^triangular solves
3201: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3202: @*/
3203: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3204: {
3214:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3215:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3216:   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);
3217:   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);
3218:   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);
3219:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3220:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3221:   MatCheckPreallocated(mat,1);
3223:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3224:   if (mat->errortype) {
3225:     PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3226:     VecSetInf(x);
3227:   } else {
3228:     (*mat->ops->solve)(mat,b,x);
3229:   }
3230:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3231:   PetscObjectStateIncrease((PetscObject)x);
3232:   return(0);
3233: }
3237: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3238: {
3240:   Vec            b,x;
3241:   PetscInt       m,N,i;
3242:   PetscScalar    *bb,*xx;
3243:   PetscBool      flg;
3246:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3247:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3248:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3249:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3251:   MatDenseGetArray(B,&bb);
3252:   MatDenseGetArray(X,&xx);
3253:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3254:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3255:   MatCreateVecs(A,&x,&b);
3256:   for (i=0; i<N; i++) {
3257:     VecPlaceArray(b,bb + i*m);
3258:     VecPlaceArray(x,xx + i*m);
3259:     MatSolve(A,b,x);
3260:     VecResetArray(x);
3261:     VecResetArray(b);
3262:   }
3263:   VecDestroy(&b);
3264:   VecDestroy(&x);
3265:   MatDenseRestoreArray(B,&bb);
3266:   MatDenseRestoreArray(X,&xx);
3267:   return(0);
3268: }
3272: /*@
3273:    MatMatSolve - Solves A X = B, given a factored matrix.
3275:    Neighbor-wise Collective on Mat
3277:    Input Parameters:
3278: +  A - the factored matrix
3279: -  B - the right-hand-side matrix  (dense matrix)
3281:    Output Parameter:
3282: .  X - the result matrix (dense matrix)
3284:    Notes:
3285:    The matrices b and x cannot be the same.  I.e., one cannot
3286:    call MatMatSolve(A,x,x).
3288:    Notes:
3289:    Most users should usually employ the simplified KSP interface for linear solvers
3290:    instead of working directly with matrix algebra routines such as this.
3291:    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3292:    at a time.
3294:    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3295:    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3297:    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3299:    Level: developer
3301:    Concepts: matrices^triangular solves
3303: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3304: @*/
3305: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3306: {
3316:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3317:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3318:   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);
3319:   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);
3320:   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);
3321:   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3322:   if (!A->rmap->N && !A->cmap->N) return(0);
3323:   MatCheckPreallocated(A,1);
3325:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3326:   if (!A->ops->matsolve) {
3327:     PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3328:     MatMatSolve_Basic(A,B,X);
3329:   } else {
3330:     (*A->ops->matsolve)(A,B,X);
3331:   }
3332:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3333:   PetscObjectStateIncrease((PetscObject)X);
3334:   return(0);
3335: }
3340: /*@
3341:    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3342:                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3344:    Neighbor-wise Collective on Mat and Vec
3346:    Input Parameters:
3347: +  mat - the factored matrix
3348: -  b - the right-hand-side vector
3350:    Output Parameter:
3351: .  x - the result vector
3353:    Notes:
3354:    MatSolve() should be used for most applications, as it performs
3355:    a forward solve followed by a backward solve.
3357:    The vectors b and x cannot be the same,  i.e., one cannot
3358:    call MatForwardSolve(A,x,x).
3360:    For matrix in seqsbaij format with block size larger than 1,
3361:    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3362:    MatForwardSolve() solves U^T*D y = b, and
3363:    MatBackwardSolve() solves U x = y.
3364:    Thus they do not provide a symmetric preconditioner.
3366:    Most users should employ the simplified KSP interface for linear solvers
3367:    instead of working directly with matrix algebra routines such as this.
3368:    See, e.g., KSPCreate().
3370:    Level: developer
3372:    Concepts: matrices^forward solves
3374: .seealso: MatSolve(), MatBackwardSolve()
3375: @*/
3376: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3377: {
3387:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3388:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3389:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3390:   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);
3391:   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);
3392:   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);
3393:   MatCheckPreallocated(mat,1);
3394:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3395:   (*mat->ops->forwardsolve)(mat,b,x);
3396:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3397:   PetscObjectStateIncrease((PetscObject)x);
3398:   return(0);
3399: }
3403: /*@
3404:    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3405:                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3407:    Neighbor-wise Collective on Mat and Vec
3409:    Input Parameters:
3410: +  mat - the factored matrix
3411: -  b - the right-hand-side vector
3413:    Output Parameter:
3414: .  x - the result vector
3416:    Notes:
3417:    MatSolve() should be used for most applications, as it performs
3418:    a forward solve followed by a backward solve.
3420:    The vectors b and x cannot be the same.  I.e., one cannot
3421:    call MatBackwardSolve(A,x,x).
3423:    For matrix in seqsbaij format with block size larger than 1,
3424:    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3425:    MatForwardSolve() solves U^T*D y = b, and
3426:    MatBackwardSolve() solves U x = y.
3427:    Thus they do not provide a symmetric preconditioner.
3429:    Most users should employ the simplified KSP interface for linear solvers
3430:    instead of working directly with matrix algebra routines such as this.
3431:    See, e.g., KSPCreate().
3433:    Level: developer
3435:    Concepts: matrices^backward solves
3437: .seealso: MatSolve(), MatForwardSolve()
3438: @*/
3439: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3440: {
3450:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3451:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3452:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3453:   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);
3454:   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);
3455:   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);
3456:   MatCheckPreallocated(mat,1);
3458:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3459:   (*mat->ops->backwardsolve)(mat,b,x);
3460:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3461:   PetscObjectStateIncrease((PetscObject)x);
3462:   return(0);
3463: }
3467: /*@
3468:    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3470:    Neighbor-wise Collective on Mat and Vec
3472:    Input Parameters:
3473: +  mat - the factored matrix
3474: .  b - the right-hand-side vector
3475: -  y - the vector to be added to
3477:    Output Parameter:
3478: .  x - the result vector
3480:    Notes:
3481:    The vectors b and x cannot be the same.  I.e., one cannot
3482:    call MatSolveAdd(A,x,y,x).
3484:    Most users should employ the simplified KSP interface for linear solvers
3485:    instead of working directly with matrix algebra routines such as this.
3486:    See, e.g., KSPCreate().
3488:    Level: developer
3490:    Concepts: matrices^triangular solves
3492: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3493: @*/
3494: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3495: {
3496:   PetscScalar    one = 1.0;
3497:   Vec            tmp;
3509:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3510:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3511:   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);
3512:   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);
3513:   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);
3514:   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);
3515:   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);
3516:   MatCheckPreallocated(mat,1);
3518:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3519:   if (mat->ops->solveadd) {
3520:     (*mat->ops->solveadd)(mat,b,y,x);
3521:   } else {
3522:     /* do the solve then the add manually */
3523:     if (x != y) {
3524:       MatSolve(mat,b,x);
3525:       VecAXPY(x,one,y);
3526:     } else {
3527:       VecDuplicate(x,&tmp);
3528:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3529:       VecCopy(x,tmp);
3530:       MatSolve(mat,b,x);
3531:       VecAXPY(x,one,tmp);
3532:       VecDestroy(&tmp);
3533:     }
3534:   }
3535:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3536:   PetscObjectStateIncrease((PetscObject)x);
3537:   return(0);
3538: }
3542: /*@
3543:    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3545:    Neighbor-wise Collective on Mat and Vec
3547:    Input Parameters:
3548: +  mat - the factored matrix
3549: -  b - the right-hand-side vector
3551:    Output Parameter:
3552: .  x - the result vector
3554:    Notes:
3555:    The vectors b and x cannot be the same.  I.e., one cannot
3556:    call MatSolveTranspose(A,x,x).
3558:    Most users should employ the simplified KSP interface for linear solvers
3559:    instead of working directly with matrix algebra routines such as this.
3560:    See, e.g., KSPCreate().
3562:    Level: developer
3564:    Concepts: matrices^triangular solves
3566: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3567: @*/
3568: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3569: {
3579:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3580:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3581:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3582:   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);
3583:   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);
3584:   MatCheckPreallocated(mat,1);
3585:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3586:   if (mat->errortype) {
3587:     PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3588:     VecSetInf(x);
3589:   } else {
3590:     (*mat->ops->solvetranspose)(mat,b,x);
3591:   }
3592:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3593:   PetscObjectStateIncrease((PetscObject)x);
3594:   return(0);
3595: }
3599: /*@
3600:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3601:                       factored matrix.
3603:    Neighbor-wise Collective on Mat and Vec
3605:    Input Parameters:
3606: +  mat - the factored matrix
3607: .  b - the right-hand-side vector
3608: -  y - the vector to be added to
3610:    Output Parameter:
3611: .  x - the result vector
3613:    Notes:
3614:    The vectors b and x cannot be the same.  I.e., one cannot
3615:    call MatSolveTransposeAdd(A,x,y,x).
3617:    Most users should employ the simplified KSP interface for linear solvers
3618:    instead of working directly with matrix algebra routines such as this.
3619:    See, e.g., KSPCreate().
3621:    Level: developer
3623:    Concepts: matrices^triangular solves
3625: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3626: @*/
3627: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3628: {
3629:   PetscScalar    one = 1.0;
3631:   Vec            tmp;
3642:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3643:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3644:   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);
3645:   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);
3646:   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);
3647:   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);
3648:   MatCheckPreallocated(mat,1);
3650:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3651:   if (mat->ops->solvetransposeadd) {
3652:     if (mat->errortype) {
3653:       PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3654:       VecSetInf(x);
3655:     } else {
3656:       (*mat->ops->solvetransposeadd)(mat,b,y,x);
3657:     }
3658:   } else {
3659:     /* do the solve then the add manually */
3660:     if (x != y) {
3661:       MatSolveTranspose(mat,b,x);
3662:       VecAXPY(x,one,y);
3663:     } else {
3664:       VecDuplicate(x,&tmp);
3665:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3666:       VecCopy(x,tmp);
3667:       MatSolveTranspose(mat,b,x);
3668:       VecAXPY(x,one,tmp);
3669:       VecDestroy(&tmp);
3670:     }
3671:   }
3672:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3673:   PetscObjectStateIncrease((PetscObject)x);
3674:   return(0);
3675: }
3676: /* ----------------------------------------------------------------*/
3680: /*@
3681:    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3683:    Neighbor-wise Collective on Mat and Vec
3685:    Input Parameters:
3686: +  mat - the matrix
3687: .  b - the right hand side
3688: .  omega - the relaxation factor
3689: .  flag - flag indicating the type of SOR (see below)
3690: .  shift -  diagonal shift
3691: .  its - the number of iterations
3692: -  lits - the number of local iterations
3694:    Output Parameters:
3695: .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3697:    SOR Flags:
3698: .     SOR_FORWARD_SWEEP - forward SOR
3699: .     SOR_BACKWARD_SWEEP - backward SOR
3700: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3701: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3702: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3703: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3704: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3705:          upper/lower triangular part of matrix to
3706:          vector (with omega)
3707: .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3709:    Notes:
3710:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3711:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3712:    on each processor.
3714:    Application programmers will not generally use MatSOR() directly,
3715:    but instead will employ the KSP/PC interface.
3717:    Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3719:    Notes for Advanced Users:
3720:    The flags are implemented as bitwise inclusive or operations.
3721:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3722:    to specify a zero initial guess for SSOR.
3724:    Most users should employ the simplified KSP interface for linear solvers
3725:    instead of working directly with matrix algebra routines such as this.
3726:    See, e.g., KSPCreate().
3728:    Vectors x and b CANNOT be the same
3730:    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3732:    Level: developer
3734:    Concepts: matrices^relaxation
3735:    Concepts: matrices^SOR
3736:    Concepts: matrices^Gauss-Seidel
3738: @*/
3739: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3740: {
3750:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3751:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3752:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3753:   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);
3754:   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);
3755:   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);
3756:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3757:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3758:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3760:   MatCheckPreallocated(mat,1);
3761:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3762:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3763:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3764:   PetscObjectStateIncrease((PetscObject)x);
3765:   return(0);
3766: }
3770: /*
3771:       Default matrix copy routine.
3772: */
3773: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3774: {
3775:   PetscErrorCode    ierr;
3776:   PetscInt          i,rstart = 0,rend = 0,nz;
3777:   const PetscInt    *cwork;
3778:   const PetscScalar *vwork;
3781:   if (B->assembled) {
3782:     MatZeroEntries(B);
3783:   }
3784:   MatGetOwnershipRange(A,&rstart,&rend);
3785:   for (i=rstart; i<rend; i++) {
3786:     MatGetRow(A,i,&nz,&cwork,&vwork);
3787:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3788:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3789:   }
3790:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3791:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3792:   PetscObjectStateIncrease((PetscObject)B);
3793:   return(0);
3794: }
3798: /*@
3799:    MatCopy - Copys a matrix to another matrix.
3801:    Collective on Mat
3803:    Input Parameters:
3804: +  A - the matrix
3805: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3807:    Output Parameter:
3808: .  B - where the copy is put
3810:    Notes:
3811:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3812:    same nonzero pattern or the routine will crash.
3814:    MatCopy() copies the matrix entries of a matrix to another existing
3815:    matrix (after first zeroing the second matrix).  A related routine is
3816:    MatConvert(), which first creates a new matrix and then copies the data.
3818:    Level: intermediate
3820:    Concepts: matrices^copying
3822: .seealso: MatConvert(), MatDuplicate()
3824: @*/
3825: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3826: {
3828:   PetscInt       i;
3836:   MatCheckPreallocated(B,2);
3837:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3838:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3839:   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);
3840:   MatCheckPreallocated(A,1);
3842:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3843:   if (A->ops->copy) {
3844:     (*A->ops->copy)(A,B,str);
3845:   } else { /* generic conversion */
3846:     MatCopy_Basic(A,B,str);
3847:   }
3849:   B->stencil.dim = A->stencil.dim;
3850:   B->stencil.noc = A->stencil.noc;
3851:   for (i=0; i<=A->stencil.dim; i++) {
3852:     B->stencil.dims[i]   = A->stencil.dims[i];
3853:     B->stencil.starts[i] = A->stencil.starts[i];
3854:   }
3856:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3857:   PetscObjectStateIncrease((PetscObject)B);
3858:   return(0);
3859: }
3863: /*@C
3864:    MatConvert - Converts a matrix to another matrix, either of the same
3865:    or different type.
3867:    Collective on Mat
3869:    Input Parameters:
3870: +  mat - the matrix
3871: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3872:    same type as the original matrix.
3873: -  reuse - denotes if the destination matrix is to be created or reused.
3874:    Use MAT_INPLACE_MATRIX for inplace conversion, otherwise use
3875:    MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX.
3877:    Output Parameter:
3878: .  M - pointer to place new matrix
3880:    Notes:
3881:    MatConvert() first creates a new matrix and then copies the data from
3882:    the first matrix.  A related routine is MatCopy(), which copies the matrix
3883:    entries of one matrix to another already existing matrix context.
3885:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3886:    the MPI communicator of the generated matrix is always the same as the communicator
3887:    of the input matrix.
3889:    Level: intermediate
3891:    Concepts: matrices^converting between storage formats
3893: .seealso: MatCopy(), MatDuplicate()
3894: @*/
3895: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3896: {
3898:   PetscBool      sametype,issame,flg;
3899:   char           convname[256],mtype[256];
3900:   Mat            B;
3906:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3907:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3908:   MatCheckPreallocated(mat,1);
3909:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);
3911:   PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3912:   if (flg) {
3913:     newtype = mtype;
3914:   }
3915:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3916:   PetscStrcmp(newtype,"same",&issame);
3917:   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
3919:   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) return(0);
3921:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3922:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3923:   } else {
3924:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3925:     const char     *prefix[3] = {"seq","mpi",""};
3926:     PetscInt       i;
3927:     /*
3928:        Order of precedence:
3929:        1) See if a specialized converter is known to the current matrix.
3930:        2) See if a specialized converter is known to the desired matrix class.
3931:        3) See if a good general converter is registered for the desired class
3932:           (as of 6/27/03 only MATMPIADJ falls into this category).
3933:        4) See if a good general converter is known for the current matrix.
3934:        5) Use a really basic converter.
3935:     */
3937:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3938:     for (i=0; i<3; i++) {
3939:       PetscStrcpy(convname,"MatConvert_");
3940:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3941:       PetscStrcat(convname,"_");
3942:       PetscStrcat(convname,prefix[i]);
3943:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3944:       PetscStrcat(convname,"_C");
3945:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3946:       if (conv) goto foundconv;
3947:     }
3949:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3950:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
3951:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3952:     MatSetType(B,newtype);
3953:     for (i=0; i<3; i++) {
3954:       PetscStrcpy(convname,"MatConvert_");
3955:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3956:       PetscStrcat(convname,"_");
3957:       PetscStrcat(convname,prefix[i]);
3958:       PetscStrcat(convname,newtype);
3959:       PetscStrcat(convname,"_C");
3960:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3961:       if (conv) {
3962:         MatDestroy(&B);
3963:         goto foundconv;
3964:       }
3965:     }
3967:     /* 3) See if a good general converter is registered for the desired class */
3968:     conv = B->ops->convertfrom;
3969:     MatDestroy(&B);
3970:     if (conv) goto foundconv;
3972:     /* 4) See if a good general converter is known for the current matrix */
3973:     if (mat->ops->convert) {
3974:       conv = mat->ops->convert;
3975:     }
3976:     if (conv) goto foundconv;
3978:     /* 5) Use a really basic converter. */
3979:     conv = MatConvert_Basic;
3981: foundconv:
3982:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3983:     (*conv)(mat,newtype,reuse,M);
3984:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3985:   }
3986:   PetscObjectStateIncrease((PetscObject)*M);
3988:   /* Copy Mat options */
3989:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3990:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3991:   return(0);
3992: }
3996: /*@C
3997:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3999:    Not Collective
4001:    Input Parameter:
4002: .  mat - the matrix, must be a factored matrix
4004:    Output Parameter:
4005: .   type - the string name of the package (do not free this string)
4007:    Notes:
4008:       In Fortran you pass in a empty string and the package name will be copied into it.
4009:     (Make sure the string is long enough)
4011:    Level: intermediate
4013: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4014: @*/
4015: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4016: {
4017:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
4022:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4023:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
4024:   if (!conv) {
4025:     *type = MATSOLVERPETSC;
4026:   } else {
4027:     (*conv)(mat,type);
4028:   }
4029:   return(0);
4030: }
4032: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4033: struct _MatSolverPackageForSpecifcType {
4034:   MatType                        mtype;
4035:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4036:   MatSolverPackageForSpecifcType next;
4037: };
4039: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4040: struct _MatSolverPackageHolder {
4041:   char                           *name;
4042:   MatSolverPackageForSpecifcType handlers;
4043:   MatSolverPackageHolder         next;
4044: };
4046: static MatSolverPackageHolder MatSolverPackageHolders = NULL;
4050: /*@C
4051:    MatSolvePackageRegister - Registers a MatSolverPackage that works for a particular matrix type
4053:    Input Parameters:
4054: +    package - name of the package, for example petsc or superlu
4055: .    mtype - the matrix type that works with this package
4056: .    ftype - the type of factorization supported by the package
4057: -    getfactor - routine that will create the factored matrix ready to be used
4059:     Level: intermediate
4061: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4062: @*/
4063: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4064: {
4065:   PetscErrorCode                 ierr;
4066:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4067:   PetscBool                      flg;
4068:   MatSolverPackageForSpecifcType inext,iprev = NULL;
4071:   if (!next) {
4072:     PetscNew(&MatSolverPackageHolders);
4073:     PetscStrallocpy(package,&MatSolverPackageHolders->name);
4074:     PetscNew(&MatSolverPackageHolders->handlers);
4075:     PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4076:     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4077:     return(0);
4078:   }
4079:   while (next) {
4080:     PetscStrcasecmp(package,next->name,&flg);
4081:     if (flg) {
4082:       inext = next->handlers;
4083:       while (inext) {
4084:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4085:         if (flg) {
4086:           inext->getfactor[(int)ftype-1] = getfactor;
4087:           return(0);
4088:         }
4089:         iprev = inext;
4090:         inext = inext->next;
4091:       }
4092:       PetscNew(&iprev->next);
4093:       PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4094:       iprev->next->getfactor[(int)ftype-1] = getfactor;
4095:       return(0);
4096:     }
4097:     prev = next;
4098:     next = next->next;
4099:   }
4100:   PetscNew(&prev->next);
4101:   PetscStrallocpy(package,&prev->next->name);
4102:   PetscNew(&prev->next->handlers);
4103:   PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4104:   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4105:   return(0);
4106: }
4110: /*@C
4111:    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4113:    Input Parameters:
4114: +    package - name of the package, for example petsc or superlu
4115: .    ftype - the type of factorization supported by the package
4116: -    mtype - the matrix type that works with this package
4118:    Output Parameters:
4119: +   foundpackage - PETSC_TRUE if the package was registered
4120: .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4121: -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4123:     Level: intermediate
4125: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4126: @*/
4127: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4128: {
4129:   PetscErrorCode                 ierr;
4130:   MatSolverPackageHolder         next = MatSolverPackageHolders;
4131:   PetscBool                      flg;
4132:   MatSolverPackageForSpecifcType inext;
4135:   if (foundpackage) *foundpackage = PETSC_FALSE;
4136:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4137:   if (getfactor)    *getfactor    = NULL;
4139:   if (package) {
4140:     while (next) {
4141:       PetscStrcasecmp(package,next->name,&flg);
4142:       if (flg) {
4143:         if (foundpackage) *foundpackage = PETSC_TRUE;
4144:         inext = next->handlers;
4145:         while (inext) {
4146:           PetscStrcasecmp(mtype,inext->mtype,&flg);
4147:           if (flg) {
4148:             if (foundmtype) *foundmtype = PETSC_TRUE;
4149:             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4150:             return(0);
4151:           }
4152:           inext = inext->next;
4153:         }
4154:       }
4155:       next = next->next;
4156:     }
4157:   } else {
4158:     while (next) {
4159:       inext = next->handlers;
4160:       while (inext) {
4161:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4162:         if (flg && inext->getfactor[(int)ftype-1]) {
4163:           if (foundpackage) *foundpackage = PETSC_TRUE;
4164:           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4165:           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4166:           return(0);
4167:         }
4168:         inext = inext->next;
4169:       }
4170:       next = next->next;
4171:     }
4172:   }
4173:   return(0);
4174: }
4178: PetscErrorCode MatSolverPackageDestroy(void)
4179: {
4180:   PetscErrorCode                 ierr;
4181:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4182:   MatSolverPackageForSpecifcType inext,iprev;
4185:   while (next) {
4186:     PetscFree(next->name);
4187:     inext = next->handlers;
4188:     while (inext) {
4189:       PetscFree(inext->mtype);
4190:       iprev = inext;
4191:       inext = inext->next;
4192:       PetscFree(iprev);
4193:     }
4194:     prev = next;
4195:     next = next->next;
4196:     PetscFree(prev);
4197:   }
4198:   MatSolverPackageHolders = NULL;
4199:   return(0);
4200: }
4204: /*@C
4205:    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4207:    Collective on Mat
4209:    Input Parameters:
4210: +  mat - the matrix
4211: .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4212: -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4214:    Output Parameters:
4215: .  f - the factor matrix used with MatXXFactorSymbolic() calls
4217:    Notes:
4218:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4219:      such as pastix, superlu, mumps etc.
4221:       PETSc must have been ./configure to use the external solver, using the option --download-package
4223:    Level: intermediate
4225: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4226: @*/
4227: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4228: {
4229:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4230:   PetscBool      foundpackage,foundmtype;
4236:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4237:   MatCheckPreallocated(mat,1);
4239:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4240:   if (!foundpackage) {
4241:     if (type) {
4242:       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4243:     } else {
4244:       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4245:     }
4246:   }
4247: 
4248:   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4249:   if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support factorization type %s for  matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4251:   (*conv)(mat,ftype,f);
4252:   return(0);
4253: }
4257: /*@C
4258:    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4260:    Not Collective
4262:    Input Parameters:
4263: +  mat - the matrix
4264: .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4265: -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4267:    Output Parameter:
4268: .    flg - PETSC_TRUE if the factorization is available
4270:    Notes:
4271:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4272:      such as pastix, superlu, mumps etc.
4274:       PETSc must have been ./configure to use the external solver, using the option --download-package
4276:    Level: intermediate
4278: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4279: @*/
4280: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4281: {
4282:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4288:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4289:   MatCheckPreallocated(mat,1);
4291:   *flg = PETSC_FALSE;
4292:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4293:   if (gconv) {
4294:     *flg = PETSC_TRUE;
4295:   }
4296:   return(0);
4297: }
4299: #include <petscdmtypes.h>
4303: /*@
4304:    MatDuplicate - Duplicates a matrix including the non-zero structure.
4306:    Collective on Mat
4308:    Input Parameters:
4309: +  mat - the matrix
4310: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4311:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4313:    Output Parameter:
4314: .  M - pointer to place new matrix
4316:    Level: intermediate
4318:    Concepts: matrices^duplicating
4320:     Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4322: .seealso: MatCopy(), MatConvert()
4323: @*/
4324: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4325: {
4327:   Mat            B;
4328:   PetscInt       i;
4329:   DM             dm;
4335:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4336:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4337:   MatCheckPreallocated(mat,1);
4339:   *M = 0;
4340:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4341:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4342:   (*mat->ops->duplicate)(mat,op,M);
4343:   B    = *M;
4345:   B->stencil.dim = mat->stencil.dim;
4346:   B->stencil.noc = mat->stencil.noc;
4347:   for (i=0; i<=mat->stencil.dim; i++) {
4348:     B->stencil.dims[i]   = mat->stencil.dims[i];
4349:     B->stencil.starts[i] = mat->stencil.starts[i];
4350:   }
4352:   B->nooffproczerorows = mat->nooffproczerorows;
4353:   B->nooffprocentries  = mat->nooffprocentries;
4355:   PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4356:   if (dm) {
4357:     PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4358:   }
4359:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4360:   PetscObjectStateIncrease((PetscObject)B);
4361:   return(0);
4362: }
4366: /*@
4367:    MatGetDiagonal - Gets the diagonal of a matrix.
4369:    Logically Collective on Mat and Vec
4371:    Input Parameters:
4372: +  mat - the matrix
4373: -  v - the vector for storing the diagonal
4375:    Output Parameter:
4376: .  v - the diagonal of the matrix
4378:    Level: intermediate
4380:    Note:
4381:    Currently only correct in parallel for square matrices.
4383:    Concepts: matrices^accessing diagonals
4385: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4386: @*/
4387: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4388: {
4395:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4396:   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4397:   MatCheckPreallocated(mat,1);
4399:   (*mat->ops->getdiagonal)(mat,v);
4400:   PetscObjectStateIncrease((PetscObject)v);
4401:   return(0);
4402: }
4406: /*@C
4407:    MatGetRowMin - Gets the minimum value (of the real part) of each
4408:         row of the matrix
4410:    Logically Collective on Mat and Vec
4412:    Input Parameters:
4413: .  mat - the matrix
4415:    Output Parameter:
4416: +  v - the vector for storing the maximums
4417: -  idx - the indices of the column found for each row (optional)
4419:    Level: intermediate
4421:    Notes: The result of this call are the same as if one converted the matrix to dense format
4422:       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4424:     This code is only implemented for a couple of matrix formats.
4426:    Concepts: matrices^getting row maximums
4428: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4429:           MatGetRowMax()
4430: @*/
4431: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4432: {
4439:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4440:   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4441:   MatCheckPreallocated(mat,1);
4443:   (*mat->ops->getrowmin)(mat,v,idx);
4444:   PetscObjectStateIncrease((PetscObject)v);
4445:   return(0);
4446: }
4450: /*@C
4451:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4452:         row of the matrix
4454:    Logically Collective on Mat and Vec
4456:    Input Parameters:
4457: .  mat - the matrix
4459:    Output Parameter:
4460: +  v - the vector for storing the minimums
4461: -  idx - the indices of the column found for each row (or NULL if not needed)
4463:    Level: intermediate
4465:    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4466:     row is 0 (the first column).
4468:     This code is only implemented for a couple of matrix formats.
4470:    Concepts: matrices^getting row maximums
4472: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4473: @*/
4474: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4475: {
4482:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4483:   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4484:   MatCheckPreallocated(mat,1);
4485:   if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4487:   (*mat->ops->getrowminabs)(mat,v,idx);
4488:   PetscObjectStateIncrease((PetscObject)v);
4489:   return(0);
4490: }
4494: /*@C
4495:    MatGetRowMax - Gets the maximum value (of the real part) of each
4496:         row of the matrix
4498:    Logically Collective on Mat and Vec
4500:    Input Parameters:
4501: .  mat - the matrix
4503:    Output Parameter:
4504: +  v - the vector for storing the maximums
4505: -  idx - the indices of the column found for each row (optional)
4507:    Level: intermediate
4509:    Notes: The result of this call are the same as if one converted the matrix to dense format
4510:       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4512:     This code is only implemented for a couple of matrix formats.
4514:    Concepts: matrices^getting row maximums
4516: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4517: @*/
4518: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4519: {
4526:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4527:   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4528:   MatCheckPreallocated(mat,1);
4530:   (*mat->ops->getrowmax)(mat,v,idx);
4531:   PetscObjectStateIncrease((PetscObject)v);
4532:   return(0);
4533: }
4537: /*@C
4538:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4539:         row of the matrix
4541:    Logically Collective on Mat and Vec
4543:    Input Parameters:
4544: .  mat - the matrix
4546:    Output Parameter:
4547: +  v - the vector for storing the maximums
4548: -  idx - the indices of the column found for each row (or NULL if not needed)
4550:    Level: intermediate
4552:    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4553:     row is 0 (the first column).
4555:     This code is only implemented for a couple of matrix formats.
4557:    Concepts: matrices^getting row maximums
4559: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4560: @*/
4561: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4562: {
4569:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4570:   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4571:   MatCheckPreallocated(mat,1);
4572:   if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4574:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4575:   PetscObjectStateIncrease((PetscObject)v);
4576:   return(0);
4577: }
4581: /*@
4582:    MatGetRowSum - Gets the sum of each row of the matrix
4584:    Logically Collective on Mat and Vec
4586:    Input Parameters:
4587: .  mat - the matrix
4589:    Output Parameter:
4590: .  v - the vector for storing the sum of rows
4592:    Level: intermediate
4594:    Notes: This code is slow since it is not currently specialized for different formats
4596:    Concepts: matrices^getting row sums
4598: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4599: @*/
4600: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4601: {
4602:   PetscInt       start = 0, end = 0, row;
4603:   PetscScalar    *array;
4610:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4611:   MatCheckPreallocated(mat,1);
4612:   MatGetOwnershipRange(mat, &start, &end);
4613:   VecGetArray(v, &array);
4614:   for (row = start; row < end; ++row) {
4615:     PetscInt          ncols, col;
4616:     const PetscInt    *cols;
4617:     const PetscScalar *vals;
4619:     array[row - start] = 0.0;
4621:     MatGetRow(mat, row, &ncols, &cols, &vals);
4622:     for (col = 0; col < ncols; col++) {
4623:       array[row - start] += vals[col];
4624:     }
4625:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4626:   }
4627:   VecRestoreArray(v, &array);
4628:   PetscObjectStateIncrease((PetscObject) v);
4629:   return(0);
4630: }
4634: /*@
4635:    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4637:    Collective on Mat
4639:    Input Parameter:
4640: +  mat - the matrix to transpose
4641: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4643:    Output Parameters:
4644: .  B - the transpose
4646:    Notes:
4647:      If you  pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4649:      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4651:    Level: intermediate
4653:    Concepts: matrices^transposing
4655: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4656: @*/
4657: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4658: {
4664:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4665:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4666:   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4667:   MatCheckPreallocated(mat,1);
4669:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4670:   (*mat->ops->transpose)(mat,reuse,B);
4671:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4672:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4673:   return(0);
4674: }
4678: /*@
4679:    MatIsTranspose - Test whether a matrix is another one's transpose,
4680:         or its own, in which case it tests symmetry.
4682:    Collective on Mat
4684:    Input Parameter:
4685: +  A - the matrix to test
4686: -  B - the matrix to test against, this can equal the first parameter
4688:    Output Parameters:
4689: .  flg - the result
4691:    Notes:
4692:    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4693:    has a running time of the order of the number of nonzeros; the parallel
4694:    test involves parallel copies of the block-offdiagonal parts of the matrix.
4696:    Level: intermediate
4698:    Concepts: matrices^transposing, matrix^symmetry
4700: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4701: @*/
4702: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4703: {
4704:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4710:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4711:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4712:   *flg = PETSC_FALSE;
4713:   if (f && g) {
4714:     if (f == g) {
4715:       (*f)(A,B,tol,flg);
4716:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4717:   } else {
4718:     MatType mattype;
4719:     if (!f) {
4720:       MatGetType(A,&mattype);
4721:     } else {
4722:       MatGetType(B,&mattype);
4723:     }
4724:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4725:   }
4726:   return(0);
4727: }
4731: /*@
4732:    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4734:    Collective on Mat
4736:    Input Parameter:
4737: +  mat - the matrix to transpose and complex conjugate
4738: -  reuse - store the transpose matrix in the provided B
4740:    Output Parameters:
4741: .  B - the Hermitian
4743:    Notes:
4744:      If you  pass in &mat for B the Hermitian will be done in place
4746:    Level: intermediate
4748:    Concepts: matrices^transposing, complex conjugatex
4750: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4751: @*/
4752: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4753: {
4757:   MatTranspose(mat,reuse,B);
4758: #if defined(PETSC_USE_COMPLEX)
4759:   MatConjugate(*B);
4760: #endif
4761:   return(0);
4762: }
4766: /*@
4767:    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4769:    Collective on Mat
4771:    Input Parameter:
4772: +  A - the matrix to test
4773: -  B - the matrix to test against, this can equal the first parameter
4775:    Output Parameters:
4776: .  flg - the result
4778:    Notes:
4779:    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4780:    has a running time of the order of the number of nonzeros; the parallel
4781:    test involves parallel copies of the block-offdiagonal parts of the matrix.
4783:    Level: intermediate
4785:    Concepts: matrices^transposing, matrix^symmetry
4787: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4788: @*/
4789: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4790: {
4791:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4797:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4798:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4799:   if (f && g) {
4800:     if (f==g) {
4801:       (*f)(A,B,tol,flg);
4802:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4803:   }
4804:   return(0);
4805: }
4809: /*@
4810:    MatPermute - Creates a new matrix with rows and columns permuted from the
4811:    original.
4813:    Collective on Mat
4815:    Input Parameters:
4816: +  mat - the matrix to permute
4817: .  row - row permutation, each processor supplies only the permutation for its rows
4818: -  col - column permutation, each processor supplies only the permutation for its columns
4820:    Output Parameters:
4821: .  B - the permuted matrix
4823:    Level: advanced
4825:    Note:
4826:    The index sets map from row/col of permuted matrix to row/col of original matrix.
4827:    The index sets should be on the same communicator as Mat and have the same local sizes.
4829:    Concepts: matrices^permuting
4831: .seealso: MatGetOrdering(), ISAllGather()
4833: @*/
4834: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4835: {
4844:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4845:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4846:   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4847:   MatCheckPreallocated(mat,1);
4849:   (*mat->ops->permute)(mat,row,col,B);
4850:   PetscObjectStateIncrease((PetscObject)*B);
4851:   return(0);
4852: }
4856: /*@
4857:    MatEqual - Compares two matrices.
4859:    Collective on Mat
4861:    Input Parameters:
4862: +  A - the first matrix
4863: -  B - the second matrix
4865:    Output Parameter:
4866: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4868:    Level: intermediate
4870:    Concepts: matrices^equality between
4871: @*/
4872: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4873: {
4883:   MatCheckPreallocated(B,2);
4884:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4885:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4886:   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);
4887:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4888:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4889:   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);
4890:   MatCheckPreallocated(A,1);
4892:   (*A->ops->equal)(A,B,flg);
4893:   return(0);
4894: }
4898: /*@
4899:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4900:    matrices that are stored as vectors.  Either of the two scaling
4901:    matrices can be NULL.
4903:    Collective on Mat
4905:    Input Parameters:
4906: +  mat - the matrix to be scaled
4907: .  l - the left scaling vector (or NULL)
4908: -  r - the right scaling vector (or NULL)
4910:    Notes:
4911:    MatDiagonalScale() computes A = LAR, where
4912:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4913:    The L scales the rows of the matrix, the R scales the columns of the matrix.
4915:    Level: intermediate
4917:    Concepts: matrices^diagonal scaling
4918:    Concepts: diagonal scaling of matrices
4920: .seealso: MatScale()
4921: @*/
4922: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4923: {
4929:   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4932:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4933:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4934:   MatCheckPreallocated(mat,1);
4936:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4937:   (*mat->ops->diagonalscale)(mat,l,r);
4938:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4939:   PetscObjectStateIncrease((PetscObject)mat);
4940: #if defined(PETSC_HAVE_CUSP)
4941:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4942:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4943:   }
4944: #elif defined(PETSC_HAVE_VIENNACL)
4945:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4946:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4947:   }
4948: #elif defined(PETSC_HAVE_VECCUDA)
4949:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4950:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4951:   }
4952: #endif
4953:   return(0);
4954: }
4958: /*@
4959:     MatScale - Scales all elements of a matrix by a given number.
4961:     Logically Collective on Mat
4963:     Input Parameters:
4964: +   mat - the matrix to be scaled
4965: -   a  - the scaling value
4967:     Output Parameter:
4968: .   mat - the scaled matrix
4970:     Level: intermediate
4972:     Concepts: matrices^scaling all entries
4974: .seealso: MatDiagonalScale()
4975: @*/
4976: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4977: {
4983:   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4984:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4985:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4987:   MatCheckPreallocated(mat,1);
4989:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4990:   if (a != (PetscScalar)1.0) {
4991:     (*mat->ops->scale)(mat,a);
4992:     PetscObjectStateIncrease((PetscObject)mat);
4993:   }
4994:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4995: #if defined(PETSC_HAVE_CUSP)
4996:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4997:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4998:   }
4999: #elif defined(PETSC_HAVE_VIENNACL)
5000:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5001:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5002:   }
5003: #elif defined(PETSC_HAVE_VECCUDA)
5004:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5005:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5006:   }
5007: #endif
5008:   return(0);
5009: }
5013: /*@
5014:    MatNorm - Calculates various norms of a matrix.
5016:    Collective on Mat
5018:    Input Parameters:
5019: +  mat - the matrix
5020: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5022:    Output Parameters:
5023: .  nrm - the resulting norm
5025:    Level: intermediate
5027:    Concepts: matrices^norm
5028:    Concepts: norm^of matrix
5029: @*/
5030: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5031: {
5039:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5040:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5041:   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5042:   MatCheckPreallocated(mat,1);
5044:   (*mat->ops->norm)(mat,type,nrm);
5045:   return(0);
5046: }
5048: /*
5049:      This variable is used to prevent counting of MatAssemblyBegin() that
5050:    are called from within a MatAssemblyEnd().
5051: */
5052: static PetscInt MatAssemblyEnd_InUse = 0;
5055: /*@
5056:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5057:    be called after completing all calls to MatSetValues().
5059:    Collective on Mat
5061:    Input Parameters:
5062: +  mat - the matrix
5063: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5065:    Notes:
5066:    MatSetValues() generally caches the values.  The matrix is ready to
5067:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5068:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5069:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5070:    using the matrix.
5072:    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5073:    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
5074:    a global collective operation requring all processes that share the matrix.
5076:    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5077:    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5078:    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5080:    Level: beginner
5082:    Concepts: matrices^assembling
5084: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5085: @*/
5086: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5087: {
5093:   MatCheckPreallocated(mat,1);
5094:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5095:   if (mat->assembled) {
5096:     mat->was_assembled = PETSC_TRUE;
5097:     mat->assembled     = PETSC_FALSE;
5098:   }
5099:   if (!MatAssemblyEnd_InUse) {
5100:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5101:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5102:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5103:   } else if (mat->ops->assemblybegin) {
5104:     (*mat->ops->assemblybegin)(mat,type);
5105:   }
5106:   return(0);
5107: }
5111: /*@
5112:    MatAssembled - Indicates if a matrix has been assembled and is ready for
5113:      use; for example, in matrix-vector product.
5115:    Not Collective
5117:    Input Parameter:
5118: .  mat - the matrix
5120:    Output Parameter:
5121: .  assembled - PETSC_TRUE or PETSC_FALSE
5123:    Level: advanced
5125:    Concepts: matrices^assembled?
5127: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5128: @*/
5129: PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5130: {
5135:   *assembled = mat->assembled;
5136:   return(0);
5137: }
5141: /*@
5142:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5143:    be called after MatAssemblyBegin().
5145:    Collective on Mat
5147:    Input Parameters:
5148: +  mat - the matrix
5149: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5151:    Options Database Keys:
5152: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5153: .  -mat_view ::ascii_info_detail - Prints more detailed info
5154: .  -mat_view - Prints matrix in ASCII format
5155: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5156: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5157: .  -display <name> - Sets display name (default is host)
5158: .  -draw_pause <sec> - Sets number of seconds to pause after display
5159: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 11 Using MATLAB with PETSc )
5160: .  -viewer_socket_machine <machine> - Machine to use for socket
5161: .  -viewer_socket_port <port> - Port number to use for socket
5162: -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5164:    Notes:
5165:    MatSetValues() generally caches the values.  The matrix is ready to
5166:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5167:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5168:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5169:    using the matrix.
5171:    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5172:    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5173:    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5175:    Level: beginner
5177: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5178: @*/
5179: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5180: {
5181:   PetscErrorCode  ierr;
5182:   static PetscInt inassm = 0;
5183:   PetscBool       flg    = PETSC_FALSE;
5189:   inassm++;
5190:   MatAssemblyEnd_InUse++;
5191:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5192:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5193:     if (mat->ops->assemblyend) {
5194:       (*mat->ops->assemblyend)(mat,type);
5195:     }
5196:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5197:   } else if (mat->ops->assemblyend) {
5198:     (*mat->ops->assemblyend)(mat,type);
5199:   }
5201:   /* Flush assembly is not a true assembly */
5202:   if (type != MAT_FLUSH_ASSEMBLY) {
5203:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5204:   }
5205:   mat->insertmode = NOT_SET_VALUES;
5206:   MatAssemblyEnd_InUse--;
5207:   PetscObjectStateIncrease((PetscObject)mat);
5208:   if (!mat->symmetric_eternal) {
5209:     mat->symmetric_set              = PETSC_FALSE;
5210:     mat->hermitian_set              = PETSC_FALSE;
5211:     mat->structurally_symmetric_set = PETSC_FALSE;
5212:   }
5213: #if defined(PETSC_HAVE_CUSP)
5214:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5215:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5216:   }
5217: #elif defined(PETSC_HAVE_VIENNACL)
5218:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5219:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5220:   }
5221: #elif defined(PETSC_HAVE_VECCUDA)
5222:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5223:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5224:   }
5225: #endif
5226:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5227:     MatViewFromOptions(mat,NULL,"-mat_view");
5229:     if (mat->checksymmetryonassembly) {
5230:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5231:       if (flg) {
5232:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5233:       } else {
5234:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5235:       }
5236:     }
5237:     if (mat->nullsp && mat->checknullspaceonassembly) {
5238:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5239:     }
5240:   }
5241:   inassm--;
5242:   return(0);
5243: }
5247: /*@
5248:    MatSetOption - Sets a parameter option for a matrix. Some options
5249:    may be specific to certain storage formats.  Some options
5250:    determine how values will be inserted (or added). Sorted,
5251:    row-oriented input will generally assemble the fastest. The default
5252:    is row-oriented.
5254:    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5256:    Input Parameters:
5257: +  mat - the matrix
5258: .  option - the option, one of those listed below (and possibly others),
5259: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5261:   Options Describing Matrix Structure:
5262: +    MAT_SPD - symmetric positive definite
5263: .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5264: .    MAT_HERMITIAN - transpose is the complex conjugation
5265: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5266: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5267:                             you set to be kept with all future use of the matrix
5268:                             including after MatAssemblyBegin/End() which could
5269:                             potentially change the symmetry structure, i.e. you
5270:                             KNOW the matrix will ALWAYS have the property you set.
5273:    Options For Use with MatSetValues():
5274:    Insert a logically dense subblock, which can be
5275: .    MAT_ROW_ORIENTED - row-oriented (default)
5277:    Note these options reflect the data you pass in with MatSetValues(); it has
5278:    nothing to do with how the data is stored internally in the matrix
5279:    data structure.
5281:    When (re)assembling a matrix, we can restrict the input for
5282:    efficiency/debugging purposes.  These options include:
5283: +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5284: .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5285: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5286: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5287: .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5288: .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5289:         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5290:         performance for very large process counts.
5291: -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5292:         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5293:         functions, instead sending only neighbor messages.
5295:    Notes:
5296:    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5298:    Some options are relevant only for particular matrix types and
5299:    are thus ignored by others.  Other options are not supported by
5300:    certain matrix types and will generate an error message if set.
5302:    If using a Fortran 77 module to compute a matrix, one may need to
5303:    use the column-oriented option (or convert to the row-oriented
5304:    format).
5306:    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5307:    that would generate a new entry in the nonzero structure is instead
5308:    ignored.  Thus, if memory has not alredy been allocated for this particular
5309:    data, then the insertion is ignored. For dense matrices, in which
5310:    the entire array is allocated, no entries are ever ignored.
5311:    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5313:    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5314:    that would generate a new entry in the nonzero structure instead produces
5315:    an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5317:    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5318:    that would generate a new entry that has not been preallocated will
5319:    instead produce an error. (Currently supported for AIJ and BAIJ formats
5320:    only.) This is a useful flag when debugging matrix memory preallocation.
5321:    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5323:    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5324:    other processors should be dropped, rather than stashed.
5325:    This is useful if you know that the "owning" processor is also
5326:    always generating the correct matrix entries, so that PETSc need
5327:    not transfer duplicate entries generated on another processor.
5329:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5330:    searches during matrix assembly. When this flag is set, the hash table
5331:    is created during the first Matrix Assembly. This hash table is
5332:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5333:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5334:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5335:    supported by MATMPIBAIJ format only.
5337:    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5338:    are kept in the nonzero structure
5340:    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5341:    a zero location in the matrix
5343:    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5345:    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5346:         zero row routines and thus improves performance for very large process counts.
5348:    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5349:         part of the matrix (since they should match the upper triangular part).
5351:    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5353:    Level: intermediate
5355:    Concepts: matrices^setting options
5357: .seealso:  MatOption, Mat
5359: @*/
5360: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5361: {
5367:   if (op > 0) {
5370:   }
5372:   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);
5373:   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()");
5375:   switch (op) {
5376:   case MAT_NO_OFF_PROC_ENTRIES:
5377:     mat->nooffprocentries = flg;
5378:     return(0);
5379:     break;
5380:   case MAT_SUBSET_OFF_PROC_ENTRIES:
5381:     mat->subsetoffprocentries = flg;
5382:     return(0);
5383:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5384:     mat->nooffproczerorows = flg;
5385:     return(0);
5386:     break;
5387:   case MAT_SPD:
5388:     mat->spd_set = PETSC_TRUE;
5389:     mat->spd     = flg;
5390:     if (flg) {
5391:       mat->symmetric                  = PETSC_TRUE;
5392:       mat->structurally_symmetric     = PETSC_TRUE;
5393:       mat->symmetric_set              = PETSC_TRUE;
5394:       mat->structurally_symmetric_set = PETSC_TRUE;
5395:     }
5396:     break;
5397:   case MAT_SYMMETRIC:
5398:     mat->symmetric = flg;
5399:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5400:     mat->symmetric_set              = PETSC_TRUE;
5401:     mat->structurally_symmetric_set = flg;
5402:     break;
5403:   case MAT_HERMITIAN:
5404:     mat->hermitian = flg;
5405:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5406:     mat->hermitian_set              = PETSC_TRUE;
5407:     mat->structurally_symmetric_set = flg;
5408:     break;
5409:   case MAT_STRUCTURALLY_SYMMETRIC:
5410:     mat->structurally_symmetric     = flg;
5411:     mat->structurally_symmetric_set = PETSC_TRUE;
5412:     break;
5413:   case MAT_SYMMETRY_ETERNAL:
5414:     mat->symmetric_eternal = flg;
5415:     break;
5416:   default:
5417:     break;
5418:   }
5419:   if (mat->ops->setoption) {
5420:     (*mat->ops->setoption)(mat,op,flg);
5421:   }
5422:   return(0);
5423: }
5427: /*@
5428:    MatGetOption - Gets a parameter option that has been set for a matrix.
5430:    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5432:    Input Parameters:
5433: +  mat - the matrix
5434: -  option - the option, this only responds to certain options, check the code for which ones
5436:    Output Parameter:
5437: .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5439:     Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5441:    Level: intermediate
5443:    Concepts: matrices^setting options
5445: .seealso:  MatOption, MatSetOption()
5447: @*/
5448: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5449: {
5454:   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);
5455:   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()");
5457:   switch (op) {
5458:   case MAT_NO_OFF_PROC_ENTRIES:
5459:     *flg = mat->nooffprocentries;
5460:     break;
5461:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5462:     *flg = mat->nooffproczerorows;
5463:     break;
5464:   case MAT_SYMMETRIC:
5465:     *flg = mat->symmetric;
5466:     break;
5467:   case MAT_HERMITIAN:
5468:     *flg = mat->hermitian;
5469:     break;
5470:   case MAT_STRUCTURALLY_SYMMETRIC:
5471:     *flg = mat->structurally_symmetric;
5472:     break;
5473:   case MAT_SYMMETRY_ETERNAL:
5474:     *flg = mat->symmetric_eternal;
5475:     break;
5476:   default:
5477:     break;
5478:   }
5479:   return(0);
5480: }
5484: /*@
5485:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5486:    this routine retains the old nonzero structure.
5488:    Logically Collective on Mat
5490:    Input Parameters:
5491: .  mat - the matrix
5493:    Level: intermediate
5495:    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.
5496:    See the Performance chapter of the users manual for information on preallocating matrices.
5498:    Concepts: matrices^zeroing
5500: .seealso: MatZeroRows()
5501: @*/
5502: PetscErrorCode MatZeroEntries(Mat mat)
5503: {
5509:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5510:   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");
5511:   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5512:   MatCheckPreallocated(mat,1);
5514:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5515:   (*mat->ops->zeroentries)(mat);
5516:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5517:   PetscObjectStateIncrease((PetscObject)mat);
5518: #if defined(PETSC_HAVE_CUSP)
5519:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5520:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5521:   }
5522: #elif defined(PETSC_HAVE_VIENNACL)
5523:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5524:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5525:   }
5526: #elif defined(PETSC_HAVE_VECCUDA)
5527:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5528:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5529:   }
5530: #endif
5531:   return(0);
5532: }
5536: /*@C
5537:    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5538:    of a set of rows and columns of a matrix.
5540:    Collective on Mat
5542:    Input Parameters:
5543: +  mat - the matrix
5544: .  numRows - the number of rows to remove
5545: .  rows - the global row indices
5546: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5547: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5548: -  b - optional vector of right hand side, that will be adjusted by provided solution
5550:    Notes:
5551:    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5553:    The user can set a value in the diagonal entry (or for the AIJ and
5554:    row formats can optionally remove the main diagonal entry from the
5555:    nonzero structure as well, by passing 0.0 as the final argument).
5557:    For the parallel case, all processes that share the matrix (i.e.,
5558:    those in the communicator used for matrix creation) MUST call this
5559:    routine, regardless of whether any rows being zeroed are owned by
5560:    them.
5562:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5563:    list only rows local to itself).
5565:    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5567:    Level: intermediate
5569:    Concepts: matrices^zeroing rows
5571: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5572: @*/
5573: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5574: {
5581:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5582:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5583:   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5584:   MatCheckPreallocated(mat,1);
5586:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5587:   MatViewFromOptions(mat,NULL,"-mat_view");
5588:   PetscObjectStateIncrease((PetscObject)mat);
5589: #if defined(PETSC_HAVE_CUSP)
5590:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5591:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5592:   }
5593: #elif defined(PETSC_HAVE_VIENNACL)
5594:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5595:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5596:   }
5597: #elif defined(PETSC_HAVE_VECCUDA)
5598:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5599:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5600:   }
5601: #endif
5602:   return(0);
5603: }
5607: /*@C
5608:    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5609:    of a set of rows and columns of a matrix.
5611:    Collective on Mat
5613:    Input Parameters:
5614: +  mat - the matrix
5615: .  is - the rows to zero
5616: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5617: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5618: -  b - optional vector of right hand side, that will be adjusted by provided solution
5620:    Notes:
5621:    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5623:    The user can set a value in the diagonal entry (or for the AIJ and
5624:    row formats can optionally remove the main diagonal entry from the
5625:    nonzero structure as well, by passing 0.0 as the final argument).
5627:    For the parallel case, all processes that share the matrix (i.e.,
5628:    those in the communicator used for matrix creation) MUST call this
5629:    routine, regardless of whether any rows being zeroed are owned by
5630:    them.
5632:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5633:    list only rows local to itself).
5635:    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5637:    Level: intermediate
5639:    Concepts: matrices^zeroing rows
5641: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5642: @*/
5643: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5644: {
5646:   PetscInt       numRows;
5647:   const PetscInt *rows;
5654:   ISGetLocalSize(is,&numRows);
5655:   ISGetIndices(is,&rows);
5656:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5657:   ISRestoreIndices(is,&rows);
5658:   return(0);
5659: }
5663: /*@C
5664:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5665:    of a set of rows of a matrix.
5667:    Collective on Mat
5669:    Input Parameters:
5670: +  mat - the matrix
5671: .  numRows - the number of rows to remove
5672: .  rows - the global row indices
5673: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5674: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5675: -  b - optional vector of right hand side, that will be adjusted by provided solution
5677:    Notes:
5678:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5679:    but does not release memory.  For the dense and block diagonal
5680:    formats this does not alter the nonzero structure.
5682:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5683:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5684:    merely zeroed.
5686:    The user can set a value in the diagonal entry (or for the AIJ and
5687:    row formats can optionally remove the main diagonal entry from the
5688:    nonzero structure as well, by passing 0.0 as the final argument).
5690:    For the parallel case, all processes that share the matrix (i.e.,
5691:    those in the communicator used for matrix creation) MUST call this
5692:    routine, regardless of whether any rows being zeroed are owned by
5693:    them.
5695:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5696:    list only rows local to itself).
5698:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5699:    owns that are to be zeroed. This saves a global synchronization in the implementation.
5701:    Level: intermediate
5703:    Concepts: matrices^zeroing rows
5705: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5706: @*/
5707: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5708: {
5715:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5716:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5717:   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5718:   MatCheckPreallocated(mat,1);
5720:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5721:   MatViewFromOptions(mat,NULL,"-mat_view");
5722:   PetscObjectStateIncrease((PetscObject)mat);
5723: #if defined(PETSC_HAVE_CUSP)
5724:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5725:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5726:   }
5727: #elif defined(PETSC_HAVE_VIENNACL)
5728:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5729:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5730:   }
5731: #elif defined(PETSC_HAVE_VECCUDA)
5732:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5733:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5734:   }
5735: #endif
5736:   return(0);
5737: }
5741: /*@C
5742:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5743:    of a set of rows of a matrix.
5745:    Collective on Mat
5747:    Input Parameters:
5748: +  mat - the matrix
5749: .  is - index set of rows to remove
5750: .  diag - value put in all diagonals of eliminated rows
5751: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5752: -  b - optional vector of right hand side, that will be adjusted by provided solution
5754:    Notes:
5755:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5756:    but does not release memory.  For the dense and block diagonal
5757:    formats this does not alter the nonzero structure.
5759:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5760:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5761:    merely zeroed.
5763:    The user can set a value in the diagonal entry (or for the AIJ and
5764:    row formats can optionally remove the main diagonal entry from the
5765:    nonzero structure as well, by passing 0.0 as the final argument).
5767:    For the parallel case, all processes that share the matrix (i.e.,
5768:    those in the communicator used for matrix creation) MUST call this
5769:    routine, regardless of whether any rows being zeroed are owned by
5770:    them.
5772:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5773:    list only rows local to itself).
5775:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5776:    owns that are to be zeroed. This saves a global synchronization in the implementation.
5778:    Level: intermediate
5780:    Concepts: matrices^zeroing rows
5782: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5783: @*/
5784: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5785: {
5786:   PetscInt       numRows;
5787:   const PetscInt *rows;
5794:   ISGetLocalSize(is,&numRows);
5795:   ISGetIndices(is,&rows);
5796:   MatZeroRows(mat,numRows,rows,diag,x,b);
5797:   ISRestoreIndices(is,&rows);
5798:   return(0);
5799: }
5803: /*@C
5804:    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5805:    of a set of rows of a matrix. These rows must be local to the process.
5807:    Collective on Mat
5809:    Input Parameters:
5810: +  mat - the matrix
5811: .  numRows - the number of rows to remove
5812: .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5813: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5814: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5815: -  b - optional vector of right hand side, that will be adjusted by provided solution
5817:    Notes:
5818:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5819:    but does not release memory.  For the dense and block diagonal
5820:    formats this does not alter the nonzero structure.
5822:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5823:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5824:    merely zeroed.
5826:    The user can set a value in the diagonal entry (or for the AIJ and
5827:    row formats can optionally remove the main diagonal entry from the
5828:    nonzero structure as well, by passing 0.0 as the final argument).
5830:    For the parallel case, all processes that share the matrix (i.e.,
5831:    those in the communicator used for matrix creation) MUST call this
5832:    routine, regardless of whether any rows being zeroed are owned by
5833:    them.
5835:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5836:    list only rows local to itself).
5838:    The grid coordinates are across the entire grid, not just the local portion
5840:    In Fortran idxm and idxn should be declared as
5841: $     MatStencil idxm(4,m)
5842:    and the values inserted using
5843: $    idxm(MatStencil_i,1) = i
5844: $    idxm(MatStencil_j,1) = j
5845: $    idxm(MatStencil_k,1) = k
5846: $    idxm(MatStencil_c,1) = c
5847:    etc
5849:    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5850:    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5851:    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5852:    DM_BOUNDARY_PERIODIC boundary type.
5854:    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
5855:    a single value per point) you can skip filling those indices.
5857:    Level: intermediate
5859:    Concepts: matrices^zeroing rows
5861: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5862: @*/
5863: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5864: {
5865:   PetscInt       dim     = mat->stencil.dim;
5866:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5867:   PetscInt       *dims   = mat->stencil.dims+1;
5868:   PetscInt       *starts = mat->stencil.starts;
5869:   PetscInt       *dxm    = (PetscInt*) rows;
5870:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5878:   PetscMalloc1(numRows, &jdxm);
5879:   for (i = 0; i < numRows; ++i) {
5880:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5881:     for (j = 0; j < 3-sdim; ++j) dxm++;
5882:     /* Local index in X dir */
5883:     tmp = *dxm++ - starts[0];
5884:     /* Loop over remaining dimensions */
5885:     for (j = 0; j < dim-1; ++j) {
5886:       /* If nonlocal, set index to be negative */
5887:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5888:       /* Update local index */
5889:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5890:     }
5891:     /* Skip component slot if necessary */
5892:     if (mat->stencil.noc) dxm++;
5893:     /* Local row number */
5894:     if (tmp >= 0) {
5895:       jdxm[numNewRows++] = tmp;
5896:     }
5897:   }
5898:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5899:   PetscFree(jdxm);
5900:   return(0);
5901: }
5905: /*@C
5906:    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5907:    of a set of rows and columns of a matrix.
5909:    Collective on Mat
5911:    Input Parameters:
5912: +  mat - the matrix
5913: .  numRows - the number of rows/columns to remove
5914: .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5915: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5916: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5917: -  b - optional vector of right hand side, that will be adjusted by provided solution
5919:    Notes:
5920:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5921:    but does not release memory.  For the dense and block diagonal
5922:    formats this does not alter the nonzero structure.
5924:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5925:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5926:    merely zeroed.
5928:    The user can set a value in the diagonal entry (or for the AIJ and
5929:    row formats can optionally remove the main diagonal entry from the
5930:    nonzero structure as well, by passing 0.0 as the final argument).
5932:    For the parallel case, all processes that share the matrix (i.e.,
5933:    those in the communicator used for matrix creation) MUST call this
5934:    routine, regardless of whether any rows being zeroed are owned by
5935:    them.
5937:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5938:    list only rows local to itself, but the row/column numbers are given in local numbering).
5940:    The grid coordinates are across the entire grid, not just the local portion
5942:    In Fortran idxm and idxn should be declared as
5943: $     MatStencil idxm(4,m)
5944:    and the values inserted using
5945: $    idxm(MatStencil_i,1) = i
5946: $    idxm(MatStencil_j,1) = j
5947: $    idxm(MatStencil_k,1) = k
5948: $    idxm(MatStencil_c,1) = c
5949:    etc
5951:    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5952:    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5953:    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5954:    DM_BOUNDARY_PERIODIC boundary type.
5956:    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
5957:    a single value per point) you can skip filling those indices.
5959:    Level: intermediate
5961:    Concepts: matrices^zeroing rows
5963: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5964: @*/
5965: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5966: {
5967:   PetscInt       dim     = mat->stencil.dim;
5968:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5969:   PetscInt       *dims   = mat->stencil.dims+1;
5970:   PetscInt       *starts = mat->stencil.starts;
5971:   PetscInt       *dxm    = (PetscInt*) rows;
5972:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5980:   PetscMalloc1(numRows, &jdxm);
5981:   for (i = 0; i < numRows; ++i) {
5982:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5983:     for (j = 0; j < 3-sdim; ++j) dxm++;
5984:     /* Local index in X dir */
5985:     tmp = *dxm++ - starts[0];
5986:     /* Loop over remaining dimensions */
5987:     for (j = 0; j < dim-1; ++j) {
5988:       /* If nonlocal, set index to be negative */
5989:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5990:       /* Update local index */
5991:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5992:     }
5993:     /* Skip component slot if necessary */
5994:     if (mat->stencil.noc) dxm++;
5995:     /* Local row number */
5996:     if (tmp >= 0) {
5997:       jdxm[numNewRows++] = tmp;
5998:     }
5999:   }
6000:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
6001:   PetscFree(jdxm);
6002:   return(0);
6003: }
6007: /*@C
6008:    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6009:    of a set of rows of a matrix; using local numbering of rows.
6011:    Collective on Mat
6013:    Input Parameters:
6014: +  mat - the matrix
6015: .  numRows - the number of rows to remove
6016: .  rows - the global row indices
6017: .  diag - value put in all diagonals of eliminated rows
6018: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6019: -  b - optional vector of right hand side, that will be adjusted by provided solution
6021:    Notes:
6022:    Before calling MatZeroRowsLocal(), the user must first set the
6023:    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6025:    For the AIJ matrix formats this removes the old nonzero structure,
6026:    but does not release memory.  For the dense and block diagonal
6027:    formats this does not alter the nonzero structure.
6029:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6030:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6031:    merely zeroed.
6033:    The user can set a value in the diagonal entry (or for the AIJ and
6034:    row formats can optionally remove the main diagonal entry from the
6035:    nonzero structure as well, by passing 0.0 as the final argument).
6037:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6038:    owns that are to be zeroed. This saves a global synchronization in the implementation.
6040:    Level: intermediate
6042:    Concepts: matrices^zeroing
6044: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6045: @*/
6046: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6047: {
6054:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6055:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6056:   MatCheckPreallocated(mat,1);
6058:   if (mat->ops->zerorowslocal) {
6059:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6060:   } else {
6061:     IS             is, newis;
6062:     const PetscInt *newRows;
6064:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6065:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6066:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6067:     ISGetIndices(newis,&newRows);
6068:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6069:     ISRestoreIndices(newis,&newRows);
6070:     ISDestroy(&newis);
6071:     ISDestroy(&is);
6072:   }
6073:   PetscObjectStateIncrease((PetscObject)mat);
6074: #if defined(PETSC_HAVE_CUSP)
6075:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6076:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6077:   }
6078: #elif defined(PETSC_HAVE_VIENNACL)
6079:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6080:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6081:   }
6082: #elif defined(PETSC_HAVE_VECCUDA)
6083:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6084:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6085:   }
6086: #endif
6087:   return(0);
6088: }
6092: /*@C
6093:    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6094:    of a set of rows of a matrix; using local numbering of rows.
6096:    Collective on Mat
6098:    Input Parameters:
6099: +  mat - the matrix
6100: .  is - index set of rows to remove
6101: .  diag - value put in all diagonals of eliminated rows
6102: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6103: -  b - optional vector of right hand side, that will be adjusted by provided solution
6105:    Notes:
6106:    Before calling MatZeroRowsLocalIS(), the user must first set the
6107:    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6109:    For the AIJ matrix formats this removes the old nonzero structure,
6110:    but does not release memory.  For the dense and block diagonal
6111:    formats this does not alter the nonzero structure.
6113:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6114:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6115:    merely zeroed.
6117:    The user can set a value in the diagonal entry (or for the AIJ and
6118:    row formats can optionally remove the main diagonal entry from the
6119:    nonzero structure as well, by passing 0.0 as the final argument).
6121:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6122:    owns that are to be zeroed. This saves a global synchronization in the implementation.
6124:    Level: intermediate
6126:    Concepts: matrices^zeroing
6128: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6129: @*/
6130: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6131: {
6133:   PetscInt       numRows;
6134:   const PetscInt *rows;
6140:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6141:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6142:   MatCheckPreallocated(mat,1);
6144:   ISGetLocalSize(is,&numRows);
6145:   ISGetIndices(is,&rows);
6146:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6147:   ISRestoreIndices(is,&rows);
6148:   return(0);
6149: }
6153: /*@C
6154:    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6155:    of a set of rows and columns of a matrix; using local numbering of rows.
6157:    Collective on Mat
6159:    Input Parameters:
6160: +  mat - the matrix
6161: .  numRows - the number of rows to remove
6162: .  rows - the global row indices
6163: .  diag - value put in all diagonals of eliminated rows
6164: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6165: -  b - optional vector of right hand side, that will be adjusted by provided solution
6167:    Notes:
6168:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6169:    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6171:    The user can set a value in the diagonal entry (or for the AIJ and
6172:    row formats can optionally remove the main diagonal entry from the
6173:    nonzero structure as well, by passing 0.0 as the final argument).
6175:    Level: intermediate
6177:    Concepts: matrices^zeroing
6179: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6180: @*/
6181: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6182: {
6184:   IS             is, newis;
6185:   const PetscInt *newRows;
6191:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6192:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6193:   MatCheckPreallocated(mat,1);
6195:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6196:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6197:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6198:   ISGetIndices(newis,&newRows);
6199:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6200:   ISRestoreIndices(newis,&newRows);
6201:   ISDestroy(&newis);
6202:   ISDestroy(&is);
6203:   PetscObjectStateIncrease((PetscObject)mat);
6204: #if defined(PETSC_HAVE_CUSP)
6205:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6206:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6207:   }
6208: #elif defined(PETSC_HAVE_VIENNACL)
6209:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6210:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6211:   }
6212: #elif defined(PETSC_HAVE_VECCUDA)
6213:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6214:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6215:   }
6216: #endif
6217:   return(0);
6218: }
6222: /*@C
6223:    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6224:    of a set of rows and columns of a matrix; using local numbering of rows.
6226:    Collective on Mat
6228:    Input Parameters:
6229: +  mat - the matrix
6230: .  is - index set of rows to remove
6231: .  diag - value put in all diagonals of eliminated rows
6232: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6233: -  b - optional vector of right hand side, that will be adjusted by provided solution
6235:    Notes:
6236:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6237:    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6239:    The user can set a value in the diagonal entry (or for the AIJ and
6240:    row formats can optionally remove the main diagonal entry from the
6241:    nonzero structure as well, by passing 0.0 as the final argument).
6243:    Level: intermediate
6245:    Concepts: matrices^zeroing
6247: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6248: @*/
6249: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6250: {
6252:   PetscInt       numRows;
6253:   const PetscInt *rows;
6259:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6260:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6261:   MatCheckPreallocated(mat,1);
6263:   ISGetLocalSize(is,&numRows);
6264:   ISGetIndices(is,&rows);
6265:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6266:   ISRestoreIndices(is,&rows);
6267:   return(0);
6268: }
6272: /*@
6273:    MatGetSize - Returns the numbers of rows and columns in a matrix.
6275:    Not Collective
6277:    Input Parameter:
6278: .  mat - the matrix
6280:    Output Parameters:
6281: +  m - the number of global rows
6282: -  n - the number of global columns
6284:    Note: both output parameters can be NULL on input.
6286:    Level: beginner
6288:    Concepts: matrices^size
6290: .seealso: MatGetLocalSize()
6291: @*/
6292: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6293: {
6296:   if (m) *m = mat->rmap->N;
6297:   if (n) *n = mat->cmap->N;
6298:   return(0);
6299: }
6303: /*@
6304:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6305:    stored locally.  This information may be implementation dependent, so
6306:    use with care.
6308:    Not Collective
6310:    Input Parameters:
6311: .  mat - the matrix
6313:    Output Parameters:
6314: +  m - the number of local rows
6315: -  n - the number of local columns
6317:    Note: both output parameters can be NULL on input.
6319:    Level: beginner
6321:    Concepts: matrices^local size
6323: .seealso: MatGetSize()
6324: @*/
6325: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6326: {
6331:   if (m) *m = mat->rmap->n;
6332:   if (n) *n = mat->cmap->n;
6333:   return(0);
6334: }
6338: /*@
6339:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6340:    this processor. (The columns of the "diagonal block")
6342:    Not Collective, unless matrix has not been allocated, then collective on Mat
6344:    Input Parameters:
6345: .  mat - the matrix
6347:    Output Parameters:
6348: +  m - the global index of the first local column
6349: -  n - one more than the global index of the last local column
6351:    Notes: both output parameters can be NULL on input.
6353:    Level: developer
6355:    Concepts: matrices^column ownership
6357: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6359: @*/
6360: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6361: {
6367:   MatCheckPreallocated(mat,1);
6368:   if (m) *m = mat->cmap->rstart;
6369:   if (n) *n = mat->cmap->rend;
6370:   return(0);
6371: }
6375: /*@
6376:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6377:    this processor, assuming that the matrix is laid out with the first
6378:    n1 rows on the first processor, the next n2 rows on the second, etc.
6379:    For certain parallel layouts this range may not be well defined.
6381:    Not Collective
6383:    Input Parameters:
6384: .  mat - the matrix
6386:    Output Parameters:
6387: +  m - the global index of the first local row
6388: -  n - one more than the global index of the last local row
6390:    Note: Both output parameters can be NULL on input.
6391: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6392: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6393: $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6395:    Level: beginner
6397:    Concepts: matrices^row ownership
6399: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6401: @*/
6402: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6403: {
6409:   MatCheckPreallocated(mat,1);
6410:   if (m) *m = mat->rmap->rstart;
6411:   if (n) *n = mat->rmap->rend;
6412:   return(0);
6413: }
6417: /*@C
6418:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6419:    each process
6421:    Not Collective, unless matrix has not been allocated, then collective on Mat
6423:    Input Parameters:
6424: .  mat - the matrix
6426:    Output Parameters:
6427: .  ranges - start of each processors portion plus one more than the total length at the end
6429:    Level: beginner
6431:    Concepts: matrices^row ownership
6433: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6435: @*/
6436: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6437: {
6443:   MatCheckPreallocated(mat,1);
6444:   PetscLayoutGetRanges(mat->rmap,ranges);
6445:   return(0);
6446: }
6450: /*@C
6451:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6452:    this processor. (The columns of the "diagonal blocks" for each process)
6454:    Not Collective, unless matrix has not been allocated, then collective on Mat
6456:    Input Parameters:
6457: .  mat - the matrix
6459:    Output Parameters:
6460: .  ranges - start of each processors portion plus one more then the total length at the end
6462:    Level: beginner
6464:    Concepts: matrices^column ownership
6466: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6468: @*/
6469: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6470: {
6476:   MatCheckPreallocated(mat,1);
6477:   PetscLayoutGetRanges(mat->cmap,ranges);
6478:   return(0);
6479: }
6483: /*@C
6484:    MatGetOwnershipIS - Get row and column ownership as index sets
6486:    Not Collective
6488:    Input Arguments:
6489: .  A - matrix of type Elemental
6491:    Output Arguments:
6492: +  rows - rows in which this process owns elements
6493: .  cols - columns in which this process owns elements
6495:    Level: intermediate
6497: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6498: @*/
6499: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6500: {
6501:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6504:   MatCheckPreallocated(A,1);
6505:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6506:   if (f) {
6507:     (*f)(A,rows,cols);
6508:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6509:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6510:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6511:   }
6512:   return(0);
6513: }
6517: /*@C
6518:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6519:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6520:    to complete the factorization.
6522:    Collective on Mat
6524:    Input Parameters:
6525: +  mat - the matrix
6526: .  row - row permutation
6527: .  column - column permutation
6528: -  info - structure containing
6529: $      levels - number of levels of fill.
6530: $      expected fill - as ratio of original fill.
6531: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6532:                 missing diagonal entries)
6534:    Output Parameters:
6535: .  fact - new matrix that has been symbolically factored
6537:    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6539:    Most users should employ the simplified KSP interface for linear solvers
6540:    instead of working directly with matrix algebra routines such as this.
6541:    See, e.g., KSPCreate().
6543:    Level: developer
6545:   Concepts: matrices^symbolic LU factorization
6546:   Concepts: matrices^factorization
6547:   Concepts: LU^symbolic factorization
6549: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6550:           MatGetOrdering(), MatFactorInfo
6552:     Developer Note: fortran interface is not autogenerated as the f90
6553:     interface defintion cannot be generated correctly [due to MatFactorInfo]
6555: @*/
6556: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6557: {
6567:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6568:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6569:   if (!(fact)->ops->ilufactorsymbolic) {
6570:     const MatSolverPackage spackage;
6571:     MatFactorGetSolverPackage(fact,&spackage);
6572:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6573:   }
6574:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6575:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6576:   MatCheckPreallocated(mat,2);
6578:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6579:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6580:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6581:   return(0);
6582: }
6586: /*@C
6587:    MatICCFactorSymbolic - Performs symbolic incomplete
6588:    Cholesky factorization for a symmetric matrix.  Use
6589:    MatCholeskyFactorNumeric() to complete the factorization.
6591:    Collective on Mat
6593:    Input Parameters:
6594: +  mat - the matrix
6595: .  perm - row and column permutation
6596: -  info - structure containing
6597: $      levels - number of levels of fill.
6598: $      expected fill - as ratio of original fill.
6600:    Output Parameter:
6601: .  fact - the factored matrix
6603:    Notes:
6604:    Most users should employ the KSP interface for linear solvers
6605:    instead of working directly with matrix algebra routines such as this.
6606:    See, e.g., KSPCreate().
6608:    Level: developer
6610:   Concepts: matrices^symbolic incomplete Cholesky factorization
6611:   Concepts: matrices^factorization
6612:   Concepts: Cholsky^symbolic factorization
6614: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6616:     Developer Note: fortran interface is not autogenerated as the f90
6617:     interface defintion cannot be generated correctly [due to MatFactorInfo]
6619: @*/
6620: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6621: {
6630:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6631:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6632:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6633:   if (!(fact)->ops->iccfactorsymbolic) {
6634:     const MatSolverPackage spackage;
6635:     MatFactorGetSolverPackage(fact,&spackage);
6636:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6637:   }
6638:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6639:   MatCheckPreallocated(mat,2);
6641:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6642:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6643:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6644:   return(0);
6645: }
6649: /*@C
6650:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6651:    points to an array of valid matrices, they may be reused to store the new
6652:    submatrices.
6654:    Collective on Mat
6656:    Input Parameters:
6657: +  mat - the matrix
6658: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6659: .  irow, icol - index sets of rows and columns to extract
6660: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6662:    Output Parameter:
6663: .  submat - the array of submatrices
6665:    Notes:
6666:    MatGetSubMatrices() can extract ONLY sequential submatrices
6667:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6668:    to extract a parallel submatrix.
6670:    Some matrix types place restrictions on the row and column
6671:    indices, such as that they be sorted or that they be equal to each other.
6673:    The index sets may not have duplicate entries.
6675:    When extracting submatrices from a parallel matrix, each processor can
6676:    form a different submatrix by setting the rows and columns of its
6677:    individual index sets according to the local submatrix desired.
6679:    When finished using the submatrices, the user should destroy
6680:    them with MatDestroyMatrices().
6682:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6683:    original matrix has not changed from that last call to MatGetSubMatrices().
6685:    This routine creates the matrices in submat; you should NOT create them before
6686:    calling it. It also allocates the array of matrix pointers submat.
6688:    For BAIJ matrices the index sets must respect the block structure, that is if they
6689:    request one row/column in a block, they must request all rows/columns that are in
6690:    that block. For example, if the block size is 2 you cannot request just row 0 and
6691:    column 0.
6693:    Fortran Note:
6694:    The Fortran interface is slightly different from that given below; it
6695:    requires one to pass in  as submat a Mat (integer) array of size at least m.
6697:    Level: advanced
6699:    Concepts: matrices^accessing submatrices
6700:    Concepts: submatrices
6702: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6703: @*/
6704: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6705: {
6707:   PetscInt       i;
6708:   PetscBool      eq;
6713:   if (n) {
6718:   }
6720:   if (n && scall == MAT_REUSE_MATRIX) {
6723:   }
6724:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6725:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6726:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6727:   MatCheckPreallocated(mat,1);
6729:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6730:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6731:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6732:   for (i=0; i<n; i++) {
6733:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6734:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6735:       ISEqual(irow[i],icol[i],&eq);
6736:       if (eq) {
6737:         if (mat->symmetric) {
6738:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6739:         } else if (mat->hermitian) {
6740:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6741:         } else if (mat->structurally_symmetric) {
6742:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6743:         }
6744:       }
6745:     }
6746:   }
6747:   return(0);
6748: }
6752: PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6753: {
6755:   PetscInt       i;
6756:   PetscBool      eq;
6761:   if (n) {
6766:   }
6768:   if (n && scall == MAT_REUSE_MATRIX) {
6771:   }
6772:   if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6773:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6774:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6775:   MatCheckPreallocated(mat,1);
6777:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6778:   (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6779:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6780:   for (i=0; i<n; i++) {
6781:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6782:       ISEqual(irow[i],icol[i],&eq);
6783:       if (eq) {
6784:         if (mat->symmetric) {
6785:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6786:         } else if (mat->hermitian) {
6787:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6788:         } else if (mat->structurally_symmetric) {
6789:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6790:         }
6791:       }
6792:     }
6793:   }
6794:   return(0);
6795: }
6799: /*@C
6800:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6802:    Collective on Mat
6804:    Input Parameters:
6805: +  n - the number of local matrices
6806: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6807:                        sequence of MatGetSubMatrices())
6809:    Level: advanced
6811:     Notes: Frees not only the matrices, but also the array that contains the matrices
6812:            In Fortran will not free the array.
6814: .seealso: MatGetSubMatrices()
6815: @*/
6816: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6817: {
6819:   PetscInt       i;
6822:   if (!*mat) return(0);
6823:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6825:   for (i=0; i<n; i++) {
6826:     MatDestroy(&(*mat)[i]);
6827:   }
6828:   /* memory is allocated even if n = 0 */
6829:   PetscFree(*mat);
6830:   *mat = NULL;
6831:   return(0);
6832: }
6836: /*@C
6837:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6839:    Collective on Mat
6841:    Input Parameters:
6842: .  mat - the matrix
6844:    Output Parameter:
6845: .  matstruct - the sequential matrix with the nonzero structure of mat
6847:   Level: intermediate
6849: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6850: @*/
6851: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6852: {
6860:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6861:   MatCheckPreallocated(mat,1);
6863:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6864:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6865:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6866:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6867:   return(0);
6868: }
6872: /*@C
6873:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6875:    Collective on Mat
6877:    Input Parameters:
6878: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6879:                        sequence of MatGetSequentialNonzeroStructure())
6881:    Level: advanced
6883:     Notes: Frees not only the matrices, but also the array that contains the matrices
6885: .seealso: MatGetSeqNonzeroStructure()
6886: @*/
6887: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6888: {
6893:   MatDestroy(mat);
6894:   return(0);
6895: }
6899: /*@
6900:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6901:    replaces the index sets by larger ones that represent submatrices with
6902:    additional overlap.
6904:    Collective on Mat
6906:    Input Parameters:
6907: +  mat - the matrix
6908: .  n   - the number of index sets
6909: .  is  - the array of index sets (these index sets will changed during the call)
6910: -  ov  - the additional overlap requested
6912:    Options Database:
6913: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6915:    Level: developer
6917:    Concepts: overlap
6918:    Concepts: ASM^computing overlap
6920: .seealso: MatGetSubMatrices()
6921: @*/
6922: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6923: {
6929:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6930:   if (n) {
6933:   }
6934:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6935:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6936:   MatCheckPreallocated(mat,1);
6938:   if (!ov) return(0);
6939:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6940:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6941:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6942:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6943:   return(0);
6944: }
6947: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6951: /*@
6952:    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6953:    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6954:    additional overlap.
6956:    Collective on Mat
6958:    Input Parameters:
6959: +  mat - the matrix
6960: .  n   - the number of index sets
6961: .  is  - the array of index sets (these index sets will changed during the call)
6962: -  ov  - the additional overlap requested
6964:    Options Database:
6965: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6967:    Level: developer
6969:    Concepts: overlap
6970:    Concepts: ASM^computing overlap
6972: .seealso: MatGetSubMatrices()
6973: @*/
6974: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6975: {
6976:   PetscInt       i;
6982:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6983:   if (n) {
6986:   }
6987:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6988:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6989:   MatCheckPreallocated(mat,1);
6990:   if (!ov) return(0);
6991:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6992:   for(i=0; i<n; i++){
6993:          MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
6994:   }
6995:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6996:   return(0);
6997: }
7004: /*@
7005:    MatGetBlockSize - Returns the matrix block size.
7007:    Not Collective
7009:    Input Parameter:
7010: .  mat - the matrix
7012:    Output Parameter:
7013: .  bs - block size
7015:    Notes:
7016:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7018:    If the block size has not been set yet this routine returns 1.
7020:    Level: intermediate
7022:    Concepts: matrices^block size
7024: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7025: @*/
7026: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7027: {
7031:   *bs = PetscAbs(mat->rmap->bs);
7032:   return(0);
7033: }
7037: /*@
7038:    MatGetBlockSizes - Returns the matrix block row and column sizes.
7040:    Not Collective
7042:    Input Parameter:
7043: .  mat - the matrix
7045:    Output Parameter:
7046: .  rbs - row block size
7047: .  cbs - coumn block size
7049:    Notes:
7050:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7051:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7053:    If a block size has not been set yet this routine returns 1.
7055:    Level: intermediate
7057:    Concepts: matrices^block size
7059: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7060: @*/
7061: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7062: {
7067:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7068:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7069:   return(0);
7070: }
7074: /*@
7075:    MatSetBlockSize - Sets the matrix block size.
7077:    Logically Collective on Mat
7079:    Input Parameters:
7080: +  mat - the matrix
7081: -  bs - block size
7083:    Notes:
7084:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7086:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7088:    Level: intermediate
7090:    Concepts: matrices^block size
7092: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7093: @*/
7094: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7095: {
7101:   PetscLayoutSetBlockSize(mat->rmap,bs);
7102:   PetscLayoutSetBlockSize(mat->cmap,bs);
7103:   return(0);
7104: }
7108: /*@
7109:    MatSetBlockSizes - Sets the matrix block row and column sizes.
7111:    Logically Collective on Mat
7113:    Input Parameters:
7114: +  mat - the matrix
7115: -  rbs - row block size
7116: -  cbs - column block size
7118:    Notes:
7119:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7120:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7122:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7124:     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7126:    Level: intermediate
7128:    Concepts: matrices^block size
7130: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7131: @*/
7132: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7133: {
7140:   PetscLayoutSetBlockSize(mat->rmap,rbs);
7141:   PetscLayoutSetBlockSize(mat->cmap,cbs);
7142:   return(0);
7143: }
7147: /*@
7148:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7150:    Logically Collective on Mat
7152:    Input Parameters:
7153: +  mat - the matrix
7154: .  fromRow - matrix from which to copy row block size
7155: -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7157:    Level: developer
7159:    Concepts: matrices^block size
7161: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7162: @*/
7163: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7164: {
7171:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7172:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7173:   return(0);
7174: }
7178: /*@
7179:    MatResidual - Default routine to calculate the residual.
7181:    Collective on Mat and Vec
7183:    Input Parameters:
7184: +  mat - the matrix
7185: .  b   - the right-hand-side
7186: -  x   - the approximate solution
7188:    Output Parameter:
7189: .  r - location to store the residual
7191:    Level: developer
7193: .keywords: MG, default, multigrid, residual
7195: .seealso: PCMGSetResidual()
7196: @*/
7197: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7198: {
7207:   MatCheckPreallocated(mat,1);
7208:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7209:   if (!mat->ops->residual) {
7210:     MatMult(mat,x,r);
7211:     VecAYPX(r,-1.0,b);
7212:   } else {
7213:     (*mat->ops->residual)(mat,b,x,r);
7214:   }
7215:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7216:   return(0);
7217: }
7221: /*@C
7222:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7224:    Collective on Mat
7226:     Input Parameters:
7227: +   mat - the matrix
7228: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7229: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7230: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7231:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7232:                  always used.
7234:     Output Parameters:
7235: +   n - number of rows in the (possibly compressed) matrix
7236: .   ia - the row pointers [of length n+1]
7237: .   ja - the column indices
7238: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7239:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7241:     Level: developer
7243:     Notes: You CANNOT change any of the ia[] or ja[] values.
7245:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
7247:     Fortran Node
7249:            In Fortran use
7250: $           PetscInt ia(1), ja(1)
7251: $           PetscOffset iia, jja
7252: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7253: $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7254: $
7255: $          or
7256: $
7257: $           PetscInt, pointer :: ia(:),ja(:)
7258: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7259: $      Acess the ith and jth entries via ia(i) and ja(j)
7263: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7264: @*/
7265: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7266: {
7276:   MatCheckPreallocated(mat,1);
7277:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7278:   else {
7279:     *done = PETSC_TRUE;
7280:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7281:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7282:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7283:   }
7284:   return(0);
7285: }
7289: /*@C
7290:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7292:     Collective on Mat
7294:     Input Parameters:
7295: +   mat - the matrix
7296: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7297: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7298:                 symmetrized
7299: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7300:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7301:                  always used.
7302: .   n - number of columns in the (possibly compressed) matrix
7303: .   ia - the column pointers
7304: -   ja - the row indices
7306:     Output Parameters:
7307: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7309:     Note:
7310:     This routine zeros out n, ia, and ja. This is to prevent accidental
7311:     us of the array after it has been restored. If you pass NULL, it will
7312:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
7314:     Level: developer
7316: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7317: @*/
7318: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7319: {
7329:   MatCheckPreallocated(mat,1);
7330:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7331:   else {
7332:     *done = PETSC_TRUE;
7333:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7334:   }
7335:   return(0);
7336: }
7340: /*@C
7341:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7342:     MatGetRowIJ().
7344:     Collective on Mat
7346:     Input Parameters:
7347: +   mat - the matrix
7348: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7349: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7350:                 symmetrized
7351: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7352:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7353:                  always used.
7354: .   n - size of (possibly compressed) matrix
7355: .   ia - the row pointers
7356: -   ja - the column indices
7358:     Output Parameters:
7359: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7361:     Note:
7362:     This routine zeros out n, ia, and ja. This is to prevent accidental
7363:     us of the array after it has been restored. If you pass NULL, it will
7364:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7366:     Level: developer
7368: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7369: @*/
7370: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7371: {
7380:   MatCheckPreallocated(mat,1);
7382:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7383:   else {
7384:     *done = PETSC_TRUE;
7385:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7386:     if (n)  *n = 0;
7387:     if (ia) *ia = NULL;
7388:     if (ja) *ja = NULL;
7389:   }
7390:   return(0);
7391: }
7395: /*@C
7396:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7397:     MatGetColumnIJ().
7399:     Collective on Mat
7401:     Input Parameters:
7402: +   mat - the matrix
7403: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7404: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7405:                 symmetrized
7406: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7407:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7408:                  always used.
7410:     Output Parameters:
7411: +   n - size of (possibly compressed) matrix
7412: .   ia - the column pointers
7413: .   ja - the row indices
7414: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7416:     Level: developer
7418: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7419: @*/
7420: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7421: {
7430:   MatCheckPreallocated(mat,1);
7432:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7433:   else {
7434:     *done = PETSC_TRUE;
7435:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7436:     if (n)  *n = 0;
7437:     if (ia) *ia = NULL;
7438:     if (ja) *ja = NULL;
7439:   }
7440:   return(0);
7441: }
7445: /*@C
7446:     MatColoringPatch -Used inside matrix coloring routines that
7447:     use MatGetRowIJ() and/or MatGetColumnIJ().
7449:     Collective on Mat
7451:     Input Parameters:
7452: +   mat - the matrix
7453: .   ncolors - max color value
7454: .   n   - number of entries in colorarray
7455: -   colorarray - array indicating color for each column
7457:     Output Parameters:
7458: .   iscoloring - coloring generated using colorarray information
7460:     Level: developer
7462: .seealso: MatGetRowIJ(), MatGetColumnIJ()
7464: @*/
7465: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7466: {
7474:   MatCheckPreallocated(mat,1);
7476:   if (!mat->ops->coloringpatch) {
7477:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7478:   } else {
7479:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7480:   }
7481:   return(0);
7482: }
7487: /*@
7488:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7490:    Logically Collective on Mat
7492:    Input Parameter:
7493: .  mat - the factored matrix to be reset
7495:    Notes:
7496:    This routine should be used only with factored matrices formed by in-place
7497:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7498:    format).  This option can save memory, for example, when solving nonlinear
7499:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7500:    ILU(0) preconditioner.
7502:    Note that one can specify in-place ILU(0) factorization by calling
7503: .vb
7504:      PCType(pc,PCILU);
7505:      PCFactorSeUseInPlace(pc);
7506: .ve
7507:    or by using the options -pc_type ilu -pc_factor_in_place
7509:    In-place factorization ILU(0) can also be used as a local
7510:    solver for the blocks within the block Jacobi or additive Schwarz
7511:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7512:    for details on setting local solver options.
7514:    Most users should employ the simplified KSP interface for linear solvers
7515:    instead of working directly with matrix algebra routines such as this.
7516:    See, e.g., KSPCreate().
7518:    Level: developer
7520: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7522:    Concepts: matrices^unfactored
7524: @*/
7525: PetscErrorCode MatSetUnfactored(Mat mat)
7526: {
7532:   MatCheckPreallocated(mat,1);
7533:   mat->factortype = MAT_FACTOR_NONE;
7534:   if (!mat->ops->setunfactored) return(0);
7535:   (*mat->ops->setunfactored)(mat);
7536:   return(0);
7537: }
7539: /*MC
7540:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7542:     Synopsis:
7543:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7545:     Not collective
7547:     Input Parameter:
7548: .   x - matrix
7550:     Output Parameters:
7551: +   xx_v - the Fortran90 pointer to the array
7552: -   ierr - error code
7554:     Example of Usage:
7555: .vb
7556:       PetscScalar, pointer xx_v(:,:)
7557:       ....
7558:       call MatDenseGetArrayF90(x,xx_v,ierr)
7559:       a = xx_v(3)
7560:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7561: .ve
7563:     Level: advanced
7565: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7567:     Concepts: matrices^accessing array
7569: M*/
7571: /*MC
7572:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7573:     accessed with MatDenseGetArrayF90().
7575:     Synopsis:
7576:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7578:     Not collective
7580:     Input Parameters:
7581: +   x - matrix
7582: -   xx_v - the Fortran90 pointer to the array
7584:     Output Parameter:
7585: .   ierr - error code
7587:     Example of Usage:
7588: .vb
7589:        PetscScalar, pointer xx_v(:,:)
7590:        ....
7591:        call MatDenseGetArrayF90(x,xx_v,ierr)
7592:        a = xx_v(3)
7593:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7594: .ve
7596:     Level: advanced
7598: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7600: M*/
7603: /*MC
7604:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7606:     Synopsis:
7607:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7609:     Not collective
7611:     Input Parameter:
7612: .   x - matrix
7614:     Output Parameters:
7615: +   xx_v - the Fortran90 pointer to the array
7616: -   ierr - error code
7618:     Example of Usage:
7619: .vb
7620:       PetscScalar, pointer xx_v(:)
7621:       ....
7622:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7623:       a = xx_v(3)
7624:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7625: .ve
7627:     Level: advanced
7629: .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7631:     Concepts: matrices^accessing array
7633: M*/
7635: /*MC
7636:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7637:     accessed with MatSeqAIJGetArrayF90().
7639:     Synopsis:
7640:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7642:     Not collective
7644:     Input Parameters:
7645: +   x - matrix
7646: -   xx_v - the Fortran90 pointer to the array
7648:     Output Parameter:
7649: .   ierr - error code
7651:     Example of Usage:
7652: .vb
7653:        PetscScalar, pointer xx_v(:)
7654:        ....
7655:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7656:        a = xx_v(3)
7657:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7658: .ve
7660:     Level: advanced
7662: .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7664: M*/
7669: /*@
7670:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7671:                       as the original matrix.
7673:     Collective on Mat
7675:     Input Parameters:
7676: +   mat - the original matrix
7677: .   isrow - parallel IS containing the rows this processor should obtain
7678: .   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.
7679: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7681:     Output Parameter:
7682: .   newmat - the new submatrix, of the same type as the old
7684:     Level: advanced
7686:     Notes:
7687:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7689:     Some matrix types place restrictions on the row and column indices, such
7690:     as that they be sorted or that they be equal to each other.
7692:     The index sets may not have duplicate entries.
7694:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7695:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7696:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7697:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7698:    you are finished using it.
7700:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7701:     the input matrix.
7703:     If iscol is NULL then all columns are obtained (not supported in Fortran).
7705:    Example usage:
7706:    Consider the following 8x8 matrix with 34 non-zero values, that is
7707:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7708:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7709:    as follows:
7711: .vb
7712:             1  2  0  |  0  3  0  |  0  4
7713:     Proc0   0  5  6  |  7  0  0  |  8  0
7714:             9  0 10  | 11  0  0  | 12  0
7715:     -------------------------------------
7716:            13  0 14  | 15 16 17  |  0  0
7717:     Proc1   0 18  0  | 19 20 21  |  0  0
7718:             0  0  0  | 22 23  0  | 24  0
7719:     -------------------------------------
7720:     Proc2  25 26 27  |  0  0 28  | 29  0
7721:            30  0  0  | 31 32 33  |  0 34
7722: .ve
7724:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7726: .vb
7727:             2  0  |  0  3  0  |  0
7728:     Proc0   5  6  |  7  0  0  |  8
7729:     -------------------------------
7730:     Proc1  18  0  | 19 20 21  |  0
7731:     -------------------------------
7732:     Proc2  26 27  |  0  0 28  | 29
7733:             0  0  | 31 32 33  |  0
7734: .ve
7737:     Concepts: matrices^submatrices
7739: .seealso: MatGetSubMatrices()
7740: @*/
7741: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7742: {
7744:   PetscMPIInt    size;
7745:   Mat            *local;
7746:   IS             iscoltmp;
7755:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7756:   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7758:   MatCheckPreallocated(mat,1);
7759:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7761:   if (!iscol || isrow == iscol) {
7762:     PetscBool   stride;
7763:     PetscMPIInt grabentirematrix = 0,grab;
7764:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7765:     if (stride) {
7766:       PetscInt first,step,n,rstart,rend;
7767:       ISStrideGetInfo(isrow,&first,&step);
7768:       if (step == 1) {
7769:         MatGetOwnershipRange(mat,&rstart,&rend);
7770:         if (rstart == first) {
7771:           ISGetLocalSize(isrow,&n);
7772:           if (n == rend-rstart) {
7773:             grabentirematrix = 1;
7774:           }
7775:         }
7776:       }
7777:     }
7778:     MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7779:     if (grab) {
7780:       PetscInfo(mat,"Getting entire matrix as submatrix\n");
7781:       if (cll == MAT_INITIAL_MATRIX) {
7782:         *newmat = mat;
7783:         PetscObjectReference((PetscObject)mat);
7784:       }
7785:       return(0);
7786:     }
7787:   }
7789:   if (!iscol) {
7790:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7791:   } else {
7792:     iscoltmp = iscol;
7793:   }
7795:   /* if original matrix is on just one processor then use submatrix generated */
7796:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7797:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7798:     if (!iscol) {ISDestroy(&iscoltmp);}
7799:     return(0);
7800:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7801:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7802:     *newmat = *local;
7803:     PetscFree(local);
7804:     if (!iscol) {ISDestroy(&iscoltmp);}
7805:     return(0);
7806:   } else if (!mat->ops->getsubmatrix) {
7807:     /* Create a new matrix type that implements the operation using the full matrix */
7808:     PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7809:     switch (cll) {
7810:     case MAT_INITIAL_MATRIX:
7811:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7812:       break;
7813:     case MAT_REUSE_MATRIX:
7814:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7815:       break;
7816:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7817:     }
7818:     PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7819:     if (!iscol) {ISDestroy(&iscoltmp);}
7820:     return(0);
7821:   }
7823:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7824:   PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7825:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7826:   PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7827:   if (!iscol) {ISDestroy(&iscoltmp);}
7828:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7829:   return(0);
7830: }
7834: /*@
7835:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7836:    used during the assembly process to store values that belong to
7837:    other processors.
7839:    Not Collective
7841:    Input Parameters:
7842: +  mat   - the matrix
7843: .  size  - the initial size of the stash.
7844: -  bsize - the initial size of the block-stash(if used).
7846:    Options Database Keys:
7847: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7848: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7850:    Level: intermediate
7852:    Notes:
7853:      The block-stash is used for values set with MatSetValuesBlocked() while
7854:      the stash is used for values set with MatSetValues()
7856:      Run with the option -info and look for output of the form
7857:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7858:      to determine the appropriate value, MM, to use for size and
7859:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7860:      to determine the value, BMM to use for bsize
7862:    Concepts: stash^setting matrix size
7863:    Concepts: matrices^stash
7865: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7867: @*/
7868: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7869: {
7875:   MatStashSetInitialSize_Private(&mat->stash,size);
7876:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7877:   return(0);
7878: }
7882: /*@
7883:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7884:      the matrix
7886:    Neighbor-wise Collective on Mat
7888:    Input Parameters:
7889: +  mat   - the matrix
7890: .  x,y - the vectors
7891: -  w - where the result is stored
7893:    Level: intermediate
7895:    Notes:
7896:     w may be the same vector as y.
7898:     This allows one to use either the restriction or interpolation (its transpose)
7899:     matrix to do the interpolation
7901:     Concepts: interpolation
7903: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7905: @*/
7906: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7907: {
7909:   PetscInt       M,N,Ny;
7917:   MatCheckPreallocated(A,1);
7918:   MatGetSize(A,&M,&N);
7919:   VecGetSize(y,&Ny);
7920:   if (M == Ny) {
7921:     MatMultAdd(A,x,y,w);
7922:   } else {
7923:     MatMultTransposeAdd(A,x,y,w);
7924:   }
7925:   return(0);
7926: }
7930: /*@
7931:    MatInterpolate - y = A*x or A'*x depending on the shape of
7932:      the matrix
7934:    Neighbor-wise Collective on Mat
7936:    Input Parameters:
7937: +  mat   - the matrix
7938: -  x,y - the vectors
7940:    Level: intermediate
7942:    Notes:
7943:     This allows one to use either the restriction or interpolation (its transpose)
7944:     matrix to do the interpolation
7946:    Concepts: matrices^interpolation
7948: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7950: @*/
7951: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7952: {
7954:   PetscInt       M,N,Ny;
7961:   MatCheckPreallocated(A,1);
7962:   MatGetSize(A,&M,&N);
7963:   VecGetSize(y,&Ny);
7964:   if (M == Ny) {
7965:     MatMult(A,x,y);
7966:   } else {
7967:     MatMultTranspose(A,x,y);
7968:   }
7969:   return(0);
7970: }
7974: /*@
7975:    MatRestrict - y = A*x or A'*x
7977:    Neighbor-wise Collective on Mat
7979:    Input Parameters:
7980: +  mat   - the matrix
7981: -  x,y - the vectors
7983:    Level: intermediate
7985:    Notes:
7986:     This allows one to use either the restriction or interpolation (its transpose)
7987:     matrix to do the restriction
7989:    Concepts: matrices^restriction
7991: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7993: @*/
7994: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7995: {
7997:   PetscInt       M,N,Ny;
8004:   MatCheckPreallocated(A,1);
8006:   MatGetSize(A,&M,&N);
8007:   VecGetSize(y,&Ny);
8008:   if (M == Ny) {
8009:     MatMult(A,x,y);
8010:   } else {
8011:     MatMultTranspose(A,x,y);
8012:   }
8013:   return(0);
8014: }
8018: /*@
8019:    MatGetNullSpace - retrieves the null space to a matrix.
8021:    Logically Collective on Mat and MatNullSpace
8023:    Input Parameters:
8024: +  mat - the matrix
8025: -  nullsp - the null space object
8027:    Level: developer
8029:    Concepts: null space^attaching to matrix
8031: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8032: @*/
8033: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8034: {
8039:   *nullsp = mat->nullsp;
8040:   return(0);
8041: }
8045: /*@
8046:    MatSetNullSpace - attaches a null space to a matrix.
8048:    Logically Collective on Mat and MatNullSpace
8050:    Input Parameters:
8051: +  mat - the matrix
8052: -  nullsp - the null space object
8054:    Level: advanced
8056:    Notes:
8057:       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8059:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8060:       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8062:       You can remove the null space by calling this routine with an nullsp of NULL
8065:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8066:    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8067:    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8068:    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8069:    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).
8071:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8073:    Concepts: null space^attaching to matrix
8075: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8076: @*/
8077: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8078: {
8085:   MatCheckPreallocated(mat,1);
8086:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8087:   MatNullSpaceDestroy(&mat->nullsp);
8088:   mat->nullsp = nullsp;
8089:   return(0);
8090: }
8094: /*@
8095:    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8097:    Logically Collective on Mat and MatNullSpace
8099:    Input Parameters:
8100: +  mat - the matrix
8101: -  nullsp - the null space object
8103:    Level: developer
8105:    Concepts: null space^attaching to matrix
8107: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8108: @*/
8109: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8110: {
8115:   *nullsp = mat->transnullsp;
8116:   return(0);
8117: }
8121: /*@
8122:    MatSetTransposeNullSpace - attaches a null space to a matrix.
8124:    Logically Collective on Mat and MatNullSpace
8126:    Input Parameters:
8127: +  mat - the matrix
8128: -  nullsp - the null space object
8130:    Level: advanced
8132:    Notes:
8133:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) this allows the linear system to be solved in a least squares sense.
8134:       You must also call MatSetNullSpace()
8137:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8138:    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8139:    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8140:    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8141:    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).
8143:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8145:    Concepts: null space^attaching to matrix
8147: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8148: @*/
8149: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8150: {
8157:   MatCheckPreallocated(mat,1);
8158:   PetscObjectReference((PetscObject)nullsp);
8159:   MatNullSpaceDestroy(&mat->transnullsp);
8160:   mat->transnullsp = nullsp;
8161:   return(0);
8162: }
8166: /*@
8167:    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8168:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8170:    Logically Collective on Mat and MatNullSpace
8172:    Input Parameters:
8173: +  mat - the matrix
8174: -  nullsp - the null space object
8176:    Level: advanced
8178:    Notes:
8179:       Overwrites any previous near null space that may have been attached
8181:       You can remove the null space by calling this routine with an nullsp of NULL
8183:    Concepts: null space^attaching to matrix
8185: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8186: @*/
8187: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8188: {
8195:   MatCheckPreallocated(mat,1);
8196:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8197:   MatNullSpaceDestroy(&mat->nearnullsp);
8198:   mat->nearnullsp = nullsp;
8199:   return(0);
8200: }
8204: /*@
8205:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8207:    Not Collective
8209:    Input Parameters:
8210: .  mat - the matrix
8212:    Output Parameters:
8213: .  nullsp - the null space object, NULL if not set
8215:    Level: developer
8217:    Concepts: null space^attaching to matrix
8219: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8220: @*/
8221: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8222: {
8227:   MatCheckPreallocated(mat,1);
8228:   *nullsp = mat->nearnullsp;
8229:   return(0);
8230: }
8234: /*@C
8235:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8237:    Collective on Mat
8239:    Input Parameters:
8240: +  mat - the matrix
8241: .  row - row/column permutation
8242: .  fill - expected fill factor >= 1.0
8243: -  level - level of fill, for ICC(k)
8245:    Notes:
8246:    Probably really in-place only when level of fill is zero, otherwise allocates
8247:    new space to store factored matrix and deletes previous memory.
8249:    Most users should employ the simplified KSP interface for linear solvers
8250:    instead of working directly with matrix algebra routines such as this.
8251:    See, e.g., KSPCreate().
8253:    Level: developer
8255:    Concepts: matrices^incomplete Cholesky factorization
8256:    Concepts: Cholesky factorization
8258: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8260:     Developer Note: fortran interface is not autogenerated as the f90
8261:     interface defintion cannot be generated correctly [due to MatFactorInfo]
8263: @*/
8264: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8265: {
8273:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8274:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8275:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8276:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8277:   MatCheckPreallocated(mat,1);
8278:   (*mat->ops->iccfactor)(mat,row,info);
8279:   PetscObjectStateIncrease((PetscObject)mat);
8280:   return(0);
8281: }
8285: /*@
8286:    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
8288:    Not Collective
8290:    Input Parameters:
8291: +  mat - the matrix
8292: .  nl - leading dimension of v
8293: -  v - the values compute with ADIFOR
8295:    Level: developer
8297:    Notes:
8298:      Must call MatSetColoring() before using this routine. Also this matrix must already
8299:      have its nonzero pattern determined.
8301: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8302:           MatSetValues(), MatSetColoring()
8303: @*/
8304: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8305: {
8313:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8314:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
8315:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8316:   (*mat->ops->setvaluesadifor)(mat,nl,v);
8317:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
8318:   PetscObjectStateIncrease((PetscObject)mat);
8319:   return(0);
8320: }
8324: /*@
8325:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8326:          ghosted ones.
8328:    Not Collective
8330:    Input Parameters:
8331: +  mat - the matrix
8332: -  diag = the diagonal values, including ghost ones
8334:    Level: developer
8336:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
8338: .seealso: MatDiagonalScale()
8339: @*/
8340: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8341: {
8343:   PetscMPIInt    size;
8350:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8351:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8352:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8353:   if (size == 1) {
8354:     PetscInt n,m;
8355:     VecGetSize(diag,&n);
8356:     MatGetSize(mat,0,&m);
8357:     if (m == n) {
8358:       MatDiagonalScale(mat,0,diag);
8359:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8360:   } else {
8361:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8362:   }
8363:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8364:   PetscObjectStateIncrease((PetscObject)mat);
8365:   return(0);
8366: }
8370: /*@
8371:    MatGetInertia - Gets the inertia from a factored matrix
8373:    Collective on Mat
8375:    Input Parameter:
8376: .  mat - the matrix
8378:    Output Parameters:
8379: +   nneg - number of negative eigenvalues
8380: .   nzero - number of zero eigenvalues
8381: -   npos - number of positive eigenvalues
8383:    Level: advanced
8385:    Notes: Matrix must have been factored by MatCholeskyFactor()
8388: @*/
8389: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8390: {
8396:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8397:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8398:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8399:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8400:   return(0);
8401: }
8403: /* ----------------------------------------------------------------*/
8406: /*@C
8407:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8409:    Neighbor-wise Collective on Mat and Vecs
8411:    Input Parameters:
8412: +  mat - the factored matrix
8413: -  b - the right-hand-side vectors
8415:    Output Parameter:
8416: .  x - the result vectors
8418:    Notes:
8419:    The vectors b and x cannot be the same.  I.e., one cannot
8420:    call MatSolves(A,x,x).
8422:    Notes:
8423:    Most users should employ the simplified KSP interface for linear solvers
8424:    instead of working directly with matrix algebra routines such as this.
8425:    See, e.g., KSPCreate().
8427:    Level: developer
8429:    Concepts: matrices^triangular solves
8431: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8432: @*/
8433: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8434: {
8440:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8441:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8442:   if (!mat->rmap->N && !mat->cmap->N) return(0);
8444:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8445:   MatCheckPreallocated(mat,1);
8446:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8447:   (*mat->ops->solves)(mat,b,x);
8448:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8449:   return(0);
8450: }
8454: /*@
8455:    MatIsSymmetric - Test whether a matrix is symmetric
8457:    Collective on Mat
8459:    Input Parameter:
8460: +  A - the matrix to test
8461: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8463:    Output Parameters:
8464: .  flg - the result
8466:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8468:    Level: intermediate
8470:    Concepts: matrix^symmetry
8472: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8473: @*/
8474: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8475: {
8482:   if (!A->symmetric_set) {
8483:     if (!A->ops->issymmetric) {
8484:       MatType mattype;
8485:       MatGetType(A,&mattype);
8486:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8487:     }
8488:     (*A->ops->issymmetric)(A,tol,flg);
8489:     if (!tol) {
8490:       A->symmetric_set = PETSC_TRUE;
8491:       A->symmetric     = *flg;
8492:       if (A->symmetric) {
8493:         A->structurally_symmetric_set = PETSC_TRUE;
8494:         A->structurally_symmetric     = PETSC_TRUE;
8495:       }
8496:     }
8497:   } else if (A->symmetric) {
8498:     *flg = PETSC_TRUE;
8499:   } else if (!tol) {
8500:     *flg = PETSC_FALSE;
8501:   } else {
8502:     if (!A->ops->issymmetric) {
8503:       MatType mattype;
8504:       MatGetType(A,&mattype);
8505:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8506:     }
8507:     (*A->ops->issymmetric)(A,tol,flg);
8508:   }
8509:   return(0);
8510: }
8514: /*@
8515:    MatIsHermitian - Test whether a matrix is Hermitian
8517:    Collective on Mat
8519:    Input Parameter:
8520: +  A - the matrix to test
8521: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8523:    Output Parameters:
8524: .  flg - the result
8526:    Level: intermediate
8528:    Concepts: matrix^symmetry
8530: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8531:           MatIsSymmetricKnown(), MatIsSymmetric()
8532: @*/
8533: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8534: {
8541:   if (!A->hermitian_set) {
8542:     if (!A->ops->ishermitian) {
8543:       MatType mattype;
8544:       MatGetType(A,&mattype);
8545:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8546:     }
8547:     (*A->ops->ishermitian)(A,tol,flg);
8548:     if (!tol) {
8549:       A->hermitian_set = PETSC_TRUE;
8550:       A->hermitian     = *flg;
8551:       if (A->hermitian) {
8552:         A->structurally_symmetric_set = PETSC_TRUE;
8553:         A->structurally_symmetric     = PETSC_TRUE;
8554:       }
8555:     }
8556:   } else if (A->hermitian) {
8557:     *flg = PETSC_TRUE;
8558:   } else if (!tol) {
8559:     *flg = PETSC_FALSE;
8560:   } else {
8561:     if (!A->ops->ishermitian) {
8562:       MatType mattype;
8563:       MatGetType(A,&mattype);
8564:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8565:     }
8566:     (*A->ops->ishermitian)(A,tol,flg);
8567:   }
8568:   return(0);
8569: }
8573: /*@
8574:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8576:    Not Collective
8578:    Input Parameter:
8579: .  A - the matrix to check
8581:    Output Parameters:
8582: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8583: -  flg - the result
8585:    Level: advanced
8587:    Concepts: matrix^symmetry
8589:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8590:          if you want it explicitly checked
8592: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8593: @*/
8594: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8595: {
8600:   if (A->symmetric_set) {
8601:     *set = PETSC_TRUE;
8602:     *flg = A->symmetric;
8603:   } else {
8604:     *set = PETSC_FALSE;
8605:   }
8606:   return(0);
8607: }
8611: /*@
8612:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8614:    Not Collective
8616:    Input Parameter:
8617: .  A - the matrix to check
8619:    Output Parameters:
8620: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8621: -  flg - the result
8623:    Level: advanced
8625:    Concepts: matrix^symmetry
8627:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8628:          if you want it explicitly checked
8630: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8631: @*/
8632: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8633: {
8638:   if (A->hermitian_set) {
8639:     *set = PETSC_TRUE;
8640:     *flg = A->hermitian;
8641:   } else {
8642:     *set = PETSC_FALSE;
8643:   }
8644:   return(0);
8645: }
8649: /*@
8650:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8652:    Collective on Mat
8654:    Input Parameter:
8655: .  A - the matrix to test
8657:    Output Parameters:
8658: .  flg - the result
8660:    Level: intermediate
8662:    Concepts: matrix^symmetry
8664: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8665: @*/
8666: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8667: {
8673:   if (!A->structurally_symmetric_set) {
8674:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8675:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8677:     A->structurally_symmetric_set = PETSC_TRUE;
8678:   }
8679:   *flg = A->structurally_symmetric;
8680:   return(0);
8681: }
8685: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8686: /*@
8687:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8688:        to be communicated to other processors during the MatAssemblyBegin/End() process
8690:     Not collective
8692:    Input Parameter:
8693: .   vec - the vector
8695:    Output Parameters:
8696: +   nstash   - the size of the stash
8697: .   reallocs - the number of additional mallocs incurred.
8698: .   bnstash   - the size of the block stash
8699: -   breallocs - the number of additional mallocs incurred.in the block stash
8701:    Level: advanced
8703: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8705: @*/
8706: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8707: {
8711:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8712:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8713:   return(0);
8714: }
8718: /*@C
8719:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8720:      parallel layout
8722:    Collective on Mat
8724:    Input Parameter:
8725: .  mat - the matrix
8727:    Output Parameter:
8728: +   right - (optional) vector that the matrix can be multiplied against
8729: -   left - (optional) vector that the matrix vector product can be stored in
8731:    Notes:
8732:     The blocksize of the returned vectors is determined by the row and column block sizes set with MatSetBlockSizes() or the single blocksize (same for both) set by MatSetBlockSize().
8734:   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8736:   Level: advanced
8738: .seealso: MatCreate(), VecDestroy()
8739: @*/
8740: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8741: {
8747:   if (mat->ops->getvecs) {
8748:     (*mat->ops->getvecs)(mat,right,left);
8749:   } else {
8750:     PetscInt rbs,cbs;
8751:     MatGetBlockSizes(mat,&rbs,&cbs);
8752:     if (right) {
8753:       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8754:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8755:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8756:       VecSetBlockSize(*right,cbs);
8757:       VecSetType(*right,VECSTANDARD);
8758:       PetscLayoutReference(mat->cmap,&(*right)->map);
8759:     }
8760:     if (left) {
8761:       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8762:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8763:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8764:       VecSetBlockSize(*left,rbs);
8765:       VecSetType(*left,VECSTANDARD);
8766:       PetscLayoutReference(mat->rmap,&(*left)->map);
8767:     }
8768:   }
8769:   return(0);
8770: }
8774: /*@C
8775:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8776:      with default values.
8778:    Not Collective
8780:    Input Parameters:
8781: .    info - the MatFactorInfo data structure
8784:    Notes: The solvers are generally used through the KSP and PC objects, for example
8785:           PCLU, PCILU, PCCHOLESKY, PCICC
8787:    Level: developer
8789: .seealso: MatFactorInfo
8791:     Developer Note: fortran interface is not autogenerated as the f90
8792:     interface defintion cannot be generated correctly [due to MatFactorInfo]
8794: @*/
8796: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8797: {
8801:   PetscMemzero(info,sizeof(MatFactorInfo));
8802:   return(0);
8803: }
8807: /*@
8808:    MatFactorSetSchurIS - Set indices corresponding to the Schur complement
8810:    Collective on Mat
8812:    Input Parameters:
8813: +  mat - the factored matrix
8814: -  is - the index set defining the Schur indices (0-based)
8816:    Notes:
8818:    Level: developer
8820:    Concepts:
8822: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8824: @*/
8825: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8826: {
8827:   PetscErrorCode ierr,(*f)(Mat,IS);
8835:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8836:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8837:   if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverPackage does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
8838:   (*f)(mat,is);
8839:   return(0);
8840: }
8844: /*@
8845:   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8847:    Logically Collective on Mat
8849:    Input Parameters:
8850: +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8851: .  *S - location where to return the Schur complement (MATDENSE)
8853:    Notes:
8854:    The routine provides a copy of the Schur data stored within solver's data strutures. The caller must destroy the object when it is no longer needed.
8855:    If MatFactorInvertSchurComplement has been called, the routine gets back the inverse
8857:    Level: advanced
8859:    References:
8861: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement()
8862: @*/
8863: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S)
8864: {
8869:   PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));
8870:   return(0);
8871: }
8875: /*@
8876:   MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data
8878:    Logically Collective on Mat
8880:    Input Parameters:
8881: +  F - the factored matrix obtained by calling MatGetFactor()
8882: .  *S - location where to return the Schur complement (in MATDENSE format)
8884:    Notes:
8885:    Schur complement mode is currently implemented for sequential matrices.
8886:    The routine returns a dense matrix pointing to the raw data of the Schur Complement stored within the data strutures of the solver; e.g. if MatFactorInvertSchurComplement has been called, the returned matrix is actually the inverse of the Schur complement.
8887:    The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.
8889:    Level: advanced
8891:    References:
8893: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8894: @*/
8895: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S)
8896: {
8901:   PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));
8902:   return(0);
8903: }
8907: /*@
8908:   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8910:    Logically Collective on Mat
8912:    Input Parameters:
8913: +  F - the factored matrix obtained by calling MatGetFactor()
8914: .  *S - location where the Schur complement is stored
8916:    Notes:
8918:    Level: advanced
8920:    References:
8922: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8923: @*/
8924: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S)
8925: {
8931:   MatDestroy(S);
8932:   return(0);
8933: }
8937: /*@
8938:   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8940:    Logically Collective on Mat
8942:    Input Parameters:
8943: +  F - the factored matrix obtained by calling MatGetFactor()
8944: .  rhs - location where the right hand side of the Schur complement system is stored
8945: -  sol - location where the solution of the Schur complement system has to be returned
8947:    Notes:
8948:    The sizes of the vectors should match the size of the Schur complement
8950:    Level: advanced
8952:    References:
8954: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8955: @*/
8956: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8957: {
8966:   PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));
8967:   return(0);
8968: }
8972: /*@
8973:   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8975:    Logically Collective on Mat
8977:    Input Parameters:
8978: +  F - the factored matrix obtained by calling MatGetFactor()
8979: .  rhs - location where the right hand side of the Schur complement system is stored
8980: -  sol - location where the solution of the Schur complement system has to be returned
8982:    Notes:
8983:    The sizes of the vectors should match the size of the Schur complement
8985:    Level: advanced
8987:    References:
8989: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8990: @*/
8991: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8992: {
9001:   PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));
9002:   return(0);
9003: }
9007: /*@
9008:   MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step
9010:    Logically Collective on Mat
9012:    Input Parameters:
9013: +  F - the factored matrix obtained by calling MatGetFactor()
9015:    Notes:
9017:    Level: advanced
9019:    References:
9021: .seealso: MatGetFactor(), MatFactorSetSchurIS()
9022: @*/
9023: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9024: {
9029:   PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));
9030:   return(0);
9031: }
9036: /*@
9037:    MatPtAP - Creates the matrix product C = P^T * A * P
9039:    Neighbor-wise Collective on Mat
9041:    Input Parameters:
9042: +  A - the matrix
9043: .  P - the projection matrix
9044: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9045: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9046:           if the result is a dense matrix this is irrelevent
9048:    Output Parameters:
9049: .  C - the product matrix
9051:    Notes:
9052:    C will be created and must be destroyed by the user with MatDestroy().
9054:    This routine is currently only implemented for pairs of AIJ matrices and classes
9055:    which inherit from AIJ.
9057:    Level: intermediate
9059: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9060: @*/
9061: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9062: {
9064:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9065:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9066:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9067:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
9070:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
9071:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);
9075:   MatCheckPreallocated(A,1);
9076:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9077:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9080:   MatCheckPreallocated(P,2);
9081:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9082:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9084:   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);
9085:   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);
9086:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9087:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9089:   if (scall == MAT_REUSE_MATRIX) {
9092:     if (viatranspose || viamatmatmatmult) {
9093:       Mat Pt;
9094:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9095:       if (viamatmatmatmult) {
9096:         MatMatMatMult(Pt,A,P,scall,fill,C);
9097:       } else {
9098:         Mat AP;
9099:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9100:         MatMatMult(Pt,AP,scall,fill,C);
9101:         MatDestroy(&AP);
9102:       }
9103:       MatDestroy(&Pt);
9104:     } else {
9105:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9106:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9107:       (*(*C)->ops->ptapnumeric)(A,P,*C);
9108:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9109:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9110:     }
9111:     return(0);
9112:   }
9114:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9115:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9117:   fA = A->ops->ptap;
9118:   fP = P->ops->ptap;
9119:   if (fP == fA) {
9120:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9121:     ptap = fA;
9122:   } else {
9123:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9124:     char ptapname[256];
9125:     PetscStrcpy(ptapname,"MatPtAP_");
9126:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
9127:     PetscStrcat(ptapname,"_");
9128:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
9129:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9130:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9131:     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);
9132:   }
9134:   if (viatranspose || viamatmatmatmult) {
9135:     Mat Pt;
9136:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9137:     if (viamatmatmatmult) {
9138:       MatMatMatMult(Pt,A,P,scall,fill,C);
9139:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
9140:     } else {
9141:       Mat AP;
9142:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9143:       MatMatMult(Pt,AP,scall,fill,C);
9144:       MatDestroy(&AP);
9145:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
9146:     }
9147:     MatDestroy(&Pt);
9148:   } else {
9149:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9150:     (*ptap)(A,P,scall,fill,C);
9151:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9152:   }
9153:   return(0);
9154: }
9158: /*@
9159:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9161:    Neighbor-wise Collective on Mat
9163:    Input Parameters:
9164: +  A - the matrix
9165: -  P - the projection matrix
9167:    Output Parameters:
9168: .  C - the product matrix
9170:    Notes:
9171:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9172:    the user using MatDeatroy().
9174:    This routine is currently only implemented for pairs of AIJ matrices and classes
9175:    which inherit from AIJ.  C will be of type MATAIJ.
9177:    Level: intermediate
9179: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9180: @*/
9181: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9182: {
9188:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9189:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9192:   MatCheckPreallocated(P,2);
9193:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9194:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9197:   MatCheckPreallocated(C,3);
9198:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9199:   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);
9200:   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);
9201:   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);
9202:   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);
9203:   MatCheckPreallocated(A,1);
9205:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9206:   (*C->ops->ptapnumeric)(A,P,C);
9207:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9208:   return(0);
9209: }
9213: /*@
9214:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9216:    Neighbor-wise Collective on Mat
9218:    Input Parameters:
9219: +  A - the matrix
9220: -  P - the projection matrix
9222:    Output Parameters:
9223: .  C - the (i,j) structure of the product matrix
9225:    Notes:
9226:    C will be created and must be destroyed by the user with MatDestroy().
9228:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9229:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9230:    this (i,j) structure by calling MatPtAPNumeric().
9232:    Level: intermediate
9234: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9235: @*/
9236: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9237: {
9243:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9244:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9245:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9248:   MatCheckPreallocated(P,2);
9249:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9250:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9253:   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);
9254:   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);
9255:   MatCheckPreallocated(A,1);
9256:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9257:   (*A->ops->ptapsymbolic)(A,P,fill,C);
9258:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
9260:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
9261:   return(0);
9262: }
9266: /*@
9267:    MatRARt - Creates the matrix product C = R * A * R^T
9269:    Neighbor-wise Collective on Mat
9271:    Input Parameters:
9272: +  A - the matrix
9273: .  R - the projection matrix
9274: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9275: -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9276:           if the result is a dense matrix this is irrelevent
9278:    Output Parameters:
9279: .  C - the product matrix
9281:    Notes:
9282:    C will be created and must be destroyed by the user with MatDestroy().
9284:    This routine is currently only implemented for pairs of AIJ matrices and classes
9285:    which inherit from AIJ.
9287:    Level: intermediate
9289: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9290: @*/
9291: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9292: {
9298:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9299:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9302:   MatCheckPreallocated(R,2);
9303:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9304:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9306:   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);
9308:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9309:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9310:   MatCheckPreallocated(A,1);
9312:   if (!A->ops->rart) {
9313:     MatType mattype;
9314:     MatGetType(A,&mattype);
9315:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
9316:   }
9317:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
9318:   (*A->ops->rart)(A,R,scall,fill,C);
9319:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
9320:   return(0);
9321: }
9325: /*@
9326:    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9328:    Neighbor-wise Collective on Mat
9330:    Input Parameters:
9331: +  A - the matrix
9332: -  R - the projection matrix
9334:    Output Parameters:
9335: .  C - the product matrix
9337:    Notes:
9338:    C must have been created by calling MatRARtSymbolic and must be destroyed by
9339:    the user using MatDestroy().
9341:    This routine is currently only implemented for pairs of AIJ matrices and classes
9342:    which inherit from AIJ.  C will be of type MATAIJ.
9344:    Level: intermediate
9346: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9347: @*/
9348: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9349: {
9355:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9356:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9359:   MatCheckPreallocated(R,2);
9360:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9361:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9364:   MatCheckPreallocated(C,3);
9365:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9366:   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);
9367:   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);
9368:   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);
9369:   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);
9370:   MatCheckPreallocated(A,1);
9372:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
9373:   (*A->ops->rartnumeric)(A,R,C);
9374:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
9375:   return(0);
9376: }
9380: /*@
9381:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9383:    Neighbor-wise Collective on Mat
9385:    Input Parameters:
9386: +  A - the matrix
9387: -  R - the projection matrix
9389:    Output Parameters:
9390: .  C - the (i,j) structure of the product matrix
9392:    Notes:
9393:    C will be created and must be destroyed by the user with MatDestroy().
9395:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9396:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9397:    this (i,j) structure by calling MatRARtNumeric().
9399:    Level: intermediate
9401: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9402: @*/
9403: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9404: {
9410:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9411:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9412:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9415:   MatCheckPreallocated(R,2);
9416:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9417:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9420:   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);
9421:   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);
9422:   MatCheckPreallocated(A,1);
9423:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9424:   (*A->ops->rartsymbolic)(A,R,fill,C);
9425:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
9427:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9428:   return(0);
9429: }
9433: /*@
9434:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9436:    Neighbor-wise Collective on Mat
9438:    Input Parameters:
9439: +  A - the left matrix
9440: .  B - the right matrix
9441: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9442: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9443:           if the result is a dense matrix this is irrelevent
9445:    Output Parameters:
9446: .  C - the product matrix
9448:    Notes:
9449:    Unless scall is MAT_REUSE_MATRIX C will be created.
9451:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9453:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9454:    actually needed.
9456:    If you have many matrices with the same non-zero structure to multiply, you
9457:    should either
9458: $   1) use MAT_REUSE_MATRIX in all calls but the first or
9459: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9460:    In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine
9461:    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9463:    Level: intermediate
9465: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9466: @*/
9467: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9468: {
9470:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9471:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9472:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9477:   MatCheckPreallocated(A,1);
9478:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9479:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9482:   MatCheckPreallocated(B,2);
9483:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9484:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9486:   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);
9487:   if (scall == MAT_REUSE_MATRIX) {
9490:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9491:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9492:     (*(*C)->ops->matmultnumeric)(A,B,*C);
9493:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9494:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9495:     return(0);
9496:   }
9497:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9498:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9500:   fA = A->ops->matmult;
9501:   fB = B->ops->matmult;
9502:   if (fB == fA) {
9503:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9504:     mult = fB;
9505:   } else {
9506:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9507:     char multname[256];
9508:     PetscStrcpy(multname,"MatMatMult_");
9509:     PetscStrcat(multname,((PetscObject)A)->type_name);
9510:     PetscStrcat(multname,"_");
9511:     PetscStrcat(multname,((PetscObject)B)->type_name);
9512:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9513:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9514:     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);
9515:   }
9516:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9517:   (*mult)(A,B,scall,fill,C);
9518:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9519:   return(0);
9520: }
9524: /*@
9525:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9526:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9528:    Neighbor-wise Collective on Mat
9530:    Input Parameters:
9531: +  A - the left matrix
9532: .  B - the right matrix
9533: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9534:       if C is a dense matrix this is irrelevent
9536:    Output Parameters:
9537: .  C - the product matrix
9539:    Notes:
9540:    Unless scall is MAT_REUSE_MATRIX C will be created.
9542:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9543:    actually needed.
9545:    This routine is currently implemented for
9546:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9547:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9548:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9550:    Level: intermediate
9552:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9553:      We should incorporate them into PETSc.
9555: .seealso: MatMatMult(), MatMatMultNumeric()
9556: @*/
9557: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9558: {
9560:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9561:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9562:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9567:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9568:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9572:   MatCheckPreallocated(B,2);
9573:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9574:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9577:   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);
9578:   if (fill == PETSC_DEFAULT) fill = 2.0;
9579:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9580:   MatCheckPreallocated(A,1);
9582:   Asymbolic = A->ops->matmultsymbolic;
9583:   Bsymbolic = B->ops->matmultsymbolic;
9584:   if (Asymbolic == Bsymbolic) {
9585:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9586:     symbolic = Bsymbolic;
9587:   } else { /* dispatch based on the type of A and B */
9588:     char symbolicname[256];
9589:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9590:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9591:     PetscStrcat(symbolicname,"_");
9592:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9593:     PetscStrcat(symbolicname,"_C");
9594:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9595:     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);
9596:   }
9597:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9598:   (*symbolic)(A,B,fill,C);
9599:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9600:   return(0);
9601: }
9605: /*@
9606:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9607:    Call this routine after first calling MatMatMultSymbolic().
9609:    Neighbor-wise Collective on Mat
9611:    Input Parameters:
9612: +  A - the left matrix
9613: -  B - the right matrix
9615:    Output Parameters:
9616: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9618:    Notes:
9619:    C must have been created with MatMatMultSymbolic().
9621:    This routine is currently implemented for
9622:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9623:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9624:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9626:    Level: intermediate
9628: .seealso: MatMatMult(), MatMatMultSymbolic()
9629: @*/
9630: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9631: {
9635:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9636:   return(0);
9637: }
9641: /*@
9642:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9644:    Neighbor-wise Collective on Mat
9646:    Input Parameters:
9647: +  A - the left matrix
9648: .  B - the right matrix
9649: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9650: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9652:    Output Parameters:
9653: .  C - the product matrix
9655:    Notes:
9656:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9658:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9660:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9661:    actually needed.
9663:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.
9665:    Level: intermediate
9667: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9668: @*/
9669: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9670: {
9672:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9673:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9678:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9679:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9682:   MatCheckPreallocated(B,2);
9683:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9684:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9686:   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);
9687:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9688:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9689:   MatCheckPreallocated(A,1);
9691:   fA = A->ops->mattransposemult;
9692:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9693:   fB = B->ops->mattransposemult;
9694:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9695:   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);
9697:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9698:   if (scall == MAT_INITIAL_MATRIX) {
9699:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9700:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9701:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9702:   }
9703:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9704:   (*A->ops->mattransposemultnumeric)(A,B,*C);
9705:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9706:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9707:   return(0);
9708: }
9712: /*@
9713:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9715:    Neighbor-wise Collective on Mat
9717:    Input Parameters:
9718: +  A - the left matrix
9719: .  B - the right matrix
9720: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9721: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9723:    Output Parameters:
9724: .  C - the product matrix
9726:    Notes:
9727:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9729:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9731:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9732:    actually needed.
9734:    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9735:    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9737:    Level: intermediate
9739: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9740: @*/
9741: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9742: {
9744:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9745:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9746:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9751:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9752:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9755:   MatCheckPreallocated(B,2);
9756:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9757:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9759:   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);
9760:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9761:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9762:   MatCheckPreallocated(A,1);
9764:   fA = A->ops->transposematmult;
9765:   fB = B->ops->transposematmult;
9766:   if (fB==fA) {
9767:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9768:     transposematmult = fA;
9769:   } else {
9770:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9771:     char multname[256];
9772:     PetscStrcpy(multname,"MatTransposeMatMult_");
9773:     PetscStrcat(multname,((PetscObject)A)->type_name);
9774:     PetscStrcat(multname,"_");
9775:     PetscStrcat(multname,((PetscObject)B)->type_name);
9776:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9777:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9778:     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);
9779:   }
9780:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9781:   (*transposematmult)(A,B,scall,fill,C);
9782:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9783:   return(0);
9784: }
9788: /*@
9789:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9791:    Neighbor-wise Collective on Mat
9793:    Input Parameters:
9794: +  A - the left matrix
9795: .  B - the middle matrix
9796: .  C - the right matrix
9797: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9798: -  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
9799:           if the result is a dense matrix this is irrelevent
9801:    Output Parameters:
9802: .  D - the product matrix
9804:    Notes:
9805:    Unless scall is MAT_REUSE_MATRIX D will be created.
9807:    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9809:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9810:    actually needed.
9812:    If you have many matrices with the same non-zero structure to multiply, you
9813:    should use MAT_REUSE_MATRIX in all calls but the first or
9815:    Level: intermediate
9817: .seealso: MatMatMult, MatPtAP()
9818: @*/
9819: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9820: {
9822:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9823:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9824:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9825:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9830:   MatCheckPreallocated(A,1);
9831:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9832:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9835:   MatCheckPreallocated(B,2);
9836:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9837:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9840:   MatCheckPreallocated(C,3);
9841:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9842:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9843:   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);
9844:   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);
9845:   if (scall == MAT_REUSE_MATRIX) {
9848:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9849:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9850:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9851:     return(0);
9852:   }
9853:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9854:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9856:   fA = A->ops->matmatmult;
9857:   fB = B->ops->matmatmult;
9858:   fC = C->ops->matmatmult;
9859:   if (fA == fB && fA == fC) {
9860:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9861:     mult = fA;
9862:   } else {
9863:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9864:     char multname[256];
9865:     PetscStrcpy(multname,"MatMatMatMult_");
9866:     PetscStrcat(multname,((PetscObject)A)->type_name);
9867:     PetscStrcat(multname,"_");
9868:     PetscStrcat(multname,((PetscObject)B)->type_name);
9869:     PetscStrcat(multname,"_");
9870:     PetscStrcat(multname,((PetscObject)C)->type_name);
9871:     PetscStrcat(multname,"_C");
9872:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9873:     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);
9874:   }
9875:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9876:   (*mult)(A,B,C,scall,fill,D);
9877:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9878:   return(0);
9879: }
9883: /*@
9884:    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9886:    Collective on Mat
9888:    Input Parameters:
9889: +  mat - the matrix
9890: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9891: .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9892: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9894:    Output Parameter:
9895: .  matredundant - redundant matrix
9897:    Notes:
9898:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9899:    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9901:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9902:    calling it.
9904:    Level: advanced
9906:    Concepts: subcommunicator
9907:    Concepts: duplicate matrix
9909: .seealso: MatDestroy()
9910: @*/
9911: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9912: {
9914:   MPI_Comm       comm;
9915:   PetscMPIInt    size;
9916:   PetscInt       mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9917:   Mat_Redundant  *redund=NULL;
9918:   PetscSubcomm   psubcomm=NULL;
9919:   MPI_Comm       subcomm_in=subcomm;
9920:   Mat            *matseq;
9921:   IS             isrow,iscol;
9922:   PetscBool      newsubcomm=PETSC_FALSE;
9925:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
9926:   if (size == 1 || nsubcomm == 1) {
9927:     if (reuse == MAT_INITIAL_MATRIX) {
9928:       MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
9929:     } else {
9930:       MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
9931:     }
9932:     return(0);
9933:   }
9936:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9939:   }
9940:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9941:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9942:   MatCheckPreallocated(mat,1);
9944:   PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
9945:   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9946:     /* create psubcomm, then get subcomm */
9947:     PetscObjectGetComm((PetscObject)mat,&comm);
9948:     MPI_Comm_size(comm,&size);
9949:     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9951:     PetscSubcommCreate(comm,&psubcomm);
9952:     PetscSubcommSetNumber(psubcomm,nsubcomm);
9953:     PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
9954:     PetscSubcommSetFromOptions(psubcomm);
9955:     PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);
9956:     newsubcomm = PETSC_TRUE;
9957:     PetscSubcommDestroy(&psubcomm);
9958:   }
9960:   /* get isrow, iscol and a local sequential matrix matseq[0] */
9961:   if (reuse == MAT_INITIAL_MATRIX) {
9962:     mloc_sub = PETSC_DECIDE;
9963:     if (bs < 1) {
9964:       PetscSplitOwnership(subcomm,&mloc_sub,&M);
9965:     } else {
9966:       PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
9967:     }
9968:     MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
9969:     rstart = rend - mloc_sub;
9970:     ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
9971:     ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
9972:   } else { /* reuse == MAT_REUSE_MATRIX */
9973:     /* retrieve subcomm */
9974:     PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
9975:     redund = (*matredundant)->redundant;
9976:     isrow  = redund->isrow;
9977:     iscol  = redund->iscol;
9978:     matseq = redund->matseq;
9979:   }
9980:   MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);
9982:   /* get matredundant over subcomm */
9983:   if (reuse == MAT_INITIAL_MATRIX) {
9984:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);
9986:     /* create a supporting struct and attach it to C for reuse */
9987:     PetscNewLog(*matredundant,&redund);
9988:     (*matredundant)->redundant = redund;
9989:     redund->isrow              = isrow;
9990:     redund->iscol              = iscol;
9991:     redund->matseq             = matseq;
9992:     if (newsubcomm) {
9993:       redund->subcomm          = subcomm;
9994:     } else {
9995:       redund->subcomm          = MPI_COMM_NULL;
9996:     }
9997:   } else {
9998:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
9999:   }
10000:   PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
10001:   return(0);
10002: }
10006: /*@C
10007:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10008:    a given 'mat' object. Each submatrix can span multiple procs.
10010:    Collective on Mat
10012:    Input Parameters:
10013: +  mat - the matrix
10014: .  subcomm - the subcommunicator obtained by com_split(comm)
10015: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10017:    Output Parameter:
10018: .  subMat - 'parallel submatrices each spans a given subcomm
10020:   Notes:
10021:   The submatrix partition across processors is dictated by 'subComm' a
10022:   communicator obtained by com_split(comm). The comm_split
10023:   is not restriced to be grouped with consecutive original ranks.
10025:   Due the comm_split() usage, the parallel layout of the submatrices
10026:   map directly to the layout of the original matrix [wrt the local
10027:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10028:   into the 'DiagonalMat' of the subMat, hence it is used directly from
10029:   the subMat. However the offDiagMat looses some columns - and this is
10030:   reconstructed with MatSetValues()
10032:   Level: advanced
10034:   Concepts: subcommunicator
10035:   Concepts: submatrices
10037: .seealso: MatGetSubMatrices()
10038: @*/
10039: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10040: {
10042:   PetscMPIInt    commsize,subCommSize;
10045:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
10046:   MPI_Comm_size(subComm,&subCommSize);
10047:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10049:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
10050:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
10051:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
10052:   return(0);
10053: }
10057: /*@
10058:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10060:    Not Collective
10062:    Input Arguments:
10063:    mat - matrix to extract local submatrix from
10064:    isrow - local row indices for submatrix
10065:    iscol - local column indices for submatrix
10067:    Output Arguments:
10068:    submat - the submatrix
10070:    Level: intermediate
10072:    Notes:
10073:    The submat should be returned with MatRestoreLocalSubMatrix().
10075:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10076:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10078:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10079:    MatSetValuesBlockedLocal() will also be implemented.
10081:    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 
10082:    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.   
10084: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10085: @*/
10086: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10087: {
10096:   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10097: 
10098:   if (mat->ops->getlocalsubmatrix) {
10099:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
10100:   } else {
10101:     MatCreateLocalRef(mat,isrow,iscol,submat);
10102:   }
10103:   return(0);
10104: }
10108: /*@
10109:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10111:    Not Collective
10113:    Input Arguments:
10114:    mat - matrix to extract local submatrix from
10115:    isrow - local row indices for submatrix
10116:    iscol - local column indices for submatrix
10117:    submat - the submatrix
10119:    Level: intermediate
10121: .seealso: MatGetLocalSubMatrix()
10122: @*/
10123: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10124: {
10133:   if (*submat) {
10135:   }
10137:   if (mat->ops->restorelocalsubmatrix) {
10138:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
10139:   } else {
10140:     MatDestroy(submat);
10141:   }
10142:   *submat = NULL;
10143:   return(0);
10144: }
10146: /* --------------------------------------------------------*/
10149: /*@
10150:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
10152:    Collective on Mat
10154:    Input Parameter:
10155: .  mat - the matrix
10157:    Output Parameter:
10158: .  is - if any rows have zero diagonals this contains the list of them
10160:    Level: developer
10162:    Concepts: matrix-vector product
10164: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10165: @*/
10166: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10167: {
10173:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10174:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10176:   if (!mat->ops->findzerodiagonals) {
10177:     Vec                diag;
10178:     const PetscScalar *a;
10179:     PetscInt          *rows;
10180:     PetscInt           rStart, rEnd, r, nrow = 0;
10182:     MatCreateVecs(mat, &diag, NULL);
10183:     MatGetDiagonal(mat, diag);
10184:     MatGetOwnershipRange(mat, &rStart, &rEnd);
10185:     VecGetArrayRead(diag, &a);
10186:     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10187:     PetscMalloc1(nrow, &rows);
10188:     nrow = 0;
10189:     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10190:     VecRestoreArrayRead(diag, &a);
10191:     VecDestroy(&diag);
10192:     ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);
10193:   } else {
10194:     (*mat->ops->findzerodiagonals)(mat, is);
10195:   }
10196:   return(0);
10197: }
10201: /*@
10202:    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10204:    Collective on Mat
10206:    Input Parameter:
10207: .  mat - the matrix
10209:    Output Parameter:
10210: .  is - contains the list of rows with off block diagonal entries
10212:    Level: developer
10214:    Concepts: matrix-vector product
10216: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10217: @*/
10218: PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10219: {
10225:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10226:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10228:   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10229:   (*mat->ops->findoffblockdiagonalentries)(mat,is);
10230:   return(0);
10231: }
10235: /*@C
10236:   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10238:   Collective on Mat
10240:   Input Parameters:
10241: . mat - the matrix
10243:   Output Parameters:
10244: . values - the block inverses in column major order (FORTRAN-like)
10246:    Note:
10247:    This routine is not available from Fortran.
10249:   Level: advanced
10250: @*/
10251: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10252: {
10257:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10258:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10259:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10260:   (*mat->ops->invertblockdiagonal)(mat,values);
10261:   return(0);
10262: }
10266: /*@C
10267:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10268:     via MatTransposeColoringCreate().
10270:     Collective on MatTransposeColoring
10272:     Input Parameter:
10273: .   c - coloring context
10275:     Level: intermediate
10277: .seealso: MatTransposeColoringCreate()
10278: @*/
10279: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10280: {
10281:   PetscErrorCode       ierr;
10282:   MatTransposeColoring matcolor=*c;
10285:   if (!matcolor) return(0);
10286:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
10288:   PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
10289:   PetscFree(matcolor->rows);
10290:   PetscFree(matcolor->den2sp);
10291:   PetscFree(matcolor->colorforcol);
10292:   PetscFree(matcolor->columns);
10293:   if (matcolor->brows>0) {
10294:     PetscFree(matcolor->lstart);
10295:   }
10296:   PetscHeaderDestroy(c);
10297:   return(0);
10298: }
10302: /*@C
10303:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10304:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10305:     MatTransposeColoring to sparse B.
10307:     Collective on MatTransposeColoring
10309:     Input Parameters:
10310: +   B - sparse matrix B
10311: .   Btdense - symbolic dense matrix B^T
10312: -   coloring - coloring context created with MatTransposeColoringCreate()
10314:     Output Parameter:
10315: .   Btdense - dense matrix B^T
10317:     Options Database Keys:
10318: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
10319: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
10320: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info
10322:     Level: intermediate
10324: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
10326: .keywords: coloring
10327: @*/
10328: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10329: {
10337:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10338:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
10339:   return(0);
10340: }
10344: /*@C
10345:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10346:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10347:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10348:     Csp from Cden.
10350:     Collective on MatTransposeColoring
10352:     Input Parameters:
10353: +   coloring - coloring context created with MatTransposeColoringCreate()
10354: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10356:     Output Parameter:
10357: .   Csp - sparse matrix
10359:     Options Database Keys:
10360: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
10361: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
10362: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
10364:     Level: intermediate
10366: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10368: .keywords: coloring
10369: @*/
10370: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10371: {
10379:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10380:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
10381:   return(0);
10382: }
10386: /*@C
10387:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10389:    Collective on Mat
10391:    Input Parameters:
10392: +  mat - the matrix product C
10393: -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10395:     Output Parameter:
10396: .   color - the new coloring context
10398:     Level: intermediate
10400: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
10401:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
10402: @*/
10403: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10404: {
10405:   MatTransposeColoring c;
10406:   MPI_Comm             comm;
10407:   PetscErrorCode       ierr;
10410:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
10411:   PetscObjectGetComm((PetscObject)mat,&comm);
10412:   PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);
10414:   c->ctype = iscoloring->ctype;
10415:   if (mat->ops->transposecoloringcreate) {
10416:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
10417:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10419:   *color = c;
10420:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
10421:   return(0);
10422: }
10426: /*@
10427:       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10428:         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10429:         same, otherwise it will be larger
10431:      Not Collective
10433:   Input Parameter:
10434: .    A  - the matrix
10436:   Output Parameter:
10437: .    state - the current state
10439:   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10440:          different matrices
10442:   Level: intermediate
10444: @*/
10445: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10446: {
10449:   *state = mat->nonzerostate;
10450:   return(0);
10451: }
10455: /*@
10456:       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10457:                  matrices from each processor
10459:     Collective on MPI_Comm
10461:    Input Parameters:
10462: +    comm - the communicators the parallel matrix will live on
10463: .    seqmat - the input sequential matrices
10464: .    n - number of local columns (or PETSC_DECIDE)
10465: -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10467:    Output Parameter:
10468: .    mpimat - the parallel matrix generated
10470:     Level: advanced
10472:    Notes: The number of columns of the matrix in EACH processor MUST be the same.
10474: @*/
10475: PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10476: {
10478:   PetscMPIInt    size;
10481:   MPI_Comm_size(comm,&size);
10482:   if (size == 1) {
10483:     if (reuse == MAT_INITIAL_MATRIX) {
10484:       MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);
10485:     } else {
10486:       MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);
10487:     }
10488:     return(0);
10489:   }
10491:   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10492:   PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);
10493:   (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);
10494:   PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);
10495:   return(0);
10496: }
10500: /*@
10501:      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10502:                  ranks' ownership ranges.
10504:     Collective on A
10506:    Input Parameters:
10507: +    A   - the matrix to create subdomains from
10508: -    N   - requested number of subdomains
10511:    Output Parameters:
10512: +    n   - number of subdomains resulting on this rank
10513: -    iss - IS list with indices of subdomains on this rank
10515:     Level: advanced
10517:     Notes: number of subdomains must be smaller than the communicator size
10518: @*/
10519: PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10520: {
10521:   MPI_Comm        comm,subcomm;
10522:   PetscMPIInt     size,rank,color;
10523:   PetscInt        rstart,rend,k;
10524:   PetscErrorCode  ierr;
10527:   PetscObjectGetComm((PetscObject)A,&comm);
10528:   MPI_Comm_size(comm,&size);
10529:   MPI_Comm_rank(comm,&rank);
10530:   if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N);
10531:   *n = 1;
10532:   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10533:   color = rank/k;
10534:   MPI_Comm_split(comm,color,rank,&subcomm);
10535:   PetscMalloc1(1,iss);
10536:   MatGetOwnershipRange(A,&rstart,&rend);
10537:   ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);
10538:   MPI_Comm_free(&subcomm);
10539:   return(0);
10540: }