Actual source code: matrix.c

petsc-master 2018-07-19
Report Typos and Errors

  2: /*
  3:    This is where the abstract matrix operations are defined
  4: */

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

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

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

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

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

 45:    Logically Collective on Mat

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

 52:    Output Parameter:
 53: .  x  - the matrix

 55:    Example of Usage:
 56: .vb
 57:      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
 58:      MatSetRandom(x,rctx);
 59:      PetscRandomDestroy(rctx);
 60: .ve

 62:    Level: intermediate

 64:    Concepts: matrix^setting to random
 65:    Concepts: random^matrix

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


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

 87:   PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);
 88:   (*x->ops->setrandom)(x,rctx);
 89:   PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);

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

 96: /*@
 97:    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in

 99:    Logically Collective on Mat

101:    Input Parameters:
102: .  mat - the factored matrix

104:    Output Parameter:
105: +  pivot - the pivot value computed
106: -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
107:          the share the matrix

109:    Level: advanced

111:    Notes:
112:     This routine does not work for factorizations done with external packages.
113:    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT

115:    This can be called on non-factored matrices that come from, for example, matrices used in SOR.

117: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
118: @*/
119: PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
120: {
123:   *pivot = mat->factorerror_zeropivot_value;
124:   *row   = mat->factorerror_zeropivot_row;
125:   return(0);
126: }

128: /*@
129:    MatFactorGetError - gets the error code from a factorization

131:    Logically Collective on Mat

133:    Input Parameters:
134: .  mat - the factored matrix

136:    Output Parameter:
137: .  err  - the error code

139:    Level: advanced

141:    Notes:
142:     This can be called on non-factored matrices that come from, for example, matrices used in SOR.

144: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
145: @*/
146: PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
147: {
150:   *err = mat->factorerrortype;
151:   return(0);
152: }

154: /*@
155:    MatFactorClearError - clears the error code in a factorization

157:    Logically Collective on Mat

159:    Input Parameter:
160: .  mat - the factored matrix

162:    Level: developer

164:    Notes:
165:     This can be called on non-factored matrices that come from, for example, matrices used in SOR.

167: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
168: @*/
169: PetscErrorCode MatFactorClearError(Mat mat)
170: {
173:   mat->factorerrortype             = MAT_FACTOR_NOERROR;
174:   mat->factorerror_zeropivot_value = 0.0;
175:   mat->factorerror_zeropivot_row   = 0;
176:   return(0);
177: }

179: PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
180: {
181:   PetscErrorCode    ierr;
182:   Vec               r,l;
183:   const PetscScalar *al;
184:   PetscInt          i,nz,gnz,N,n;

187:   MatCreateVecs(mat,&r,&l);
188:   if (!cols) { /* nonzero rows */
189:     MatGetSize(mat,&N,NULL);
190:     MatGetLocalSize(mat,&n,NULL);
191:     VecSet(l,0.0);
192:     VecSetRandom(r,NULL);
193:     MatMult(mat,r,l);
194:     VecGetArrayRead(l,&al);
195:   } else { /* nonzero columns */
196:     MatGetSize(mat,NULL,&N);
197:     MatGetLocalSize(mat,NULL,&n);
198:     VecSet(r,0.0);
199:     VecSetRandom(l,NULL);
200:     MatMultTranspose(mat,l,r);
201:     VecGetArrayRead(r,&al);
202:   }
203:   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
204:   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
205:   MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));
206:   if (gnz != N) {
207:     PetscInt *nzr;
208:     PetscMalloc1(nz,&nzr);
209:     if (nz) {
210:       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
211:       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
212:     }
213:     ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);
214:   } else *nonzero = NULL;
215:   if (!cols) { /* nonzero rows */
216:     VecRestoreArrayRead(l,&al);
217:   } else {
218:     VecRestoreArrayRead(r,&al);
219:   }
220:   VecDestroy(&l);
221:   VecDestroy(&r);
222:   return(0);
223: }

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

228:   Input Parameter:
229: .    A  - the matrix

231:   Output Parameter:
232: .    keptrows - the rows that are not completely zero

234:   Notes:
235:     keptrows is set to NULL if all rows are nonzero.

237:   Level: intermediate

239:  @*/
240: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
241: {

248:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
249:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
250:   if (!mat->ops->findnonzerorows) {
251:     MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);
252:   } else {
253:     (*mat->ops->findnonzerorows)(mat,keptrows);
254:   }
255:   return(0);
256: }

258: /*@
259:       MatFindZeroRows - Locate all rows that are completely zero in the matrix

261:   Input Parameter:
262: .    A  - the matrix

264:   Output Parameter:
265: .    zerorows - the rows that are completely zero

267:   Notes:
268:     zerorows is set to NULL if no rows are zero.

270:   Level: intermediate

272:  @*/
273: PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
274: {
276:   IS keptrows;
277:   PetscInt m, n;


282:   MatFindNonzeroRows(mat, &keptrows);
283:   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
284:      In keeping with this convention, we set zerorows to NULL if there are no zero
285:      rows. */
286:   if (keptrows == NULL) {
287:     *zerorows = NULL;
288:   } else {
289:     MatGetOwnershipRange(mat,&m,&n);
290:     ISComplement(keptrows,m,n,zerorows);
291:     ISDestroy(&keptrows);
292:   }
293:   return(0);
294: }

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

299:    Not Collective

301:    Input Parameters:
302: .   A - the matrix

304:    Output Parameters:
305: .   a - the diagonal part (which is a SEQUENTIAL matrix)

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

312:    Level: advanced

314: @*/
315: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
316: {

323:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
324:   if (!A->ops->getdiagonalblock) {
325:     PetscMPIInt size;
326:     MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
327:     if (size == 1) {
328:       *a = A;
329:       return(0);
330:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
331:   }
332:   (*A->ops->getdiagonalblock)(A,a);
333:   return(0);
334: }

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

339:    Collective on Mat

341:    Input Parameters:
342: .  mat - the matrix

344:    Output Parameter:
345: .   trace - the sum of the diagonal entries

347:    Level: advanced

349: @*/
350: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
351: {
353:   Vec            diag;

356:   MatCreateVecs(mat,&diag,NULL);
357:   MatGetDiagonal(mat,diag);
358:   VecSum(diag,trace);
359:   VecDestroy(&diag);
360:   return(0);
361: }

363: /*@
364:    MatRealPart - Zeros out the imaginary part of the matrix

366:    Logically Collective on Mat

368:    Input Parameters:
369: .  mat - the matrix

371:    Level: advanced


374: .seealso: MatImaginaryPart()
375: @*/
376: PetscErrorCode MatRealPart(Mat mat)
377: {

383:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
384:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
385:   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
386:   MatCheckPreallocated(mat,1);
387:   (*mat->ops->realpart)(mat);
388: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
389:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
390:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
391:   }
392: #endif
393:   return(0);
394: }

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

399:    Collective on Mat

401:    Input Parameter:
402: .  mat - the matrix

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

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

411:    Level: advanced

413: @*/
414: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
415: {

421:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
422:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
423:   if (!mat->ops->getghosts) {
424:     if (nghosts) *nghosts = 0;
425:     if (ghosts) *ghosts = 0;
426:   } else {
427:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
428:   }
429:   return(0);
430: }


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

436:    Logically Collective on Mat

438:    Input Parameters:
439: .  mat - the matrix

441:    Level: advanced


444: .seealso: MatRealPart()
445: @*/
446: PetscErrorCode MatImaginaryPart(Mat mat)
447: {

453:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
454:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
455:   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
456:   MatCheckPreallocated(mat,1);
457:   (*mat->ops->imaginarypart)(mat);
458: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
459:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
460:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
461:   }
462: #endif
463:   return(0);
464: }

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

469:    Not Collective

471:    Input Parameter:
472: .  mat - the matrix

474:    Output Parameters:
475: +  missing - is any diagonal missing
476: -  dd - first diagonal entry that is missing (optional) on this process

478:    Level: advanced


481: .seealso: MatRealPart()
482: @*/
483: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
484: {

490:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
491:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
492:   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
493:   (*mat->ops->missingdiagonal)(mat,missing,dd);
494:   return(0);
495: }

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

502:    Not Collective

504:    Input Parameters:
505: +  mat - the matrix
506: -  row - the row to get

508:    Output Parameters:
509: +  ncols -  if not NULL, the number of nonzeros in the row
510: .  cols - if not NULL, the column numbers
511: -  vals - if not NULL, the values

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

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

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

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

528:    You can only have one call to MatGetRow() outstanding for a particular
529:    matrix at a time, per processor. MatGetRow() can only obtain rows
530:    associated with the given processor, it cannot get rows from the
531:    other processors; for that we suggest using MatCreateSubMatrices(), then
532:    MatGetRow() on the submatrix. The row index passed to MatGetRows()
533:    is in the global number of rows.

535:    Fortran Notes:
536:    The calling sequence from Fortran is
537: .vb
538:    MatGetRow(matrix,row,ncols,cols,values,ierr)
539:          Mat     matrix (input)
540:          integer row    (input)
541:          integer ncols  (output)
542:          integer cols(maxcols) (output)
543:          double precision (or double complex) values(maxcols) output
544: .ve
545:    where maxcols >= maximum nonzeros in any row of the matrix.


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

552:    Level: advanced

554:    Concepts: matrices^row access

556: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
557: @*/
558: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
559: {
561:   PetscInt       incols;

566:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
567:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
568:   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
569:   MatCheckPreallocated(mat,1);
570:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
571:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
572:   if (ncols) *ncols = incols;
573:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
574:   return(0);
575: }

577: /*@
578:    MatConjugate - replaces the matrix values with their complex conjugates

580:    Logically Collective on Mat

582:    Input Parameters:
583: .  mat - the matrix

585:    Level: advanced

587: .seealso:  VecConjugate()
588: @*/
589: PetscErrorCode MatConjugate(Mat mat)
590: {
591: #if defined(PETSC_USE_COMPLEX)

596:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
597:   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");
598:   (*mat->ops->conjugate)(mat);
599: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
600:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
601:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
602:   }
603: #endif
604:   return(0);
605: #else
606:   return 0;
607: #endif
608: }

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

613:    Not Collective

615:    Input Parameters:
616: +  mat - the matrix
617: .  row - the row to get
618: .  ncols, cols - the number of nonzeros and their columns
619: -  vals - if nonzero the column values

621:    Notes:
622:    This routine should be called after you have finished examining the entries.

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

628:    Fortran Notes:
629:    The calling sequence from Fortran is
630: .vb
631:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
632:       Mat     matrix (input)
633:       integer row    (input)
634:       integer ncols  (output)
635:       integer cols(maxcols) (output)
636:       double precision (or double complex) values(maxcols) output
637: .ve
638:    Where maxcols >= maximum nonzeros in any row of the matrix.

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

643:    Level: advanced

645: .seealso:  MatGetRow()
646: @*/
647: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
648: {

654:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
655:   if (!mat->ops->restorerow) return(0);
656:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
657:   if (ncols) *ncols = 0;
658:   if (cols)  *cols = NULL;
659:   if (vals)  *vals = NULL;
660:   return(0);
661: }

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

667:    Not Collective

669:    Input Parameters:
670: +  mat - the matrix

672:    Notes:
673:    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.

675:    Level: advanced

677:    Concepts: matrices^row access

679: .seealso: MatRestoreRowRowUpperTriangular()
680: @*/
681: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
682: {

688:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
689:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
690:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
691:   MatCheckPreallocated(mat,1);
692:   (*mat->ops->getrowuppertriangular)(mat);
693:   return(0);
694: }

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

699:    Not Collective

701:    Input Parameters:
702: +  mat - the matrix

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


708:    Level: advanced

710: .seealso:  MatGetRowUpperTriangular()
711: @*/
712: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
713: {

718:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
719:   if (!mat->ops->restorerowuppertriangular) return(0);
720:   (*mat->ops->restorerowuppertriangular)(mat);
721:   return(0);
722: }

724: /*@C
725:    MatSetOptionsPrefix - Sets the prefix used for searching for all
726:    Mat options in the database.

728:    Logically Collective on Mat

730:    Input Parameter:
731: +  A - the Mat context
732: -  prefix - the prefix to prepend to all option names

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

738:    Level: advanced

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

742: .seealso: MatSetFromOptions()
743: @*/
744: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
745: {

750:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
751:   return(0);
752: }

754: /*@C
755:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
756:    Mat options in the database.

758:    Logically Collective on Mat

760:    Input Parameters:
761: +  A - the Mat context
762: -  prefix - the prefix to prepend to all option names

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

768:    Level: advanced

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

772: .seealso: MatGetOptionsPrefix()
773: @*/
774: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
775: {

780:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
781:   return(0);
782: }

784: /*@C
785:    MatGetOptionsPrefix - Sets the prefix used for searching for all
786:    Mat options in the database.

788:    Not Collective

790:    Input Parameter:
791: .  A - the Mat context

793:    Output Parameter:
794: .  prefix - pointer to the prefix string used

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

800:    Level: advanced

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

804: .seealso: MatAppendOptionsPrefix()
805: @*/
806: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
807: {

812:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
813:   return(0);
814: }

816: /*@
817:    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.

819:    Collective on Mat

821:    Input Parameters:
822: .  A - the Mat context

824:    Notes:
825:    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
826:    Currently support MPIAIJ and SEQAIJ.

828:    Level: beginner

830: .keywords: Mat, ResetPreallocation

832: .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
833: @*/
834: PetscErrorCode MatResetPreallocation(Mat A)
835: {

841:   PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));
842:   return(0);
843: }


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

849:    Collective on Mat

851:    Input Parameters:
852: .  A - the Mat context

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

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

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

861:    Level: beginner

863: .keywords: Mat, setup

865: .seealso: MatCreate(), MatDestroy()
866: @*/
867: PetscErrorCode MatSetUp(Mat A)
868: {
869:   PetscMPIInt    size;

874:   if (!((PetscObject)A)->type_name) {
875:     MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
876:     if (size == 1) {
877:       MatSetType(A, MATSEQAIJ);
878:     } else {
879:       MatSetType(A, MATMPIAIJ);
880:     }
881:   }
882:   if (!A->preallocated && A->ops->setup) {
883:     PetscInfo(A,"Warning not preallocating matrix storage\n");
884:     (*A->ops->setup)(A);
885:   }
886:   PetscLayoutSetUp(A->rmap);
887:   PetscLayoutSetUp(A->cmap);
888:   A->preallocated = PETSC_TRUE;
889:   return(0);
890: }

892: #if defined(PETSC_HAVE_SAWS)
893:  #include <petscviewersaws.h>
894: #endif
895: /*@C
896:    MatView - Visualizes a matrix object.

898:    Collective on Mat

900:    Input Parameters:
901: +  mat - the matrix
902: -  viewer - visualization context

904:   Notes:
905:   The available visualization contexts include
906: +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
907: .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
908: .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
909: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

911:    The user can open alternative visualization contexts with
912: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
913: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
914:          specified file; corresponding input uses MatLoad()
915: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
916:          an X window display
917: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
918:          Currently only the sequential dense and AIJ
919:          matrix types support the Socket viewer.

921:    The user can call PetscViewerPushFormat() to specify the output
922:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
923:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
924: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
925: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
926: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
927: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
928:          format common among all matrix types
929: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
930:          format (which is in many cases the same as the default)
931: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
932:          size and structure (not the matrix entries)
933: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
934:          the matrix structure

936:    Options Database Keys:
937: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
938: .  -mat_view ::ascii_info_detail - Prints more detailed info
939: .  -mat_view - Prints matrix in ASCII format
940: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
941: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
942: .  -display <name> - Sets display name (default is host)
943: .  -draw_pause <sec> - Sets number of seconds to pause after display
944: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 12 Using MATLAB with PETSc for details)
945: .  -viewer_socket_machine <machine> -
946: .  -viewer_socket_port <port> -
947: .  -mat_view binary - save matrix to file in binary format
948: -  -viewer_binary_filename <name> -
949:    Level: beginner

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

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

958:       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
959:       And then use the following mouse functions:
960:           left mouse: zoom in
961:           middle mouse: zoom out
962:           right mouse: continue with the simulation

964:    Concepts: matrices^viewing
965:    Concepts: matrices^plotting
966:    Concepts: matrices^printing

968: .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
969:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
970: @*/
971: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
972: {
973:   PetscErrorCode    ierr;
974:   PetscInt          rows,cols,rbs,cbs;
975:   PetscBool         iascii,ibinary;
976:   PetscViewerFormat format;
977:   PetscMPIInt       size;
978: #if defined(PETSC_HAVE_SAWS)
979:   PetscBool         issaws;
980: #endif

985:   if (!viewer) {
986:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
987:   }
990:   MatCheckPreallocated(mat,1);
991:   PetscViewerGetFormat(viewer,&format);
992:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
993:   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) return(0);
994:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
995:   if (ibinary) {
996:     PetscBool mpiio;
997:     PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
998:     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
999:   }

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

1007: #if defined(PETSC_HAVE_SAWS)
1008:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
1009: #endif
1010:   if (iascii) {
1011:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1012:     PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
1013:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1014:       MatNullSpace nullsp,transnullsp;

1016:       PetscViewerASCIIPushTab(viewer);
1017:       MatGetSize(mat,&rows,&cols);
1018:       MatGetBlockSizes(mat,&rbs,&cbs);
1019:       if (rbs != 1 || cbs != 1) {
1020:         if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
1021:         else            {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
1022:       } else {
1023:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
1024:       }
1025:       if (mat->factortype) {
1026:         MatSolverType solver;
1027:         MatFactorGetSolverType(mat,&solver);
1028:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
1029:       }
1030:       if (mat->ops->getinfo) {
1031:         MatInfo info;
1032:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
1033:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
1034:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
1035:       }
1036:       MatGetNullSpace(mat,&nullsp);
1037:       MatGetTransposeNullSpace(mat,&transnullsp);
1038:       if (nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached null space\n");}
1039:       if (transnullsp && transnullsp != nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");}
1040:       MatGetNearNullSpace(mat,&nullsp);
1041:       if (nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");}
1042:     }
1043: #if defined(PETSC_HAVE_SAWS)
1044:   } else if (issaws) {
1045:     PetscMPIInt rank;

1047:     PetscObjectName((PetscObject)mat);
1048:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
1049:     if (!((PetscObject)mat)->amsmem && !rank) {
1050:       PetscObjectViewSAWs((PetscObject)mat,viewer);
1051:     }
1052: #endif
1053:   }
1054:   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1055:     PetscViewerASCIIPushTab(viewer);
1056:     (*mat->ops->viewnative)(mat,viewer);
1057:     PetscViewerASCIIPopTab(viewer);
1058:   } else if (mat->ops->view) {
1059:     PetscViewerASCIIPushTab(viewer);
1060:     (*mat->ops->view)(mat,viewer);
1061:     PetscViewerASCIIPopTab(viewer);
1062:   }
1063:   if (iascii) {
1064:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1065:     PetscViewerGetFormat(viewer,&format);
1066:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1067:       PetscViewerASCIIPopTab(viewer);
1068:     }
1069:   }
1070:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
1071:   return(0);
1072: }

1074: #if defined(PETSC_USE_DEBUG)
1075: #include <../src/sys/totalview/tv_data_display.h>
1076: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1077: {
1078:   TV_add_row("Local rows", "int", &mat->rmap->n);
1079:   TV_add_row("Local columns", "int", &mat->cmap->n);
1080:   TV_add_row("Global rows", "int", &mat->rmap->N);
1081:   TV_add_row("Global columns", "int", &mat->cmap->N);
1082:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1083:   return TV_format_OK;
1084: }
1085: #endif

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

1093:    Collective on PetscViewer

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

1100:    Options Database Keys:
1101:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1102:    block size
1103: .    -matload_block_size <bs>

1105:    Level: beginner

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

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

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

1120:    In parallel, each processor can load a subset of rows (or the
1121:    entire matrix).  This routine is especially useful when a large
1122:    matrix is stored on disk and only part of it is desired on each
1123:    processor.  For example, a parallel solver may access only some of
1124:    the rows from each processor.  The algorithm used here reads
1125:    relatively small blocks of data rather than reading the entire
1126:    matrix and then subsetting it.

1128:    Notes for advanced users:
1129:    Most users should not need to know the details of the binary storage
1130:    format, since MatLoad() and MatView() completely hide these details.
1131:    But for anyone who's interested, the standard binary matrix storage
1132:    format is

1134: $    int    MAT_FILE_CLASSID
1135: $    int    number of rows
1136: $    int    number of columns
1137: $    int    total number of nonzeros
1138: $    int    *number nonzeros in each row
1139: $    int    *column indices of all nonzeros (starting index is zero)
1140: $    PetscScalar *values of all nonzeros

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

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

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

1152:  @*/
1153: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1154: {
1156:   PetscBool      isbinary,flg;

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

1164:   if (!((PetscObject)newmat)->type_name) {
1165:     MatSetType(newmat,MATAIJ);
1166:   }

1168:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1169:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1170:   (*newmat->ops->load)(newmat,viewer);
1171:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

1173:   flg  = PETSC_FALSE;
1174:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1175:   if (flg) {
1176:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1177:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1178:   }
1179:   flg  = PETSC_FALSE;
1180:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1181:   if (flg) {
1182:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1183:   }
1184:   return(0);
1185: }

1187: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1188: {
1190:   Mat_Redundant  *redund = *redundant;
1191:   PetscInt       i;

1194:   if (redund){
1195:     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1196:       ISDestroy(&redund->isrow);
1197:       ISDestroy(&redund->iscol);
1198:       MatDestroySubMatrices(1,&redund->matseq);
1199:     } else {
1200:       PetscFree2(redund->send_rank,redund->recv_rank);
1201:       PetscFree(redund->sbuf_j);
1202:       PetscFree(redund->sbuf_a);
1203:       for (i=0; i<redund->nrecvs; i++) {
1204:         PetscFree(redund->rbuf_j[i]);
1205:         PetscFree(redund->rbuf_a[i]);
1206:       }
1207:       PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1208:     }

1210:     if (redund->subcomm) {
1211:       PetscCommDestroy(&redund->subcomm);
1212:     }
1213:     PetscFree(redund);
1214:   }
1215:   return(0);
1216: }

1218: /*@
1219:    MatDestroy - Frees space taken by a matrix.

1221:    Collective on Mat

1223:    Input Parameter:
1224: .  A - the matrix

1226:    Level: beginner

1228: @*/
1229: PetscErrorCode MatDestroy(Mat *A)
1230: {

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

1238:   /* if memory was published with SAWs then destroy it */
1239:   PetscObjectSAWsViewOff((PetscObject)*A);
1240:   if ((*A)->ops->destroy) {
1241:     (*(*A)->ops->destroy)(*A);
1242:   }

1244:   PetscFree((*A)->solvertype);
1245:   MatDestroy_Redundant(&(*A)->redundant);
1246:   MatNullSpaceDestroy(&(*A)->nullsp);
1247:   MatNullSpaceDestroy(&(*A)->transnullsp);
1248:   MatNullSpaceDestroy(&(*A)->nearnullsp);
1249:   MatDestroy(&(*A)->schur);
1250:   PetscLayoutDestroy(&(*A)->rmap);
1251:   PetscLayoutDestroy(&(*A)->cmap);
1252:   PetscHeaderDestroy(A);
1253:   return(0);
1254: }

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

1261:    Not Collective

1263:    Input Parameters:
1264: +  mat - the matrix
1265: .  v - a logically two-dimensional array of values
1266: .  m, idxm - the number of rows and their global indices
1267: .  n, idxn - the number of columns and their global indices
1268: -  addv - either ADD_VALUES or INSERT_VALUES, where
1269:    ADD_VALUES adds values to any existing entries, and
1270:    INSERT_VALUES replaces existing entries with new values

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

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

1278:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1279:    options cannot be mixed without intervening calls to the assembly
1280:    routines.

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

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

1290:    Efficiency Alert:
1291:    The routine MatSetValuesBlocked() may offer much better efficiency
1292:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1294:    Level: beginner

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

1300:    Concepts: matrices^putting entries in

1302: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1303:           InsertMode, INSERT_VALUES, ADD_VALUES
1304: @*/
1305: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1306: {
1308: #if defined(PETSC_USE_DEBUG)
1309:   PetscInt       i,j;
1310: #endif

1315:   if (!m || !n) return(0); /* no values to insert */
1319:   MatCheckPreallocated(mat,1);
1320:   if (mat->insertmode == NOT_SET_VALUES) {
1321:     mat->insertmode = addv;
1322:   }
1323: #if defined(PETSC_USE_DEBUG)
1324:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1325:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1326:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);

1328:   for (i=0; i<m; i++) {
1329:     for (j=0; j<n; j++) {
1330:       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1331: #if defined(PETSC_USE_COMPLEX)
1332:         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]);
1333: #else
1334:         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1335: #endif
1336:     }
1337:   }
1338: #endif

1340:   if (mat->assembled) {
1341:     mat->was_assembled = PETSC_TRUE;
1342:     mat->assembled     = PETSC_FALSE;
1343:   }
1344:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1345:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1346:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1347: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
1348:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1349:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1350:   }
1351: #endif
1352:   return(0);
1353: }


1356: /*@
1357:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1358:         values into a matrix

1360:    Not Collective

1362:    Input Parameters:
1363: +  mat - the matrix
1364: .  row - the (block) row to set
1365: -  v - a logically two-dimensional array of values

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

1370:    All the nonzeros in the row must be provided

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

1374:    The row must belong to this process

1376:    Level: intermediate

1378:    Concepts: matrices^putting entries in

1380: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1381:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1382: @*/
1383: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1384: {
1386:   PetscInt       globalrow;

1392:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1393:   MatSetValuesRow(mat,globalrow,v);
1394: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
1395:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1396:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1397:   }
1398: #endif
1399:   return(0);
1400: }

1402: /*@
1403:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1404:         values into a matrix

1406:    Not Collective

1408:    Input Parameters:
1409: +  mat - the matrix
1410: .  row - the (block) row to set
1411: -  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

1413:    Notes:
1414:    The values, v, are column-oriented for the block version.

1416:    All the nonzeros in the row must be provided

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

1420:    The row must belong to this process

1422:    Level: advanced

1424:    Concepts: matrices^putting entries in

1426: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1427:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1428: @*/
1429: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1430: {

1436:   MatCheckPreallocated(mat,1);
1438: #if defined(PETSC_USE_DEBUG)
1439:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1440:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1441: #endif
1442:   mat->insertmode = INSERT_VALUES;

1444:   if (mat->assembled) {
1445:     mat->was_assembled = PETSC_TRUE;
1446:     mat->assembled     = PETSC_FALSE;
1447:   }
1448:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1449:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1450:   (*mat->ops->setvaluesrow)(mat,row,v);
1451:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1452: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
1453:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1454:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1455:   }
1456: #endif
1457:   return(0);
1458: }

1460: /*@
1461:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1462:      Using structured grid indexing

1464:    Not Collective

1466:    Input Parameters:
1467: +  mat - the matrix
1468: .  m - number of rows being entered
1469: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1470: .  n - number of columns being entered
1471: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1472: .  v - a logically two-dimensional array of values
1473: -  addv - either ADD_VALUES or INSERT_VALUES, where
1474:    ADD_VALUES adds values to any existing entries, and
1475:    INSERT_VALUES replaces existing entries with new values

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

1480:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1481:    options cannot be mixed without intervening calls to the assembly
1482:    routines.

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

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

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

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

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

1500:    In Fortran idxm and idxn should be declared as
1501: $     MatStencil idxm(4,m),idxn(4,n)
1502:    and the values inserted using
1503: $    idxm(MatStencil_i,1) = i
1504: $    idxm(MatStencil_j,1) = j
1505: $    idxm(MatStencil_k,1) = k
1506: $    idxm(MatStencil_c,1) = c
1507:    etc

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

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

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

1520:    Efficiency Alert:
1521:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1522:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1524:    Level: beginner

1526:    Concepts: matrices^putting entries in

1528: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1529:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1530: @*/
1531: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1532: {
1534:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1535:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1536:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1546:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1547:     jdxm = buf; jdxn = buf+m;
1548:   } else {
1549:     PetscMalloc2(m,&bufm,n,&bufn);
1550:     jdxm = bufm; jdxn = bufn;
1551:   }
1552:   for (i=0; i<m; i++) {
1553:     for (j=0; j<3-sdim; j++) dxm++;
1554:     tmp = *dxm++ - starts[0];
1555:     for (j=0; j<dim-1; j++) {
1556:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1557:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1558:     }
1559:     if (mat->stencil.noc) dxm++;
1560:     jdxm[i] = tmp;
1561:   }
1562:   for (i=0; i<n; i++) {
1563:     for (j=0; j<3-sdim; j++) dxn++;
1564:     tmp = *dxn++ - starts[0];
1565:     for (j=0; j<dim-1; j++) {
1566:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1567:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1568:     }
1569:     if (mat->stencil.noc) dxn++;
1570:     jdxn[i] = tmp;
1571:   }
1572:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1573:   PetscFree2(bufm,bufn);
1574:   return(0);
1575: }

1577: /*@
1578:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1579:      Using structured grid indexing

1581:    Not Collective

1583:    Input Parameters:
1584: +  mat - the matrix
1585: .  m - number of rows being entered
1586: .  idxm - grid coordinates for matrix rows being entered
1587: .  n - number of columns being entered
1588: .  idxn - grid coordinates for matrix columns being entered
1589: .  v - a logically two-dimensional array of values
1590: -  addv - either ADD_VALUES or INSERT_VALUES, where
1591:    ADD_VALUES adds values to any existing entries, and
1592:    INSERT_VALUES replaces existing entries with new values

1594:    Notes:
1595:    By default the values, v, are row-oriented and unsorted.
1596:    See MatSetOption() for other options.

1598:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1599:    options cannot be mixed without intervening calls to the assembly
1600:    routines.

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

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

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

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

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

1618:    In Fortran idxm and idxn should be declared as
1619: $     MatStencil idxm(4,m),idxn(4,n)
1620:    and the values inserted using
1621: $    idxm(MatStencil_i,1) = i
1622: $    idxm(MatStencil_j,1) = j
1623: $    idxm(MatStencil_k,1) = k
1624:    etc

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

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

1634:    Level: beginner

1636:    Concepts: matrices^putting entries in

1638: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1639:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1640:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1641: @*/
1642: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1643: {
1645:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1646:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1647:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1657:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1658:     jdxm = buf; jdxn = buf+m;
1659:   } else {
1660:     PetscMalloc2(m,&bufm,n,&bufn);
1661:     jdxm = bufm; jdxn = bufn;
1662:   }
1663:   for (i=0; i<m; i++) {
1664:     for (j=0; j<3-sdim; j++) dxm++;
1665:     tmp = *dxm++ - starts[0];
1666:     for (j=0; j<sdim-1; j++) {
1667:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1668:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1669:     }
1670:     dxm++;
1671:     jdxm[i] = tmp;
1672:   }
1673:   for (i=0; i<n; i++) {
1674:     for (j=0; j<3-sdim; j++) dxn++;
1675:     tmp = *dxn++ - starts[0];
1676:     for (j=0; j<sdim-1; j++) {
1677:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1678:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1679:     }
1680:     dxn++;
1681:     jdxn[i] = tmp;
1682:   }
1683:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1684:   PetscFree2(bufm,bufn);
1685: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
1686:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1687:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1688:   }
1689: #endif
1690:   return(0);
1691: }

1693: /*@
1694:    MatSetStencil - Sets the grid information for setting values into a matrix via
1695:         MatSetValuesStencil()

1697:    Not Collective

1699:    Input Parameters:
1700: +  mat - the matrix
1701: .  dim - dimension of the grid 1, 2, or 3
1702: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1703: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1704: -  dof - number of degrees of freedom per node


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

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

1713:    Level: beginner

1715:    Concepts: matrices^putting entries in

1717: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1718:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1719: @*/
1720: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1721: {
1722:   PetscInt i;


1729:   mat->stencil.dim = dim + (dof > 1);
1730:   for (i=0; i<dim; i++) {
1731:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1732:     mat->stencil.starts[i] = starts[dim-i-1];
1733:   }
1734:   mat->stencil.dims[dim]   = dof;
1735:   mat->stencil.starts[dim] = 0;
1736:   mat->stencil.noc         = (PetscBool)(dof == 1);
1737:   return(0);
1738: }

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

1743:    Not Collective

1745:    Input Parameters:
1746: +  mat - the matrix
1747: .  v - a logically two-dimensional array of values
1748: .  m, idxm - the number of block rows and their global block indices
1749: .  n, idxn - the number of block columns and their global block indices
1750: -  addv - either ADD_VALUES or INSERT_VALUES, where
1751:    ADD_VALUES adds values to any existing entries, and
1752:    INSERT_VALUES replaces existing entries with new values

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

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

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

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

1770:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1771:    options cannot be mixed without intervening calls to the assembly
1772:    routines.

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

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

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

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

1803:    Level: intermediate

1805:    Concepts: matrices^putting entries in blocked

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

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

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

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

1872:    Not Collective; currently only returns a local block

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

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

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

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

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

1896:    Level: advanced

1898:    Concepts: matrices^accessing values

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

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

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

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

1928:   Not Collective

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

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

1940:   Level: advanced

1942:   Concepts: matrices^putting entries in

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

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

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

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

1978:    Not Collective

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

1985:    Level: intermediate

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

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


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


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

2015:    Not Collective

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

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

2024:    Level: advanced

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

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

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

2046:    Not Collective

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

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

2055:    Level: advanced

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

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

2075:    Not Collective

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

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

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

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

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

2099:    Level: intermediate

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

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

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

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

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

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

2164:    Not Collective

2166:    Input Parameters:
2167: +  x - the matrix
2168: .  nrow, irow - number of rows and their local indices
2169: .  ncol, icol - number of columns and their local indices
2170: .  y -  a logically two-dimensional array of values
2171: -  addv - either INSERT_VALUES or ADD_VALUES, where
2172:    ADD_VALUES adds values to any existing entries, and
2173:    INSERT_VALUES replaces existing entries with new values

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

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

2182:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2183:    options cannot be mixed without intervening calls to the assembly
2184:    routines.

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

2189:    Level: intermediate

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

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

2197: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2198:            MatSetValuesLocal(),  MatSetValuesBlocked()
2199: @*/
2200: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2201: {

2207:   MatCheckPreallocated(mat,1);
2208:   if (!nrow || !ncol) return(0); /* no values to insert */
2212:   if (mat->insertmode == NOT_SET_VALUES) {
2213:     mat->insertmode = addv;
2214:   }
2215: #if defined(PETSC_USE_DEBUG)
2216:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2217:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2218:   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);
2219: #endif

2221:   if (mat->assembled) {
2222:     mat->was_assembled = PETSC_TRUE;
2223:     mat->assembled     = PETSC_FALSE;
2224:   }
2225:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2226:   if (mat->ops->setvaluesblockedlocal) {
2227:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2228:   } else {
2229:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2230:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2231:       irowm = buf; icolm = buf + nrow;
2232:     } else {
2233:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
2234:       irowm = bufr; icolm = bufc;
2235:     }
2236:     ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2237:     ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2238:     MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2239:     PetscFree2(bufr,bufc);
2240:   }
2241:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2242: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
2243:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2244:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2245:   }
2246: #endif
2247:   return(0);
2248: }

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

2253:    Collective on Mat and Vec

2255:    Input Parameters:
2256: +  mat - the matrix
2257: -  x   - the vector to be multiplied

2259:    Output Parameters:
2260: .  y - the result

2262:    Notes:
2263:    The vectors x and y cannot be the same.  I.e., one cannot
2264:    call MatMult(A,y,y).

2266:    Level: developer

2268:    Concepts: matrix-vector product

2270: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2271: @*/
2272: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2273: {


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

2287:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2288:   (*mat->ops->multdiagonalblock)(mat,x,y);
2289:   PetscObjectStateIncrease((PetscObject)y);
2290:   return(0);
2291: }

2293: /* --------------------------------------------------------*/
2294: /*@
2295:    MatMult - Computes the matrix-vector product, y = Ax.

2297:    Neighbor-wise Collective on Mat and Vec

2299:    Input Parameters:
2300: +  mat - the matrix
2301: -  x   - the vector to be multiplied

2303:    Output Parameters:
2304: .  y - the result

2306:    Notes:
2307:    The vectors x and y cannot be the same.  I.e., one cannot
2308:    call MatMult(A,y,y).

2310:    Level: beginner

2312:    Concepts: matrix-vector product

2314: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2315: @*/
2316: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2317: {

2325:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2326:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2327:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2328: #if !defined(PETSC_HAVE_CONSTRAINTS)
2329:   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);
2330:   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);
2331:   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);
2332: #endif
2333:   VecLocked(y,3);
2334:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2335:   MatCheckPreallocated(mat,1);

2337:   VecLockPush(x);
2338:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2339:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2340:   (*mat->ops->mult)(mat,x,y);
2341:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2342:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2343:   VecLockPop(x);
2344:   return(0);
2345: }

2347: /*@
2348:    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.

2350:    Neighbor-wise Collective on Mat and Vec

2352:    Input Parameters:
2353: +  mat - the matrix
2354: -  x   - the vector to be multiplied

2356:    Output Parameters:
2357: .  y - the result

2359:    Notes:
2360:    The vectors x and y cannot be the same.  I.e., one cannot
2361:    call MatMultTranspose(A,y,y).

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

2366:    Level: beginner

2368:    Concepts: matrix vector product^transpose

2370: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2371: @*/
2372: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2373: {


2382:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2383:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2384:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2385: #if !defined(PETSC_HAVE_CONSTRAINTS)
2386:   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);
2387:   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);
2388: #endif
2389:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2390:   MatCheckPreallocated(mat,1);

2392:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2393:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2394:   VecLockPush(x);
2395:   (*mat->ops->multtranspose)(mat,x,y);
2396:   VecLockPop(x);
2397:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2398:   PetscObjectStateIncrease((PetscObject)y);
2399:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2400:   return(0);
2401: }

2403: /*@
2404:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2406:    Neighbor-wise Collective on Mat and Vec

2408:    Input Parameters:
2409: +  mat - the matrix
2410: -  x   - the vector to be multilplied

2412:    Output Parameters:
2413: .  y - the result

2415:    Notes:
2416:    The vectors x and y cannot be the same.  I.e., one cannot
2417:    call MatMultHermitianTranspose(A,y,y).

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

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

2423:    Level: beginner

2425:    Concepts: matrix vector product^transpose

2427: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2428: @*/
2429: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2430: {
2432:   Vec            w;


2440:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2441:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2442:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2443: #if !defined(PETSC_HAVE_CONSTRAINTS)
2444:   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);
2445:   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);
2446: #endif
2447:   MatCheckPreallocated(mat,1);

2449:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2450:   if (mat->ops->multhermitiantranspose) {
2451:     VecLockPush(x);
2452:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2453:     VecLockPop(x);
2454:   } else {
2455:     VecDuplicate(x,&w);
2456:     VecCopy(x,w);
2457:     VecConjugate(w);
2458:     MatMultTranspose(mat,w,y);
2459:     VecDestroy(&w);
2460:     VecConjugate(y);
2461:   }
2462:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2463:   PetscObjectStateIncrease((PetscObject)y);
2464:   return(0);
2465: }

2467: /*@
2468:     MatMultAdd -  Computes v3 = v2 + A * v1.

2470:     Neighbor-wise Collective on Mat and Vec

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

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

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

2483:     Level: beginner

2485:     Concepts: matrix vector product^addition

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


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

2510:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2511:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2512:   VecLockPush(v1);
2513:   (*mat->ops->multadd)(mat,v1,v2,v3);
2514:   VecLockPop(v1);
2515:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2516:   PetscObjectStateIncrease((PetscObject)v3);
2517:   return(0);
2518: }

2520: /*@
2521:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2523:    Neighbor-wise Collective on Mat and Vec

2525:    Input Parameters:
2526: +  mat - the matrix
2527: -  v1, v2 - the vectors

2529:    Output Parameters:
2530: .  v3 - the result

2532:    Notes:
2533:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2534:    call MatMultTransposeAdd(A,v1,v2,v1).

2536:    Level: beginner

2538:    Concepts: matrix vector product^transpose and addition

2540: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2541: @*/
2542: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2543: {


2553:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2554:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2555:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2556:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2557:   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);
2558:   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);
2559:   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);
2560:   MatCheckPreallocated(mat,1);

2562:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2563:   VecLockPush(v1);
2564:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2565:   VecLockPop(v1);
2566:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2567:   PetscObjectStateIncrease((PetscObject)v3);
2568:   return(0);
2569: }

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

2574:    Neighbor-wise Collective on Mat and Vec

2576:    Input Parameters:
2577: +  mat - the matrix
2578: -  v1, v2 - the vectors

2580:    Output Parameters:
2581: .  v3 - the result

2583:    Notes:
2584:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2585:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2587:    Level: beginner

2589:    Concepts: matrix vector product^transpose and addition

2591: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2592: @*/
2593: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2594: {


2604:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2605:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2606:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2607:   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);
2608:   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);
2609:   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);
2610:   MatCheckPreallocated(mat,1);

2612:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2613:   VecLockPush(v1);
2614:   if (mat->ops->multhermitiantransposeadd) {
2615:     (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2616:    } else {
2617:     Vec w,z;
2618:     VecDuplicate(v1,&w);
2619:     VecCopy(v1,w);
2620:     VecConjugate(w);
2621:     VecDuplicate(v3,&z);
2622:     MatMultTranspose(mat,w,z);
2623:     VecDestroy(&w);
2624:     VecConjugate(z);
2625:     VecWAXPY(v3,1.0,v2,z);
2626:     VecDestroy(&z);
2627:   }
2628:   VecLockPop(v1);
2629:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2630:   PetscObjectStateIncrease((PetscObject)v3);
2631:   return(0);
2632: }

2634: /*@
2635:    MatMultConstrained - The inner multiplication routine for a
2636:    constrained matrix P^T A P.

2638:    Neighbor-wise Collective on Mat and Vec

2640:    Input Parameters:
2641: +  mat - the matrix
2642: -  x   - the vector to be multilplied

2644:    Output Parameters:
2645: .  y - the result

2647:    Notes:
2648:    The vectors x and y cannot be the same.  I.e., one cannot
2649:    call MatMult(A,y,y).

2651:    Level: beginner

2653: .keywords: matrix, multiply, matrix-vector product, constraint
2654: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2655: @*/
2656: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2657: {

2664:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2665:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2666:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2667:   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);
2668:   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);
2669:   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);

2671:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2672:   VecLockPush(x);
2673:   (*mat->ops->multconstrained)(mat,x,y);
2674:   VecLockPop(x);
2675:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2676:   PetscObjectStateIncrease((PetscObject)y);
2677:   return(0);
2678: }

2680: /*@
2681:    MatMultTransposeConstrained - The inner multiplication routine for a
2682:    constrained matrix P^T A^T P.

2684:    Neighbor-wise Collective on Mat and Vec

2686:    Input Parameters:
2687: +  mat - the matrix
2688: -  x   - the vector to be multilplied

2690:    Output Parameters:
2691: .  y - the result

2693:    Notes:
2694:    The vectors x and y cannot be the same.  I.e., one cannot
2695:    call MatMult(A,y,y).

2697:    Level: beginner

2699: .keywords: matrix, multiply, matrix-vector product, constraint
2700: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2701: @*/
2702: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2703: {

2710:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2711:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2712:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2713:   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);
2714:   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);

2716:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2717:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2718:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2719:   PetscObjectStateIncrease((PetscObject)y);
2720:   return(0);
2721: }

2723: /*@C
2724:    MatGetFactorType - gets the type of factorization it is

2726:    Note Collective
2727:    as the flag

2729:    Input Parameters:
2730: .  mat - the matrix

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

2735:     Level: intermediate

2737: .seealso:    MatFactorType, MatGetFactor()
2738: @*/
2739: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2740: {
2744:   *t = mat->factortype;
2745:   return(0);
2746: }

2748: /* ------------------------------------------------------------*/
2749: /*@C
2750:    MatGetInfo - Returns information about matrix storage (number of
2751:    nonzeros, memory, etc.).

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

2755:    Input Parameters:
2756: .  mat - the matrix

2758:    Output Parameters:
2759: +  flag - flag indicating the type of parameters to be returned
2760:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2761:    MAT_GLOBAL_SUM - sum over all processors)
2762: -  info - matrix information context

2764:    Notes:
2765:    The MatInfo context contains a variety of matrix data, including
2766:    number of nonzeros allocated and used, number of mallocs during
2767:    matrix assembly, etc.  Additional information for factored matrices
2768:    is provided (such as the fill ratio, number of mallocs during
2769:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2770:    when using the runtime options
2771: $       -info -mat_view ::ascii_info

2773:    Example for C/C++ Users:
2774:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2775:    data within the MatInfo context.  For example,
2776: .vb
2777:       MatInfo info;
2778:       Mat     A;
2779:       double  mal, nz_a, nz_u;

2781:       MatGetInfo(A,MAT_LOCAL,&info);
2782:       mal  = info.mallocs;
2783:       nz_a = info.nz_allocated;
2784: .ve

2786:    Example for Fortran Users:
2787:    Fortran users should declare info as a double precision
2788:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2789:    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2790:    a complete list of parameter names.
2791: .vb
2792:       double  precision info(MAT_INFO_SIZE)
2793:       double  precision mal, nz_a
2794:       Mat     A
2795:       integer ierr

2797:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2798:       mal = info(MAT_INFO_MALLOCS)
2799:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2800: .ve

2802:     Level: intermediate

2804:     Concepts: matrices^getting information on

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

2809: .seealso: MatStashGetInfo()

2811: @*/
2812: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2813: {

2820:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2821:   MatCheckPreallocated(mat,1);
2822:   (*mat->ops->getinfo)(mat,flag,info);
2823:   return(0);
2824: }

2826: /*
2827:    This is used by external packages where it is not easy to get the info from the actual
2828:    matrix factorization.
2829: */
2830: PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2831: {

2835:   PetscMemzero(info,sizeof(MatInfo));
2836:   return(0);
2837: }

2839: /* ----------------------------------------------------------*/

2841: /*@C
2842:    MatLUFactor - Performs in-place LU factorization of matrix.

2844:    Collective on Mat

2846:    Input Parameters:
2847: +  mat - the matrix
2848: .  row - row permutation
2849: .  col - column permutation
2850: -  info - options for factorization, includes
2851: $          fill - expected fill as ratio of original fill.
2852: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2853: $                   Run with the option -info to determine an optimal value to use

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

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

2863:    Level: developer

2865:    Concepts: matrices^LU factorization

2867: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2868:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2873: @*/
2874: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2875: {
2877:   MatFactorInfo  tinfo;

2885:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2886:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2887:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2888:   MatCheckPreallocated(mat,1);
2889:   if (!info) {
2890:     MatFactorInfoInitialize(&tinfo);
2891:     info = &tinfo;
2892:   }

2894:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2895:   (*mat->ops->lufactor)(mat,row,col,info);
2896:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2897:   PetscObjectStateIncrease((PetscObject)mat);
2898:   return(0);
2899: }

2901: /*@C
2902:    MatILUFactor - Performs in-place ILU factorization of matrix.

2904:    Collective on Mat

2906:    Input Parameters:
2907: +  mat - the matrix
2908: .  row - row permutation
2909: .  col - column permutation
2910: -  info - structure containing
2911: $      levels - number of levels of fill.
2912: $      expected fill - as ratio of original fill.
2913: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2914:                 missing diagonal entries)

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

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

2924:    Level: developer

2926:    Concepts: matrices^ILU factorization

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

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

2933: @*/
2934: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2935: {

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

2950:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2951:   (*mat->ops->ilufactor)(mat,row,col,info);
2952:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2953:   PetscObjectStateIncrease((PetscObject)mat);
2954:   return(0);
2955: }

2957: /*@C
2958:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2959:    Call this routine before calling MatLUFactorNumeric().

2961:    Collective on Mat

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


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

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

2980:    Level: developer

2982:    Concepts: matrices^LU symbolic factorization

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

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

2989: @*/
2990: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2991: {

3001:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3002:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3003:   if (!(fact)->ops->lufactorsymbolic) {
3004:     MatSolverType spackage;
3005:     MatFactorGetSolverType(fact,&spackage);
3006:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3007:   }
3008:   MatCheckPreallocated(mat,2);

3010:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
3011:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
3012:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
3013:   PetscObjectStateIncrease((PetscObject)fact);
3014:   return(0);
3015: }

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

3021:    Collective on Mat

3023:    Input Parameters:
3024: +  fact - the factor matrix obtained with MatGetFactor()
3025: .  mat - the matrix
3026: -  info - options for factorization

3028:    Notes:
3029:    See MatLUFactor() for in-place factorization.  See
3030:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

3036:    Level: developer

3038:    Concepts: matrices^LU numeric factorization

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

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

3045: @*/
3046: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3047: {

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

3058:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3059:   MatCheckPreallocated(mat,2);
3060:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
3061:   (fact->ops->lufactornumeric)(fact,mat,info);
3062:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
3063:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3064:   PetscObjectStateIncrease((PetscObject)fact);
3065:   return(0);
3066: }

3068: /*@C
3069:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3070:    symmetric matrix.

3072:    Collective on Mat

3074:    Input Parameters:
3075: +  mat - the matrix
3076: .  perm - row and column permutations
3077: -  f - expected fill as ratio of original fill

3079:    Notes:
3080:    See MatLUFactor() for the nonsymmetric case.  See also
3081:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

3087:    Level: developer

3089:    Concepts: matrices^Cholesky factorization

3091: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3092:           MatGetOrdering()

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

3097: @*/
3098: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3099: {

3107:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3108:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3109:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3110:   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);
3111:   MatCheckPreallocated(mat,1);

3113:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3114:   (*mat->ops->choleskyfactor)(mat,perm,info);
3115:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3116:   PetscObjectStateIncrease((PetscObject)mat);
3117:   return(0);
3118: }

3120: /*@C
3121:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3122:    of a symmetric matrix.

3124:    Collective on Mat

3126:    Input Parameters:
3127: +  fact - the factor matrix obtained with MatGetFactor()
3128: .  mat - the matrix
3129: .  perm - row and column permutations
3130: -  info - options for factorization, includes
3131: $          fill - expected fill as ratio of original fill.
3132: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3133: $                   Run with the option -info to determine an optimal value to use

3135:    Notes:
3136:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3137:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

3143:    Level: developer

3145:    Concepts: matrices^Cholesky symbolic factorization

3147: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3148:           MatGetOrdering()

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

3153: @*/
3154: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3155: {

3164:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3165:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3166:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3167:   if (!(fact)->ops->choleskyfactorsymbolic) {
3168:     MatSolverType spackage;
3169:     MatFactorGetSolverType(fact,&spackage);
3170:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3171:   }
3172:   MatCheckPreallocated(mat,2);

3174:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3175:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3176:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3177:   PetscObjectStateIncrease((PetscObject)fact);
3178:   return(0);
3179: }

3181: /*@C
3182:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3183:    of a symmetric matrix. Call this routine after first calling
3184:    MatCholeskyFactorSymbolic().

3186:    Collective on Mat

3188:    Input Parameters:
3189: +  fact - the factor matrix obtained with MatGetFactor()
3190: .  mat - the initial matrix
3191: .  info - options for factorization
3192: -  fact - the symbolic factor of mat


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

3200:    Level: developer

3202:    Concepts: matrices^Cholesky numeric factorization

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

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

3209: @*/
3210: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3211: {

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

3224:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3225:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3226:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3227:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3228:   PetscObjectStateIncrease((PetscObject)fact);
3229:   return(0);
3230: }

3232: /* ----------------------------------------------------------------*/
3233: /*@
3234:    MatSolve - Solves A x = b, given a factored matrix.

3236:    Neighbor-wise Collective on Mat and Vec

3238:    Input Parameters:
3239: +  mat - the factored matrix
3240: -  b - the right-hand-side vector

3242:    Output Parameter:
3243: .  x - the result vector

3245:    Notes:
3246:    The vectors b and x cannot be the same.  I.e., one cannot
3247:    call MatSolve(A,x,x).

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

3254:    Level: developer

3256:    Concepts: matrices^triangular solves

3258: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3259: @*/
3260: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3261: {

3271:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3272:   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);
3273:   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);
3274:   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);
3275:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3276:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3277:   MatCheckPreallocated(mat,1);

3279:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3280:   if (mat->factorerrortype) {
3281:     PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3282:     VecSetInf(x);
3283:   } else {
3284:     (*mat->ops->solve)(mat,b,x);
3285:   }
3286:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3287:   PetscObjectStateIncrease((PetscObject)x);
3288:   return(0);
3289: }

3291: static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3292: {
3294:   Vec            b,x;
3295:   PetscInt       m,N,i;
3296:   PetscScalar    *bb,*xx;
3297:   PetscBool      flg;

3300:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3301:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3302:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3303:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3305:   MatDenseGetArray(B,&bb);
3306:   MatDenseGetArray(X,&xx);
3307:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
3308:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
3309:   MatCreateVecs(A,&x,&b);
3310:   for (i=0; i<N; i++) {
3311:     VecPlaceArray(b,bb + i*m);
3312:     VecPlaceArray(x,xx + i*m);
3313:     if (trans) {
3314:       MatSolveTranspose(A,b,x);
3315:     } else {
3316:       MatSolve(A,b,x);
3317:     }
3318:     VecResetArray(x);
3319:     VecResetArray(b);
3320:   }
3321:   VecDestroy(&b);
3322:   VecDestroy(&x);
3323:   MatDenseRestoreArray(B,&bb);
3324:   MatDenseRestoreArray(X,&xx);
3325:   return(0);
3326: }

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

3331:    Neighbor-wise Collective on Mat

3333:    Input Parameters:
3334: +  A - the factored matrix
3335: -  B - the right-hand-side matrix  (dense matrix)

3337:    Output Parameter:
3338: .  X - the result matrix (dense matrix)

3340:    Notes:
3341:    The matrices b and x cannot be the same.  I.e., one cannot
3342:    call MatMatSolve(A,x,x).

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

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

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

3355:    Level: developer

3357:    Concepts: matrices^triangular solves

3359: .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3360: @*/
3361: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3362: {

3372:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3373:   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);
3374:   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);
3375:   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");
3376:   if (!A->rmap->N && !A->cmap->N) return(0);
3377:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3378:   MatCheckPreallocated(A,1);

3380:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3381:   if (!A->ops->matsolve) {
3382:     PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3383:     MatMatSolve_Basic(A,B,X,PETSC_FALSE);
3384:   } else {
3385:     (*A->ops->matsolve)(A,B,X);
3386:   }
3387:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3388:   PetscObjectStateIncrease((PetscObject)X);
3389:   return(0);
3390: }

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

3395:    Neighbor-wise Collective on Mat

3397:    Input Parameters:
3398: +  A - the factored matrix
3399: -  B - the right-hand-side matrix  (dense matrix)

3401:    Output Parameter:
3402: .  X - the result matrix (dense matrix)

3404:    Notes:
3405:    The matrices B and X cannot be the same.  I.e., one cannot
3406:    call MatMatSolveTranspose(A,X,X).

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

3414:    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.

3416:    Level: developer

3418:    Concepts: matrices^triangular solves

3420: .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3421: @*/
3422: PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3423: {

3433:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3434:   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);
3435:   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);
3436:   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);
3437:   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");
3438:   if (!A->rmap->N && !A->cmap->N) return(0);
3439:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3440:   MatCheckPreallocated(A,1);

3442:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3443:   if (!A->ops->matsolvetranspose) {
3444:     PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);
3445:     MatMatSolve_Basic(A,B,X,PETSC_TRUE);
3446:   } else {
3447:     (*A->ops->matsolvetranspose)(A,B,X);
3448:   }
3449:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3450:   PetscObjectStateIncrease((PetscObject)X);
3451:   return(0);
3452: }

3454: /*@
3455:    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.

3457:    Neighbor-wise Collective on Mat

3459:    Input Parameters:
3460: +  A - the factored matrix
3461: -  Bt - the transpose of right-hand-side matrix

3463:    Output Parameter:
3464: .  X - the result matrix (dense matrix)

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

3472:    For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve().

3474:    Level: developer

3476:    Concepts: matrices^triangular solves

3478: .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3479: @*/
3480: PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3481: {


3492:   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3493:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3494:   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);
3495:   if (A->rmap->N != Bt->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %D %D",A->rmap->N,Bt->cmap->N);
3496:   if (X->cmap->N < Bt->rmap->N) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix");
3497:   if (!A->rmap->N && !A->cmap->N) return(0);
3498:   MatCheckPreallocated(A,1);

3500:   PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);
3501:   if (A->ops->mattransposesolve) {
3502:     (*A->ops->mattransposesolve)(A,Bt,X);
3503:   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeSolve() is not supported for the input matrix types");
3504:   PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);
3505:   PetscObjectStateIncrease((PetscObject)X);
3506:   return(0);
3507: }

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

3513:    Neighbor-wise Collective on Mat and Vec

3515:    Input Parameters:
3516: +  mat - the factored matrix
3517: -  b - the right-hand-side vector

3519:    Output Parameter:
3520: .  x - the result vector

3522:    Notes:
3523:    MatSolve() should be used for most applications, as it performs
3524:    a forward solve followed by a backward solve.

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

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

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

3539:    Level: developer

3541:    Concepts: matrices^forward solves

3543: .seealso: MatSolve(), MatBackwardSolve()
3544: @*/
3545: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3546: {

3556:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3557:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3558:   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);
3559:   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);
3560:   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);
3561:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3562:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3563:   MatCheckPreallocated(mat,1);
3564:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3565:   (*mat->ops->forwardsolve)(mat,b,x);
3566:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3567:   PetscObjectStateIncrease((PetscObject)x);
3568:   return(0);
3569: }

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

3575:    Neighbor-wise Collective on Mat and Vec

3577:    Input Parameters:
3578: +  mat - the factored matrix
3579: -  b - the right-hand-side vector

3581:    Output Parameter:
3582: .  x - the result vector

3584:    Notes:
3585:    MatSolve() should be used for most applications, as it performs
3586:    a forward solve followed by a backward solve.

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

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

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

3601:    Level: developer

3603:    Concepts: matrices^backward solves

3605: .seealso: MatSolve(), MatForwardSolve()
3606: @*/
3607: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3608: {

3618:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3619:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3620:   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);
3621:   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);
3622:   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);
3623:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3624:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3625:   MatCheckPreallocated(mat,1);

3627:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3628:   (*mat->ops->backwardsolve)(mat,b,x);
3629:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3630:   PetscObjectStateIncrease((PetscObject)x);
3631:   return(0);
3632: }

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

3637:    Neighbor-wise Collective on Mat and Vec

3639:    Input Parameters:
3640: +  mat - the factored matrix
3641: .  b - the right-hand-side vector
3642: -  y - the vector to be added to

3644:    Output Parameter:
3645: .  x - the result vector

3647:    Notes:
3648:    The vectors b and x cannot be the same.  I.e., one cannot
3649:    call MatSolveAdd(A,x,y,x).

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

3655:    Level: developer

3657:    Concepts: matrices^triangular solves

3659: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3660: @*/
3661: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3662: {
3663:   PetscScalar    one = 1.0;
3664:   Vec            tmp;

3676:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3677:   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);
3678:   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);
3679:   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);
3680:   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);
3681:   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);
3682:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3683:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3684:   MatCheckPreallocated(mat,1);

3686:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3687:   if (mat->ops->solveadd) {
3688:     (*mat->ops->solveadd)(mat,b,y,x);
3689:   } else {
3690:     /* do the solve then the add manually */
3691:     if (x != y) {
3692:       MatSolve(mat,b,x);
3693:       VecAXPY(x,one,y);
3694:     } else {
3695:       VecDuplicate(x,&tmp);
3696:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3697:       VecCopy(x,tmp);
3698:       MatSolve(mat,b,x);
3699:       VecAXPY(x,one,tmp);
3700:       VecDestroy(&tmp);
3701:     }
3702:   }
3703:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3704:   PetscObjectStateIncrease((PetscObject)x);
3705:   return(0);
3706: }

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

3711:    Neighbor-wise Collective on Mat and Vec

3713:    Input Parameters:
3714: +  mat - the factored matrix
3715: -  b - the right-hand-side vector

3717:    Output Parameter:
3718: .  x - the result vector

3720:    Notes:
3721:    The vectors b and x cannot be the same.  I.e., one cannot
3722:    call MatSolveTranspose(A,x,x).

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

3730:    Concepts: matrices^triangular solves

3732: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3733: @*/
3734: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3735: {

3745:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3746:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3747:   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);
3748:   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);
3749:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3750:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3751:   MatCheckPreallocated(mat,1);
3752:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3753:   if (mat->factorerrortype) {
3754:     PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3755:     VecSetInf(x);
3756:   } else {
3757:     (*mat->ops->solvetranspose)(mat,b,x);
3758:   }
3759:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3760:   PetscObjectStateIncrease((PetscObject)x);
3761:   return(0);
3762: }

3764: /*@
3765:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3766:                       factored matrix.

3768:    Neighbor-wise Collective on Mat and Vec

3770:    Input Parameters:
3771: +  mat - the factored matrix
3772: .  b - the right-hand-side vector
3773: -  y - the vector to be added to

3775:    Output Parameter:
3776: .  x - the result vector

3778:    Notes:
3779:    The vectors b and x cannot be the same.  I.e., one cannot
3780:    call MatSolveTransposeAdd(A,x,y,x).

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

3786:    Level: developer

3788:    Concepts: matrices^triangular solves

3790: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3791: @*/
3792: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3793: {
3794:   PetscScalar    one = 1.0;
3796:   Vec            tmp;

3807:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3808:   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);
3809:   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);
3810:   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);
3811:   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);
3812:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3813:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3814:   MatCheckPreallocated(mat,1);

3816:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3817:   if (mat->ops->solvetransposeadd) {
3818:     if (mat->factorerrortype) {
3819:       PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3820:       VecSetInf(x);
3821:     } else {
3822:       (*mat->ops->solvetransposeadd)(mat,b,y,x);
3823:     }
3824:   } else {
3825:     /* do the solve then the add manually */
3826:     if (x != y) {
3827:       MatSolveTranspose(mat,b,x);
3828:       VecAXPY(x,one,y);
3829:     } else {
3830:       VecDuplicate(x,&tmp);
3831:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3832:       VecCopy(x,tmp);
3833:       MatSolveTranspose(mat,b,x);
3834:       VecAXPY(x,one,tmp);
3835:       VecDestroy(&tmp);
3836:     }
3837:   }
3838:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3839:   PetscObjectStateIncrease((PetscObject)x);
3840:   return(0);
3841: }
3842: /* ----------------------------------------------------------------*/

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

3847:    Neighbor-wise Collective on Mat and Vec

3849:    Input Parameters:
3850: +  mat - the matrix
3851: .  b - the right hand side
3852: .  omega - the relaxation factor
3853: .  flag - flag indicating the type of SOR (see below)
3854: .  shift -  diagonal shift
3855: .  its - the number of iterations
3856: -  lits - the number of local iterations

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

3861:    SOR Flags:
3862: .     SOR_FORWARD_SWEEP - forward SOR
3863: .     SOR_BACKWARD_SWEEP - backward SOR
3864: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3865: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3866: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3867: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3868: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3869:          upper/lower triangular part of matrix to
3870:          vector (with omega)
3871: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3873:    Notes:
3874:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3875:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3876:    on each processor.

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

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

3884:    Notes for Advanced Users:
3885:    The flags are implemented as bitwise inclusive or operations.
3886:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3887:    to specify a zero initial guess for SSOR.

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

3893:    Vectors x and b CANNOT be the same

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

3897:    Level: developer

3899:    Concepts: matrices^relaxation
3900:    Concepts: matrices^SOR
3901:    Concepts: matrices^Gauss-Seidel

3903: @*/
3904: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3905: {

3915:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3916:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3917:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3918:   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);
3919:   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);
3920:   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);
3921:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3922:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3923:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3925:   MatCheckPreallocated(mat,1);
3926:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3927:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3928:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3929:   PetscObjectStateIncrease((PetscObject)x);
3930:   return(0);
3931: }

3933: /*
3934:       Default matrix copy routine.
3935: */
3936: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3937: {
3938:   PetscErrorCode    ierr;
3939:   PetscInt          i,rstart = 0,rend = 0,nz;
3940:   const PetscInt    *cwork;
3941:   const PetscScalar *vwork;

3944:   if (B->assembled) {
3945:     MatZeroEntries(B);
3946:   }
3947:   MatGetOwnershipRange(A,&rstart,&rend);
3948:   for (i=rstart; i<rend; i++) {
3949:     MatGetRow(A,i,&nz,&cwork,&vwork);
3950:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3951:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3952:   }
3953:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3954:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3955:   return(0);
3956: }

3958: /*@
3959:    MatCopy - Copys a matrix to another matrix.

3961:    Collective on Mat

3963:    Input Parameters:
3964: +  A - the matrix
3965: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3967:    Output Parameter:
3968: .  B - where the copy is put

3970:    Notes:
3971:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3972:    same nonzero pattern or the routine will crash.

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

3978:    Level: intermediate

3980:    Concepts: matrices^copying

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

3984: @*/
3985: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3986: {
3988:   PetscInt       i;

3996:   MatCheckPreallocated(B,2);
3997:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3998:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3999:   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);
4000:   MatCheckPreallocated(A,1);
4001:   if (A == B) return(0);

4003:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
4004:   if (A->ops->copy) {
4005:     (*A->ops->copy)(A,B,str);
4006:   } else { /* generic conversion */
4007:     MatCopy_Basic(A,B,str);
4008:   }

4010:   B->stencil.dim = A->stencil.dim;
4011:   B->stencil.noc = A->stencil.noc;
4012:   for (i=0; i<=A->stencil.dim; i++) {
4013:     B->stencil.dims[i]   = A->stencil.dims[i];
4014:     B->stencil.starts[i] = A->stencil.starts[i];
4015:   }

4017:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
4018:   PetscObjectStateIncrease((PetscObject)B);
4019:   return(0);
4020: }

4022: /*@C
4023:    MatConvert - Converts a matrix to another matrix, either of the same
4024:    or different type.

4026:    Collective on Mat

4028:    Input Parameters:
4029: +  mat - the matrix
4030: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4031:    same type as the original matrix.
4032: -  reuse - denotes if the destination matrix is to be created or reused.
4033:    Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use
4034:    MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused).

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

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

4044:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4045:    the MPI communicator of the generated matrix is always the same as the communicator
4046:    of the input matrix.

4048:    Level: intermediate

4050:    Concepts: matrices^converting between storage formats

4052: .seealso: MatCopy(), MatDuplicate()
4053: @*/
4054: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4055: {
4057:   PetscBool      sametype,issame,flg;
4058:   char           convname[256],mtype[256];
4059:   Mat            B;

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

4069:   PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
4070:   if (flg) {
4071:     newtype = mtype;
4072:   }
4073:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
4074:   PetscStrcmp(newtype,"same",&issame);
4075:   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4076:   if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX");

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

4080:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4081:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
4082:   } else {
4083:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4084:     const char     *prefix[3] = {"seq","mpi",""};
4085:     PetscInt       i;
4086:     /*
4087:        Order of precedence:
4088:        1) See if a specialized converter is known to the current matrix.
4089:        2) See if a specialized converter is known to the desired matrix class.
4090:        3) See if a good general converter is registered for the desired class
4091:           (as of 6/27/03 only MATMPIADJ falls into this category).
4092:        4) See if a good general converter is known for the current matrix.
4093:        5) Use a really basic converter.
4094:     */

4096:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4097:     for (i=0; i<3; i++) {
4098:       PetscStrncpy(convname,"MatConvert_",sizeof(convname));
4099:       PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));
4100:       PetscStrlcat(convname,"_",sizeof(convname));
4101:       PetscStrlcat(convname,prefix[i],sizeof(convname));
4102:       PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));
4103:       PetscStrlcat(convname,"_C",sizeof(convname));
4104:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4105:       if (conv) goto foundconv;
4106:     }

4108:     /* 2)  See if a specialized converter is known to the desired matrix class. */
4109:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
4110:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
4111:     MatSetType(B,newtype);
4112:     for (i=0; i<3; i++) {
4113:       PetscStrncpy(convname,"MatConvert_",sizeof(convname));
4114:       PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));
4115:       PetscStrlcat(convname,"_",sizeof(convname));
4116:       PetscStrlcat(convname,prefix[i],sizeof(convname));
4117:       PetscStrlcat(convname,newtype,sizeof(convname));
4118:       PetscStrlcat(convname,"_C",sizeof(convname));
4119:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
4120:       if (conv) {
4121:         MatDestroy(&B);
4122:         goto foundconv;
4123:       }
4124:     }

4126:     /* 3) See if a good general converter is registered for the desired class */
4127:     conv = B->ops->convertfrom;
4128:     MatDestroy(&B);
4129:     if (conv) goto foundconv;

4131:     /* 4) See if a good general converter is known for the current matrix */
4132:     if (mat->ops->convert) {
4133:       conv = mat->ops->convert;
4134:     }
4135:     if (conv) goto foundconv;

4137:     /* 5) Use a really basic converter. */
4138:     conv = MatConvert_Basic;

4140: foundconv:
4141:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4142:     (*conv)(mat,newtype,reuse,M);
4143:     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4144:       /* the block sizes must be same if the mappings are copied over */
4145:       (*M)->rmap->bs = mat->rmap->bs;
4146:       (*M)->cmap->bs = mat->cmap->bs;
4147:       PetscObjectReference((PetscObject)mat->rmap->mapping);
4148:       PetscObjectReference((PetscObject)mat->cmap->mapping);
4149:       (*M)->rmap->mapping = mat->rmap->mapping;
4150:       (*M)->cmap->mapping = mat->cmap->mapping;
4151:     }
4152:     (*M)->stencil.dim = mat->stencil.dim;
4153:     (*M)->stencil.noc = mat->stencil.noc;
4154:     for (i=0; i<=mat->stencil.dim; i++) {
4155:       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4156:       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4157:     }
4158:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4159:   }
4160:   PetscObjectStateIncrease((PetscObject)*M);

4162:   /* Copy Mat options */
4163:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
4164:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
4165:   return(0);
4166: }

4168: /*@C
4169:    MatFactorGetSolverType - Returns name of the package providing the factorization routines

4171:    Not Collective

4173:    Input Parameter:
4174: .  mat - the matrix, must be a factored matrix

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

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

4183:    Level: intermediate

4185: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4186: @*/
4187: PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4188: {
4189:   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);

4194:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4195:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);
4196:   if (!conv) {
4197:     *type = MATSOLVERPETSC;
4198:   } else {
4199:     (*conv)(mat,type);
4200:   }
4201:   return(0);
4202: }

4204: typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4205: struct _MatSolverTypeForSpecifcType {
4206:   MatType                        mtype;
4207:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4208:   MatSolverTypeForSpecifcType next;
4209: };

4211: typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4212: struct _MatSolverTypeHolder {
4213:   char                           *name;
4214:   MatSolverTypeForSpecifcType handlers;
4215:   MatSolverTypeHolder         next;
4216: };

4218: static MatSolverTypeHolder MatSolverTypeHolders = NULL;

4220: /*@C
4221:    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type

4223:    Input Parameters:
4224: +    package - name of the package, for example petsc or superlu
4225: .    mtype - the matrix type that works with this package
4226: .    ftype - the type of factorization supported by the package
4227: -    getfactor - routine that will create the factored matrix ready to be used

4229:     Level: intermediate

4231: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4232: @*/
4233: PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4234: {
4235:   PetscErrorCode              ierr;
4236:   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4237:   PetscBool                   flg;
4238:   MatSolverTypeForSpecifcType inext,iprev = NULL;

4241:   if (!next) {
4242:     PetscNew(&MatSolverTypeHolders);
4243:     PetscStrallocpy(package,&MatSolverTypeHolders->name);
4244:     PetscNew(&MatSolverTypeHolders->handlers);
4245:     PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);
4246:     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4247:     return(0);
4248:   }
4249:   while (next) {
4250:     PetscStrcasecmp(package,next->name,&flg);
4251:     if (flg) {
4252:       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4253:       inext = next->handlers;
4254:       while (inext) {
4255:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4256:         if (flg) {
4257:           inext->getfactor[(int)ftype-1] = getfactor;
4258:           return(0);
4259:         }
4260:         iprev = inext;
4261:         inext = inext->next;
4262:       }
4263:       PetscNew(&iprev->next);
4264:       PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4265:       iprev->next->getfactor[(int)ftype-1] = getfactor;
4266:       return(0);
4267:     }
4268:     prev = next;
4269:     next = next->next;
4270:   }
4271:   PetscNew(&prev->next);
4272:   PetscStrallocpy(package,&prev->next->name);
4273:   PetscNew(&prev->next->handlers);
4274:   PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4275:   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4276:   return(0);
4277: }

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

4282:    Input Parameters:
4283: +    package - name of the package, for example petsc or superlu
4284: .    ftype - the type of factorization supported by the package
4285: -    mtype - the matrix type that works with this package

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

4292:     Level: intermediate

4294: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4295: @*/
4296: PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4297: {
4298:   PetscErrorCode                 ierr;
4299:   MatSolverTypeHolder         next = MatSolverTypeHolders;
4300:   PetscBool                      flg;
4301:   MatSolverTypeForSpecifcType inext;

4304:   if (foundpackage) *foundpackage = PETSC_FALSE;
4305:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4306:   if (getfactor)    *getfactor    = NULL;

4308:   if (package) {
4309:     while (next) {
4310:       PetscStrcasecmp(package,next->name,&flg);
4311:       if (flg) {
4312:         if (foundpackage) *foundpackage = PETSC_TRUE;
4313:         inext = next->handlers;
4314:         while (inext) {
4315:           PetscStrbeginswith(mtype,inext->mtype,&flg);
4316:           if (flg) {
4317:             if (foundmtype) *foundmtype = PETSC_TRUE;
4318:             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4319:             return(0);
4320:           }
4321:           inext = inext->next;
4322:         }
4323:       }
4324:       next = next->next;
4325:     }
4326:   } else {
4327:     while (next) {
4328:       inext = next->handlers;
4329:       while (inext) {
4330:         PetscStrbeginswith(mtype,inext->mtype,&flg);
4331:         if (flg && inext->getfactor[(int)ftype-1]) {
4332:           if (foundpackage) *foundpackage = PETSC_TRUE;
4333:           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4334:           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4335:           return(0);
4336:         }
4337:         inext = inext->next;
4338:       }
4339:       next = next->next;
4340:     }
4341:   }
4342:   return(0);
4343: }

4345: PetscErrorCode MatSolverTypeDestroy(void)
4346: {
4347:   PetscErrorCode              ierr;
4348:   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4349:   MatSolverTypeForSpecifcType inext,iprev;

4352:   while (next) {
4353:     PetscFree(next->name);
4354:     inext = next->handlers;
4355:     while (inext) {
4356:       PetscFree(inext->mtype);
4357:       iprev = inext;
4358:       inext = inext->next;
4359:       PetscFree(iprev);
4360:     }
4361:     prev = next;
4362:     next = next->next;
4363:     PetscFree(prev);
4364:   }
4365:   MatSolverTypeHolders = NULL;
4366:   return(0);
4367: }

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

4372:    Collective on Mat

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

4379:    Output Parameters:
4380: .  f - the factor matrix used with MatXXFactorSymbolic() calls

4382:    Notes:
4383:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4384:      such as pastix, superlu, mumps etc.

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

4388:    Level: intermediate

4390: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4391: @*/
4392: PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4393: {
4394:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4395:   PetscBool      foundpackage,foundmtype;


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

4404:   MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4405:   if (!foundpackage) {
4406:     if (type) {
4407:       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4408:     } else {
4409:       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4410:     }
4411:   }

4413:   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4414:   if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support factorization type %s for  matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);

4416: #if defined(PETSC_USE_COMPLEX)
4417:   if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported");
4418: #endif

4420:   (*conv)(mat,ftype,f);
4421:   return(0);
4422: }

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

4427:    Not Collective

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

4434:    Output Parameter:
4435: .    flg - PETSC_TRUE if the factorization is available

4437:    Notes:
4438:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4439:      such as pastix, superlu, mumps etc.

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

4443:    Level: intermediate

4445: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4446: @*/
4447: PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4448: {
4449:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);


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

4458:   *flg = PETSC_FALSE;
4459:   MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4460:   if (gconv) {
4461:     *flg = PETSC_TRUE;
4462:   }
4463:   return(0);
4464: }

4466:  #include <petscdmtypes.h>

4468: /*@
4469:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4471:    Collective on Mat

4473:    Input Parameters:
4474: +  mat - the matrix
4475: -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4476:         See the manual page for MatDuplicateOption for an explanation of these options.

4478:    Output Parameter:
4479: .  M - pointer to place new matrix

4481:    Level: intermediate

4483:    Concepts: matrices^duplicating

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

4488: .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4489: @*/
4490: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4491: {
4493:   Mat            B;
4494:   PetscInt       i;
4495:   DM             dm;
4496:   void           (*viewf)(void);

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

4506:   *M = 0;
4507:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4508:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4509:   (*mat->ops->duplicate)(mat,op,M);
4510:   B    = *M;

4512:   MatGetOperation(mat,MATOP_VIEW,&viewf);
4513:   if (viewf) {
4514:     MatSetOperation(B,MATOP_VIEW,viewf);
4515:   }

4517:   B->stencil.dim = mat->stencil.dim;
4518:   B->stencil.noc = mat->stencil.noc;
4519:   for (i=0; i<=mat->stencil.dim; i++) {
4520:     B->stencil.dims[i]   = mat->stencil.dims[i];
4521:     B->stencil.starts[i] = mat->stencil.starts[i];
4522:   }

4524:   B->nooffproczerorows = mat->nooffproczerorows;
4525:   B->nooffprocentries  = mat->nooffprocentries;

4527:   PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4528:   if (dm) {
4529:     PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4530:   }
4531:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4532:   PetscObjectStateIncrease((PetscObject)B);
4533:   return(0);
4534: }

4536: /*@
4537:    MatGetDiagonal - Gets the diagonal of a matrix.

4539:    Logically Collective on Mat and Vec

4541:    Input Parameters:
4542: +  mat - the matrix
4543: -  v - the vector for storing the diagonal

4545:    Output Parameter:
4546: .  v - the diagonal of the matrix

4548:    Level: intermediate

4550:    Note:
4551:    Currently only correct in parallel for square matrices.

4553:    Concepts: matrices^accessing diagonals

4555: .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4556: @*/
4557: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4558: {

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

4569:   (*mat->ops->getdiagonal)(mat,v);
4570:   PetscObjectStateIncrease((PetscObject)v);
4571:   return(0);
4572: }

4574: /*@C
4575:    MatGetRowMin - Gets the minimum value (of the real part) of each
4576:         row of the matrix

4578:    Logically Collective on Mat and Vec

4580:    Input Parameters:
4581: .  mat - the matrix

4583:    Output Parameter:
4584: +  v - the vector for storing the maximums
4585: -  idx - the indices of the column found for each row (optional)

4587:    Level: intermediate

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

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

4595:    Concepts: matrices^getting row maximums

4597: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4598:           MatGetRowMax()
4599: @*/
4600: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4601: {

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

4612:   (*mat->ops->getrowmin)(mat,v,idx);
4613:   PetscObjectStateIncrease((PetscObject)v);
4614:   return(0);
4615: }

4617: /*@C
4618:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4619:         row of the matrix

4621:    Logically Collective on Mat and Vec

4623:    Input Parameters:
4624: .  mat - the matrix

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

4630:    Level: intermediate

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

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

4638:    Concepts: matrices^getting row maximums

4640: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4641: @*/
4642: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4643: {

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

4655:   (*mat->ops->getrowminabs)(mat,v,idx);
4656:   PetscObjectStateIncrease((PetscObject)v);
4657:   return(0);
4658: }

4660: /*@C
4661:    MatGetRowMax - Gets the maximum value (of the real part) of each
4662:         row of the matrix

4664:    Logically Collective on Mat and Vec

4666:    Input Parameters:
4667: .  mat - the matrix

4669:    Output Parameter:
4670: +  v - the vector for storing the maximums
4671: -  idx - the indices of the column found for each row (optional)

4673:    Level: intermediate

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

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

4681:    Concepts: matrices^getting row maximums

4683: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4684: @*/
4685: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4686: {

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

4697:   (*mat->ops->getrowmax)(mat,v,idx);
4698:   PetscObjectStateIncrease((PetscObject)v);
4699:   return(0);
4700: }

4702: /*@C
4703:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4704:         row of the matrix

4706:    Logically Collective on Mat and Vec

4708:    Input Parameters:
4709: .  mat - the matrix

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

4715:    Level: intermediate

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

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

4723:    Concepts: matrices^getting row maximums

4725: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4726: @*/
4727: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4728: {

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

4740:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4741:   PetscObjectStateIncrease((PetscObject)v);
4742:   return(0);
4743: }

4745: /*@
4746:    MatGetRowSum - Gets the sum of each row of the matrix

4748:    Logically or Neighborhood Collective on Mat and Vec

4750:    Input Parameters:
4751: .  mat - the matrix

4753:    Output Parameter:
4754: .  v - the vector for storing the sum of rows

4756:    Level: intermediate

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

4761:    Concepts: matrices^getting row sums

4763: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4764: @*/
4765: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4766: {
4767:   Vec            ones;

4774:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4775:   MatCheckPreallocated(mat,1);
4776:   MatCreateVecs(mat,&ones,NULL);
4777:   VecSet(ones,1.);
4778:   MatMult(mat,ones,v);
4779:   VecDestroy(&ones);
4780:   return(0);
4781: }

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

4786:    Collective on Mat

4788:    Input Parameter:
4789: +  mat - the matrix to transpose
4790: -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX

4792:    Output Parameters:
4793: .  B - the transpose

4795:    Notes:
4796:      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B

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

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

4802:    Level: intermediate

4804:    Concepts: matrices^transposing

4806: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4807: @*/
4808: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4809: {

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

4822:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4823:   (*mat->ops->transpose)(mat,reuse,B);
4824:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4825:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4826:   return(0);
4827: }

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

4833:    Collective on Mat

4835:    Input Parameter:
4836: +  A - the matrix to test
4837: -  B - the matrix to test against, this can equal the first parameter

4839:    Output Parameters:
4840: .  flg - the result

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

4847:    Level: intermediate

4849:    Concepts: matrices^transposing, matrix^symmetry

4851: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4852: @*/
4853: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4854: {
4855:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4861:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4862:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4863:   *flg = PETSC_FALSE;
4864:   if (f && g) {
4865:     if (f == g) {
4866:       (*f)(A,B,tol,flg);
4867:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4868:   } else {
4869:     MatType mattype;
4870:     if (!f) {
4871:       MatGetType(A,&mattype);
4872:     } else {
4873:       MatGetType(B,&mattype);
4874:     }
4875:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4876:   }
4877:   return(0);
4878: }

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

4883:    Collective on Mat

4885:    Input Parameter:
4886: +  mat - the matrix to transpose and complex conjugate
4887: -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose

4889:    Output Parameters:
4890: .  B - the Hermitian

4892:    Level: intermediate

4894:    Concepts: matrices^transposing, complex conjugatex

4896: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4897: @*/
4898: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4899: {

4903:   MatTranspose(mat,reuse,B);
4904: #if defined(PETSC_USE_COMPLEX)
4905:   MatConjugate(*B);
4906: #endif
4907:   return(0);
4908: }

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

4913:    Collective on Mat

4915:    Input Parameter:
4916: +  A - the matrix to test
4917: -  B - the matrix to test against, this can equal the first parameter

4919:    Output Parameters:
4920: .  flg - the result

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

4927:    Level: intermediate

4929:    Concepts: matrices^transposing, matrix^symmetry

4931: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4932: @*/
4933: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4934: {
4935:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4941:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4942:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4943:   if (f && g) {
4944:     if (f==g) {
4945:       (*f)(A,B,tol,flg);
4946:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4947:   }
4948:   return(0);
4949: }

4951: /*@
4952:    MatPermute - Creates a new matrix with rows and columns permuted from the
4953:    original.

4955:    Collective on Mat

4957:    Input Parameters:
4958: +  mat - the matrix to permute
4959: .  row - row permutation, each processor supplies only the permutation for its rows
4960: -  col - column permutation, each processor supplies only the permutation for its columns

4962:    Output Parameters:
4963: .  B - the permuted matrix

4965:    Level: advanced

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

4971:    Concepts: matrices^permuting

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

4975: @*/
4976: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4977: {

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

4991:   (*mat->ops->permute)(mat,row,col,B);
4992:   PetscObjectStateIncrease((PetscObject)*B);
4993:   return(0);
4994: }

4996: /*@
4997:    MatEqual - Compares two matrices.

4999:    Collective on Mat

5001:    Input Parameters:
5002: +  A - the first matrix
5003: -  B - the second matrix

5005:    Output Parameter:
5006: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

5008:    Level: intermediate

5010:    Concepts: matrices^equality between
5011: @*/
5012: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5013: {

5023:   MatCheckPreallocated(B,2);
5024:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5025:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5026:   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);
5027:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5028:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5029:   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);
5030:   MatCheckPreallocated(A,1);

5032:   (*A->ops->equal)(A,B,flg);
5033:   return(0);
5034: }

5036: /*@C
5037:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5038:    matrices that are stored as vectors.  Either of the two scaling
5039:    matrices can be NULL.

5041:    Collective on Mat

5043:    Input Parameters:
5044: +  mat - the matrix to be scaled
5045: .  l - the left scaling vector (or NULL)
5046: -  r - the right scaling vector (or NULL)

5048:    Notes:
5049:    MatDiagonalScale() computes A = LAR, where
5050:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5051:    The L scales the rows of the matrix, the R scales the columns of the matrix.

5053:    Level: intermediate

5055:    Concepts: matrices^diagonal scaling
5056:    Concepts: diagonal scaling of matrices

5058: .seealso: MatScale(), MatShift(), MatDiagonalSet()
5059: @*/
5060: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5061: {

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

5074:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5075:   (*mat->ops->diagonalscale)(mat,l,r);
5076:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5077:   PetscObjectStateIncrease((PetscObject)mat);
5078: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5079:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5080:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5081:   }
5082: #endif
5083:   return(0);
5084: }

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

5089:     Logically Collective on Mat

5091:     Input Parameters:
5092: +   mat - the matrix to be scaled
5093: -   a  - the scaling value

5095:     Output Parameter:
5096: .   mat - the scaled matrix

5098:     Level: intermediate

5100:     Concepts: matrices^scaling all entries

5102: .seealso: MatDiagonalScale()
5103: @*/
5104: PetscErrorCode MatScale(Mat mat,PetscScalar a)
5105: {

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

5117:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5118:   if (a != (PetscScalar)1.0) {
5119:     (*mat->ops->scale)(mat,a);
5120:     PetscObjectStateIncrease((PetscObject)mat);
5121: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5122:     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5123:       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5124:     }
5125: #endif
5126:   }
5127:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5128:   return(0);
5129: }

5131: static PetscErrorCode MatNorm_Basic(Mat A,NormType type,PetscReal *nrm)
5132: {

5136:   if (type == NORM_1 || type == NORM_INFINITY) {
5137:     Vec l,r;

5139:     MatCreateVecs(A,&r,&l);
5140:     if (type == NORM_INFINITY) {
5141:       VecSet(r,1.);
5142:       MatMult(A,r,l);
5143:       VecNorm(l,NORM_INFINITY,nrm);
5144:     } else {
5145:       VecSet(l,1.);
5146:       MatMultTranspose(A,l,r);
5147:       VecNorm(r,NORM_INFINITY,nrm);
5148:     }
5149:     VecDestroy(&l);
5150:     VecDestroy(&r);
5151:   } else SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix class %s, norm type %d",((PetscObject)A)->type_name,type);
5152:   return(0);
5153: }

5155: /*@
5156:    MatNorm - Calculates various norms of a matrix.

5158:    Collective on Mat

5160:    Input Parameters:
5161: +  mat - the matrix
5162: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

5164:    Output Parameters:
5165: .  nrm - the resulting norm

5167:    Level: intermediate

5169:    Concepts: matrices^norm
5170:    Concepts: norm^of matrix
5171: @*/
5172: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5173: {


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

5186:   if (!mat->ops->norm) {
5187:     MatNorm_Basic(mat,type,nrm);
5188:   } else {
5189:     (*mat->ops->norm)(mat,type,nrm);
5190:   }
5191:   return(0);
5192: }

5194: /*
5195:      This variable is used to prevent counting of MatAssemblyBegin() that
5196:    are called from within a MatAssemblyEnd().
5197: */
5198: static PetscInt MatAssemblyEnd_InUse = 0;
5199: /*@
5200:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5201:    be called after completing all calls to MatSetValues().

5203:    Collective on Mat

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

5209:    Notes:
5210:    MatSetValues() generally caches the values.  The matrix is ready to
5211:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5212:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5213:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5214:    using the matrix.

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

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

5224:    Level: beginner

5226:    Concepts: matrices^assembling

5228: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5229: @*/
5230: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5231: {

5237:   MatCheckPreallocated(mat,1);
5238:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5239:   if (mat->assembled) {
5240:     mat->was_assembled = PETSC_TRUE;
5241:     mat->assembled     = PETSC_FALSE;
5242:   }
5243:   if (!MatAssemblyEnd_InUse) {
5244:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5245:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5246:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5247:   } else if (mat->ops->assemblybegin) {
5248:     (*mat->ops->assemblybegin)(mat,type);
5249:   }
5250:   return(0);
5251: }

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

5257:    Not Collective

5259:    Input Parameter:
5260: .  mat - the matrix

5262:    Output Parameter:
5263: .  assembled - PETSC_TRUE or PETSC_FALSE

5265:    Level: advanced

5267:    Concepts: matrices^assembled?

5269: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5270: @*/
5271: PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5272: {
5277:   *assembled = mat->assembled;
5278:   return(0);
5279: }

5281: /*@
5282:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5283:    be called after MatAssemblyBegin().

5285:    Collective on Mat

5287:    Input Parameters:
5288: +  mat - the matrix
5289: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5291:    Options Database Keys:
5292: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5293: .  -mat_view ::ascii_info_detail - Prints more detailed info
5294: .  -mat_view - Prints matrix in ASCII format
5295: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5296: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5297: .  -display <name> - Sets display name (default is host)
5298: .  -draw_pause <sec> - Sets number of seconds to pause after display
5299: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 12 Using MATLAB with PETSc )
5300: .  -viewer_socket_machine <machine> - Machine to use for socket
5301: .  -viewer_socket_port <port> - Port number to use for socket
5302: -  -mat_view binary:filename[:append] - Save matrix to file in binary format

5304:    Notes:
5305:    MatSetValues() generally caches the values.  The matrix is ready to
5306:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5307:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5308:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5309:    using the matrix.

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

5315:    Level: beginner

5317: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5318: @*/
5319: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5320: {
5321:   PetscErrorCode  ierr;
5322:   static PetscInt inassm = 0;
5323:   PetscBool       flg    = PETSC_FALSE;


5329:   inassm++;
5330:   MatAssemblyEnd_InUse++;
5331:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5332:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5333:     if (mat->ops->assemblyend) {
5334:       (*mat->ops->assemblyend)(mat,type);
5335:     }
5336:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5337:   } else if (mat->ops->assemblyend) {
5338:     (*mat->ops->assemblyend)(mat,type);
5339:   }

5341:   /* Flush assembly is not a true assembly */
5342:   if (type != MAT_FLUSH_ASSEMBLY) {
5343:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5344:   }
5345:   mat->insertmode = NOT_SET_VALUES;
5346:   MatAssemblyEnd_InUse--;
5347:   PetscObjectStateIncrease((PetscObject)mat);
5348:   if (!mat->symmetric_eternal) {
5349:     mat->symmetric_set              = PETSC_FALSE;
5350:     mat->hermitian_set              = PETSC_FALSE;
5351:     mat->structurally_symmetric_set = PETSC_FALSE;
5352:   }
5353: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5354:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5355:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5356:   }
5357: #endif
5358:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5359:     MatViewFromOptions(mat,NULL,"-mat_view");

5361:     if (mat->checksymmetryonassembly) {
5362:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5363:       if (flg) {
5364:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5365:       } else {
5366:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5367:       }
5368:     }
5369:     if (mat->nullsp && mat->checknullspaceonassembly) {
5370:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5371:     }
5372:   }
5373:   inassm--;
5374:   return(0);
5375: }

5377: /*@
5378:    MatSetOption - Sets a parameter option for a matrix. Some options
5379:    may be specific to certain storage formats.  Some options
5380:    determine how values will be inserted (or added). Sorted,
5381:    row-oriented input will generally assemble the fastest. The default
5382:    is row-oriented.

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

5386:    Input Parameters:
5387: +  mat - the matrix
5388: .  option - the option, one of those listed below (and possibly others),
5389: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5391:   Options Describing Matrix Structure:
5392: +    MAT_SPD - symmetric positive definite
5393: .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5394: .    MAT_HERMITIAN - transpose is the complex conjugation
5395: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5396: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5397:                             you set to be kept with all future use of the matrix
5398:                             including after MatAssemblyBegin/End() which could
5399:                             potentially change the symmetry structure, i.e. you
5400:                             KNOW the matrix will ALWAYS have the property you set.


5403:    Options For Use with MatSetValues():
5404:    Insert a logically dense subblock, which can be
5405: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

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

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

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

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

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

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

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

5459:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5460:    searches during matrix assembly. When this flag is set, the hash table
5461:    is created during the first Matrix Assembly. This hash table is
5462:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5463:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5464:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5465:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5484:    Level: intermediate

5486:    Concepts: matrices^setting options

5488: .seealso:  MatOption, Mat

5490: @*/
5491: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5492: {

5498:   if (op > 0) {
5501:   }

5503:   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);
5504:   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()");

5506:   switch (op) {
5507:   case MAT_NO_OFF_PROC_ENTRIES:
5508:     mat->nooffprocentries = flg;
5509:     return(0);
5510:     break;
5511:   case MAT_SUBSET_OFF_PROC_ENTRIES:
5512:     mat->subsetoffprocentries = flg;
5513:     return(0);
5514:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5515:     mat->nooffproczerorows = flg;
5516:     return(0);
5517:     break;
5518:   case MAT_SPD:
5519:     mat->spd_set = PETSC_TRUE;
5520:     mat->spd     = flg;
5521:     if (flg) {
5522:       mat->symmetric                  = PETSC_TRUE;
5523:       mat->structurally_symmetric     = PETSC_TRUE;
5524:       mat->symmetric_set              = PETSC_TRUE;
5525:       mat->structurally_symmetric_set = PETSC_TRUE;
5526:     }
5527:     break;
5528:   case MAT_SYMMETRIC:
5529:     mat->symmetric = flg;
5530:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5531:     mat->symmetric_set              = PETSC_TRUE;
5532:     mat->structurally_symmetric_set = flg;
5533: #if !defined(PETSC_USE_COMPLEX)
5534:     mat->hermitian     = flg;
5535:     mat->hermitian_set = PETSC_TRUE;
5536: #endif
5537:     break;
5538:   case MAT_HERMITIAN:
5539:     mat->hermitian = flg;
5540:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5541:     mat->hermitian_set              = PETSC_TRUE;
5542:     mat->structurally_symmetric_set = flg;
5543: #if !defined(PETSC_USE_COMPLEX)
5544:     mat->symmetric     = flg;
5545:     mat->symmetric_set = PETSC_TRUE;
5546: #endif
5547:     break;
5548:   case MAT_STRUCTURALLY_SYMMETRIC:
5549:     mat->structurally_symmetric     = flg;
5550:     mat->structurally_symmetric_set = PETSC_TRUE;
5551:     break;
5552:   case MAT_SYMMETRY_ETERNAL:
5553:     mat->symmetric_eternal = flg;
5554:     break;
5555:   case MAT_STRUCTURE_ONLY:
5556:     mat->structure_only = flg;
5557:     break;
5558:   default:
5559:     break;
5560:   }
5561:   if (mat->ops->setoption) {
5562:     (*mat->ops->setoption)(mat,op,flg);
5563:   }
5564:   return(0);
5565: }

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

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

5572:    Input Parameters:
5573: +  mat - the matrix
5574: -  option - the option, this only responds to certain options, check the code for which ones

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

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

5582:    Level: intermediate

5584:    Concepts: matrices^setting options

5586: .seealso:  MatOption, MatSetOption()

5588: @*/
5589: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5590: {

5595:   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);
5596:   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()");

5598:   switch (op) {
5599:   case MAT_NO_OFF_PROC_ENTRIES:
5600:     *flg = mat->nooffprocentries;
5601:     break;
5602:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5603:     *flg = mat->nooffproczerorows;
5604:     break;
5605:   case MAT_SYMMETRIC:
5606:     *flg = mat->symmetric;
5607:     break;
5608:   case MAT_HERMITIAN:
5609:     *flg = mat->hermitian;
5610:     break;
5611:   case MAT_STRUCTURALLY_SYMMETRIC:
5612:     *flg = mat->structurally_symmetric;
5613:     break;
5614:   case MAT_SYMMETRY_ETERNAL:
5615:     *flg = mat->symmetric_eternal;
5616:     break;
5617:   case MAT_SPD:
5618:     *flg = mat->spd;
5619:     break;
5620:   default:
5621:     break;
5622:   }
5623:   return(0);
5624: }

5626: /*@
5627:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5628:    this routine retains the old nonzero structure.

5630:    Logically Collective on Mat

5632:    Input Parameters:
5633: .  mat - the matrix

5635:    Level: intermediate

5637:    Notes:
5638:     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.
5639:    See the Performance chapter of the users manual for information on preallocating matrices.

5641:    Concepts: matrices^zeroing

5643: .seealso: MatZeroRows()
5644: @*/
5645: PetscErrorCode MatZeroEntries(Mat mat)
5646: {

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

5657:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5658:   (*mat->ops->zeroentries)(mat);
5659:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5660:   PetscObjectStateIncrease((PetscObject)mat);
5661: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5662:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5663:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5664:   }
5665: #endif
5666:   return(0);
5667: }

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

5673:    Collective on Mat

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

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

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:    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.

5700:    Level: intermediate

5702:    Concepts: matrices^zeroing rows

5704: .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5705:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5706: @*/
5707: PetscErrorCode MatZeroRowsColumns(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->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5718:   MatCheckPreallocated(mat,1);

5720:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5721:   MatViewFromOptions(mat,NULL,"-mat_view");
5722:   PetscObjectStateIncrease((PetscObject)mat);
5723: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5724:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5725:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5726:   }
5727: #endif
5728:   return(0);
5729: }

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

5735:    Collective on Mat

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

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

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

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

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

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

5761:    Level: intermediate

5763:    Concepts: matrices^zeroing rows

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

5779:   ISGetLocalSize(is,&numRows);
5780:   ISGetIndices(is,&rows);
5781:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5782:   ISRestoreIndices(is,&rows);
5783:   return(0);
5784: }

5786: /*@C
5787:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5788:    of a set of rows of a matrix.

5790:    Collective on Mat

5792:    Input Parameters:
5793: +  mat - the matrix
5794: .  numRows - the number of rows to remove
5795: .  rows - the global row indices
5796: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5797: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5798: -  b - optional vector of right hand side, that will be adjusted by provided solution

5800:    Notes:
5801:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5802:    but does not release memory.  For the dense and block diagonal
5803:    formats this does not alter the nonzero structure.

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

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

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

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

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

5824:    Level: intermediate

5826:    Concepts: matrices^zeroing rows

5828: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5829:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5830: @*/
5831: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5832: {

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

5844:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5845:   MatViewFromOptions(mat,NULL,"-mat_view");
5846:   PetscObjectStateIncrease((PetscObject)mat);
5847: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5848:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5849:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5850:   }
5851: #endif
5852:   return(0);
5853: }

5855: /*@C
5856:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5857:    of a set of rows of a matrix.

5859:    Collective on Mat

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

5868:    Notes:
5869:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5870:    but does not release memory.  For the dense and block diagonal
5871:    formats this does not alter the nonzero structure.

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

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

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

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

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

5892:    Level: intermediate

5894:    Concepts: matrices^zeroing rows

5896: .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5897:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5898: @*/
5899: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5900: {
5901:   PetscInt       numRows;
5902:   const PetscInt *rows;

5909:   ISGetLocalSize(is,&numRows);
5910:   ISGetIndices(is,&rows);
5911:   MatZeroRows(mat,numRows,rows,diag,x,b);
5912:   ISRestoreIndices(is,&rows);
5913:   return(0);
5914: }

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

5920:    Collective on Mat

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

5930:    Notes:
5931:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5932:    but does not release memory.  For the dense and block diagonal
5933:    formats this does not alter the nonzero structure.

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

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

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

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

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

5953:    In Fortran idxm and idxn should be declared as
5954: $     MatStencil idxm(4,m)
5955:    and the values inserted using
5956: $    idxm(MatStencil_i,1) = i
5957: $    idxm(MatStencil_j,1) = j
5958: $    idxm(MatStencil_k,1) = k
5959: $    idxm(MatStencil_c,1) = c
5960:    etc

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

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

5970:    Level: intermediate

5972:    Concepts: matrices^zeroing rows

5974: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5975:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5976: @*/
5977: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5978: {
5979:   PetscInt       dim     = mat->stencil.dim;
5980:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5981:   PetscInt       *dims   = mat->stencil.dims+1;
5982:   PetscInt       *starts = mat->stencil.starts;
5983:   PetscInt       *dxm    = (PetscInt*) rows;
5984:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5992:   PetscMalloc1(numRows, &jdxm);
5993:   for (i = 0; i < numRows; ++i) {
5994:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5995:     for (j = 0; j < 3-sdim; ++j) dxm++;
5996:     /* Local index in X dir */
5997:     tmp = *dxm++ - starts[0];
5998:     /* Loop over remaining dimensions */
5999:     for (j = 0; j < dim-1; ++j) {
6000:       /* If nonlocal, set index to be negative */
6001:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6002:       /* Update local index */
6003:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6004:     }
6005:     /* Skip component slot if necessary */
6006:     if (mat->stencil.noc) dxm++;
6007:     /* Local row number */
6008:     if (tmp >= 0) {
6009:       jdxm[numNewRows++] = tmp;
6010:     }
6011:   }
6012:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
6013:   PetscFree(jdxm);
6014:   return(0);
6015: }

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

6021:    Collective on Mat

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

6031:    Notes:
6032:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6033:    but does not release memory.  For the dense and block diagonal
6034:    formats this does not alter the nonzero structure.

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

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

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

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

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

6054:    In Fortran idxm and idxn should be declared as
6055: $     MatStencil idxm(4,m)
6056:    and the values inserted using
6057: $    idxm(MatStencil_i,1) = i
6058: $    idxm(MatStencil_j,1) = j
6059: $    idxm(MatStencil_k,1) = k
6060: $    idxm(MatStencil_c,1) = c
6061:    etc

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

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

6071:    Level: intermediate

6073:    Concepts: matrices^zeroing rows

6075: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6076:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6077: @*/
6078: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6079: {
6080:   PetscInt       dim     = mat->stencil.dim;
6081:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6082:   PetscInt       *dims   = mat->stencil.dims+1;
6083:   PetscInt       *starts = mat->stencil.starts;
6084:   PetscInt       *dxm    = (PetscInt*) rows;
6085:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


6093:   PetscMalloc1(numRows, &jdxm);
6094:   for (i = 0; i < numRows; ++i) {
6095:     /* Skip unused dimensions (they are ordered k, j, i, c) */
6096:     for (j = 0; j < 3-sdim; ++j) dxm++;
6097:     /* Local index in X dir */
6098:     tmp = *dxm++ - starts[0];
6099:     /* Loop over remaining dimensions */
6100:     for (j = 0; j < dim-1; ++j) {
6101:       /* If nonlocal, set index to be negative */
6102:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6103:       /* Update local index */
6104:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6105:     }
6106:     /* Skip component slot if necessary */
6107:     if (mat->stencil.noc) dxm++;
6108:     /* Local row number */
6109:     if (tmp >= 0) {
6110:       jdxm[numNewRows++] = tmp;
6111:     }
6112:   }
6113:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
6114:   PetscFree(jdxm);
6115:   return(0);
6116: }

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

6122:    Collective on Mat

6124:    Input Parameters:
6125: +  mat - the matrix
6126: .  numRows - the number of rows to remove
6127: .  rows - the global row indices
6128: .  diag - value put in all diagonals of eliminated rows
6129: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6130: -  b - optional vector of right hand side, that will be adjusted by provided solution

6132:    Notes:
6133:    Before calling MatZeroRowsLocal(), the user must first set the
6134:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6136:    For the AIJ matrix formats this removes the old nonzero structure,
6137:    but does not release memory.  For the dense and block diagonal
6138:    formats this does not alter the nonzero structure.

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

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

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

6151:    Level: intermediate

6153:    Concepts: matrices^zeroing

6155: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6156:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6157: @*/
6158: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6159: {

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

6170:   if (mat->ops->zerorowslocal) {
6171:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6172:   } else {
6173:     IS             is, newis;
6174:     const PetscInt *newRows;

6176:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6177:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6178:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6179:     ISGetIndices(newis,&newRows);
6180:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6181:     ISRestoreIndices(newis,&newRows);
6182:     ISDestroy(&newis);
6183:     ISDestroy(&is);
6184:   }
6185:   PetscObjectStateIncrease((PetscObject)mat);
6186: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6187:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6188:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6189:   }
6190: #endif
6191:   return(0);
6192: }

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

6198:    Collective on Mat

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

6207:    Notes:
6208:    Before calling MatZeroRowsLocalIS(), the user must first set the
6209:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6211:    For the AIJ matrix formats this removes the old nonzero structure,
6212:    but does not release memory.  For the dense and block diagonal
6213:    formats this does not alter the nonzero structure.

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

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

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

6226:    Level: intermediate

6228:    Concepts: matrices^zeroing

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

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

6247:   ISGetLocalSize(is,&numRows);
6248:   ISGetIndices(is,&rows);
6249:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6250:   ISRestoreIndices(is,&rows);
6251:   return(0);
6252: }

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

6258:    Collective on Mat

6260:    Input Parameters:
6261: +  mat - the matrix
6262: .  numRows - the number of rows to remove
6263: .  rows - the global row indices
6264: .  diag - value put in all diagonals of eliminated rows
6265: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6266: -  b - optional vector of right hand side, that will be adjusted by provided solution

6268:    Notes:
6269:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6270:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6276:    Level: intermediate

6278:    Concepts: matrices^zeroing

6280: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6281:           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6282: @*/
6283: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6284: {
6286:   IS             is, newis;
6287:   const PetscInt *newRows;

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

6297:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6298:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6299:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6300:   ISGetIndices(newis,&newRows);
6301:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6302:   ISRestoreIndices(newis,&newRows);
6303:   ISDestroy(&newis);
6304:   ISDestroy(&is);
6305:   PetscObjectStateIncrease((PetscObject)mat);
6306: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6307:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6308:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6309:   }
6310: #endif
6311:   return(0);
6312: }

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

6318:    Collective on Mat

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

6327:    Notes:
6328:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6329:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6335:    Level: intermediate

6337:    Concepts: matrices^zeroing

6339: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6340:           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6341: @*/
6342: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6343: {
6345:   PetscInt       numRows;
6346:   const PetscInt *rows;

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

6356:   ISGetLocalSize(is,&numRows);
6357:   ISGetIndices(is,&rows);
6358:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6359:   ISRestoreIndices(is,&rows);
6360:   return(0);
6361: }

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

6366:    Not Collective

6368:    Input Parameter:
6369: .  mat - the matrix

6371:    Output Parameters:
6372: +  m - the number of global rows
6373: -  n - the number of global columns

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

6377:    Level: beginner

6379:    Concepts: matrices^size

6381: .seealso: MatGetLocalSize()
6382: @*/
6383: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6384: {
6387:   if (m) *m = mat->rmap->N;
6388:   if (n) *n = mat->cmap->N;
6389:   return(0);
6390: }

6392: /*@C
6393:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6394:    stored locally.  This information may be implementation dependent, so
6395:    use with care.

6397:    Not Collective

6399:    Input Parameters:
6400: .  mat - the matrix

6402:    Output Parameters:
6403: +  m - the number of local rows
6404: -  n - the number of local columns

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

6408:    Level: beginner

6410:    Concepts: matrices^local size

6412: .seealso: MatGetSize()
6413: @*/
6414: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6415: {
6420:   if (m) *m = mat->rmap->n;
6421:   if (n) *n = mat->cmap->n;
6422:   return(0);
6423: }

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

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

6431:    Input Parameters:
6432: .  mat - the matrix

6434:    Output Parameters:
6435: +  m - the global index of the first local column
6436: -  n - one more than the global index of the last local column

6438:    Notes:
6439:     both output parameters can be NULL on input.

6441:    Level: developer

6443:    Concepts: matrices^column ownership

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

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

6461: /*@C
6462:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6463:    this processor, assuming that the matrix is laid out with the first
6464:    n1 rows on the first processor, the next n2 rows on the second, etc.
6465:    For certain parallel layouts this range may not be well defined.

6467:    Not Collective

6469:    Input Parameters:
6470: .  mat - the matrix

6472:    Output Parameters:
6473: +  m - the global index of the first local row
6474: -  n - one more than the global index of the last local row

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

6481:    Level: beginner

6483:    Concepts: matrices^row ownership

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

6487: @*/
6488: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6489: {
6495:   MatCheckPreallocated(mat,1);
6496:   if (m) *m = mat->rmap->rstart;
6497:   if (n) *n = mat->rmap->rend;
6498:   return(0);
6499: }

6501: /*@C
6502:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6503:    each process

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

6507:    Input Parameters:
6508: .  mat - the matrix

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

6513:    Level: beginner

6515:    Concepts: matrices^row ownership

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

6519: @*/
6520: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6521: {

6527:   MatCheckPreallocated(mat,1);
6528:   PetscLayoutGetRanges(mat->rmap,ranges);
6529:   return(0);
6530: }

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

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

6538:    Input Parameters:
6539: .  mat - the matrix

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

6544:    Level: beginner

6546:    Concepts: matrices^column ownership

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

6550: @*/
6551: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6552: {

6558:   MatCheckPreallocated(mat,1);
6559:   PetscLayoutGetRanges(mat->cmap,ranges);
6560:   return(0);
6561: }

6563: /*@C
6564:    MatGetOwnershipIS - Get row and column ownership as index sets

6566:    Not Collective

6568:    Input Arguments:
6569: .  A - matrix of type Elemental

6571:    Output Arguments:
6572: +  rows - rows in which this process owns elements
6573: .  cols - columns in which this process owns elements

6575:    Level: intermediate

6577: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6578: @*/
6579: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6580: {
6581:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6584:   MatCheckPreallocated(A,1);
6585:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6586:   if (f) {
6587:     (*f)(A,rows,cols);
6588:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6589:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6590:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6591:   }
6592:   return(0);
6593: }

6595: /*@C
6596:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6597:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6598:    to complete the factorization.

6600:    Collective on Mat

6602:    Input Parameters:
6603: +  mat - the matrix
6604: .  row - row permutation
6605: .  column - column permutation
6606: -  info - structure containing
6607: $      levels - number of levels of fill.
6608: $      expected fill - as ratio of original fill.
6609: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6610:                 missing diagonal entries)

6612:    Output Parameters:
6613: .  fact - new matrix that has been symbolically factored

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

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

6622:    Level: developer

6624:   Concepts: matrices^symbolic LU factorization
6625:   Concepts: matrices^factorization
6626:   Concepts: LU^symbolic factorization

6628: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6629:           MatGetOrdering(), MatFactorInfo

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

6634: @*/
6635: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6636: {

6646:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6647:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6648:   if (!(fact)->ops->ilufactorsymbolic) {
6649:     MatSolverType spackage;
6650:     MatFactorGetSolverType(fact,&spackage);
6651:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6652:   }
6653:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6654:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6655:   MatCheckPreallocated(mat,2);

6657:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6658:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6659:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6660:   return(0);
6661: }

6663: /*@C
6664:    MatICCFactorSymbolic - Performs symbolic incomplete
6665:    Cholesky factorization for a symmetric matrix.  Use
6666:    MatCholeskyFactorNumeric() to complete the factorization.

6668:    Collective on Mat

6670:    Input Parameters:
6671: +  mat - the matrix
6672: .  perm - row and column permutation
6673: -  info - structure containing
6674: $      levels - number of levels of fill.
6675: $      expected fill - as ratio of original fill.

6677:    Output Parameter:
6678: .  fact - the factored matrix

6680:    Notes:
6681:    Most users should employ the KSP interface for linear solvers
6682:    instead of working directly with matrix algebra routines such as this.
6683:    See, e.g., KSPCreate().

6685:    Level: developer

6687:   Concepts: matrices^symbolic incomplete Cholesky factorization
6688:   Concepts: matrices^factorization
6689:   Concepts: Cholsky^symbolic factorization

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

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

6696: @*/
6697: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6698: {

6707:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6708:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6709:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6710:   if (!(fact)->ops->iccfactorsymbolic) {
6711:     MatSolverType spackage;
6712:     MatFactorGetSolverType(fact,&spackage);
6713:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6714:   }
6715:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6716:   MatCheckPreallocated(mat,2);

6718:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6719:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6720:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6721:   return(0);
6722: }

6724: /*@C
6725:    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6726:    points to an array of valid matrices, they may be reused to store the new
6727:    submatrices.

6729:    Collective on Mat

6731:    Input Parameters:
6732: +  mat - the matrix
6733: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6734: .  irow, icol - index sets of rows and columns to extract
6735: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6737:    Output Parameter:
6738: .  submat - the array of submatrices

6740:    Notes:
6741:    MatCreateSubMatrices() can extract ONLY sequential submatrices
6742:    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6743:    to extract a parallel submatrix.

6745:    Some matrix types place restrictions on the row and column
6746:    indices, such as that they be sorted or that they be equal to each other.

6748:    The index sets may not have duplicate entries.

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

6754:    When finished using the submatrices, the user should destroy
6755:    them with MatDestroySubMatrices().

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

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

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

6768:    Fortran Note:
6769:    The Fortran interface is slightly different from that given below; it
6770:    requires one to pass in  as submat a Mat (integer) array of size at least n+1.

6772:    Level: advanced

6774:    Concepts: matrices^accessing submatrices
6775:    Concepts: submatrices

6777: .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6778: @*/
6779: PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6780: {
6782:   PetscInt       i;
6783:   PetscBool      eq;

6788:   if (n) {
6793:   }
6795:   if (n && scall == MAT_REUSE_MATRIX) {
6798:   }
6799:   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6800:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6801:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6802:   MatCheckPreallocated(mat,1);

6804:   PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6805:   (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);
6806:   PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6807:   for (i=0; i<n; i++) {
6808:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6809:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6810:       ISEqual(irow[i],icol[i],&eq);
6811:       if (eq) {
6812:         if (mat->symmetric) {
6813:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6814:         } else if (mat->hermitian) {
6815:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6816:         } else if (mat->structurally_symmetric) {
6817:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6818:         }
6819:       }
6820:     }
6821:   }
6822:   return(0);
6823: }

6825: /*@C
6826:    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).

6828:    Collective on Mat

6830:    Input Parameters:
6831: +  mat - the matrix
6832: .  n   - the number of submatrixes to be extracted
6833: .  irow, icol - index sets of rows and columns to extract
6834: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6836:    Output Parameter:
6837: .  submat - the array of submatrices

6839:    Level: advanced

6841:    Concepts: matrices^accessing submatrices
6842:    Concepts: submatrices

6844: .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6845: @*/
6846: PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6847: {
6849:   PetscInt       i;
6850:   PetscBool      eq;

6855:   if (n) {
6860:   }
6862:   if (n && scall == MAT_REUSE_MATRIX) {
6865:   }
6866:   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6867:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6868:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6869:   MatCheckPreallocated(mat,1);

6871:   PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6872:   (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6873:   PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6874:   for (i=0; i<n; i++) {
6875:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6876:       ISEqual(irow[i],icol[i],&eq);
6877:       if (eq) {
6878:         if (mat->symmetric) {
6879:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6880:         } else if (mat->hermitian) {
6881:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6882:         } else if (mat->structurally_symmetric) {
6883:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6884:         }
6885:       }
6886:     }
6887:   }
6888:   return(0);
6889: }

6891: /*@C
6892:    MatDestroyMatrices - Destroys an array of matrices.

6894:    Collective on Mat

6896:    Input Parameters:
6897: +  n - the number of local matrices
6898: -  mat - the matrices (note that this is a pointer to the array of matrices)

6900:    Level: advanced

6902:     Notes:
6903:     Frees not only the matrices, but also the array that contains the matrices
6904:            In Fortran will not free the array.

6906: .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6907: @*/
6908: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6909: {
6911:   PetscInt       i;

6914:   if (!*mat) return(0);
6915:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);

6918:   for (i=0; i<n; i++) {
6919:     MatDestroy(&(*mat)[i]);
6920:   }

6922:   /* memory is allocated even if n = 0 */
6923:   PetscFree(*mat);
6924:   return(0);
6925: }

6927: /*@C
6928:    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().

6930:    Collective on Mat

6932:    Input Parameters:
6933: +  n - the number of local matrices
6934: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6935:                        sequence of MatCreateSubMatrices())

6937:    Level: advanced

6939:     Notes:
6940:     Frees not only the matrices, but also the array that contains the matrices
6941:            In Fortran will not free the array.

6943: .seealso: MatCreateSubMatrices()
6944: @*/
6945: PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6946: {
6948:   Mat            mat0;

6951:   if (!*mat) return(0);
6952:   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6953:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);

6956:   mat0 = (*mat)[0];
6957:   if (mat0 && mat0->ops->destroysubmatrices) {
6958:     (mat0->ops->destroysubmatrices)(n,mat);
6959:   } else {
6960:     MatDestroyMatrices(n,mat);
6961:   }
6962:   return(0);
6963: }

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

6968:    Collective on Mat

6970:    Input Parameters:
6971: .  mat - the matrix

6973:    Output Parameter:
6974: .  matstruct - the sequential matrix with the nonzero structure of mat

6976:   Level: intermediate

6978: .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6979: @*/
6980: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6981: {


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

6992:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6993:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6994:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6995:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6996:   return(0);
6997: }

6999: /*@C
7000:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

7002:    Collective on Mat

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

7008:    Level: advanced

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

7013: .seealso: MatGetSeqNonzeroStructure()
7014: @*/
7015: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7016: {

7021:   MatDestroy(mat);
7022:   return(0);
7023: }

7025: /*@
7026:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7027:    replaces the index sets by larger ones that represent submatrices with
7028:    additional overlap.

7030:    Collective on Mat

7032:    Input Parameters:
7033: +  mat - the matrix
7034: .  n   - the number of index sets
7035: .  is  - the array of index sets (these index sets will changed during the call)
7036: -  ov  - the additional overlap requested

7038:    Options Database:
7039: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

7041:    Level: developer

7043:    Concepts: overlap
7044:    Concepts: ASM^computing overlap

7046: .seealso: MatCreateSubMatrices()
7047: @*/
7048: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7049: {

7055:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7056:   if (n) {
7059:   }
7060:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7061:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7062:   MatCheckPreallocated(mat,1);

7064:   if (!ov) return(0);
7065:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7066:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
7067:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
7068:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
7069:   return(0);
7070: }


7073: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);

7075: /*@
7076:    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7077:    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7078:    additional overlap.

7080:    Collective on Mat

7082:    Input Parameters:
7083: +  mat - the matrix
7084: .  n   - the number of index sets
7085: .  is  - the array of index sets (these index sets will changed during the call)
7086: -  ov  - the additional overlap requested

7088:    Options Database:
7089: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

7091:    Level: developer

7093:    Concepts: overlap
7094:    Concepts: ASM^computing overlap

7096: .seealso: MatCreateSubMatrices()
7097: @*/
7098: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7099: {
7100:   PetscInt       i;

7106:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7107:   if (n) {
7110:   }
7111:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7112:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7113:   MatCheckPreallocated(mat,1);
7114:   if (!ov) return(0);
7115:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
7116:   for(i=0; i<n; i++){
7117:          MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
7118:   }
7119:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
7120:   return(0);
7121: }




7126: /*@
7127:    MatGetBlockSize - Returns the matrix block size.

7129:    Not Collective

7131:    Input Parameter:
7132: .  mat - the matrix

7134:    Output Parameter:
7135: .  bs - block size

7137:    Notes:
7138:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

7140:    If the block size has not been set yet this routine returns 1.

7142:    Level: intermediate

7144:    Concepts: matrices^block size

7146: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7147: @*/
7148: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7149: {
7153:   *bs = PetscAbs(mat->rmap->bs);
7154:   return(0);
7155: }

7157: /*@
7158:    MatGetBlockSizes - Returns the matrix block row and column sizes.

7160:    Not Collective

7162:    Input Parameter:
7163: .  mat - the matrix

7165:    Output Parameter:
7166: .  rbs - row block size
7167: .  cbs - column block size

7169:    Notes:
7170:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7171:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

7173:    If a block size has not been set yet this routine returns 1.

7175:    Level: intermediate

7177:    Concepts: matrices^block size

7179: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7180: @*/
7181: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7182: {
7187:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7188:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7189:   return(0);
7190: }

7192: /*@
7193:    MatSetBlockSize - Sets the matrix block size.

7195:    Logically Collective on Mat

7197:    Input Parameters:
7198: +  mat - the matrix
7199: -  bs - block size

7201:    Notes:
7202:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7203:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.

7205:     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7206:     is compatible with the matrix local sizes.

7208:    Level: intermediate

7210:    Concepts: matrices^block size

7212: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7213: @*/
7214: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7215: {

7221:   MatSetBlockSizes(mat,bs,bs);
7222:   return(0);
7223: }

7225: /*@
7226:    MatSetBlockSizes - Sets the matrix block row and column sizes.

7228:    Logically Collective on Mat

7230:    Input Parameters:
7231: +  mat - the matrix
7232: -  rbs - row block size
7233: -  cbs - column block size

7235:    Notes:
7236:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7237:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7238:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

7240:     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7241:     are compatible with the matrix local sizes.

7243:     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().

7245:    Level: intermediate

7247:    Concepts: matrices^block size

7249: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7250: @*/
7251: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7252: {

7259:   if (mat->ops->setblocksizes) {
7260:     (*mat->ops->setblocksizes)(mat,rbs,cbs);
7261:   }
7262:   if (mat->rmap->refcnt) {
7263:     ISLocalToGlobalMapping l2g = NULL;
7264:     PetscLayout            nmap = NULL;

7266:     PetscLayoutDuplicate(mat->rmap,&nmap);
7267:     if (mat->rmap->mapping) {
7268:       ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);
7269:     }
7270:     PetscLayoutDestroy(&mat->rmap);
7271:     mat->rmap = nmap;
7272:     mat->rmap->mapping = l2g;
7273:   }
7274:   if (mat->cmap->refcnt) {
7275:     ISLocalToGlobalMapping l2g = NULL;
7276:     PetscLayout            nmap = NULL;

7278:     PetscLayoutDuplicate(mat->cmap,&nmap);
7279:     if (mat->cmap->mapping) {
7280:       ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);
7281:     }
7282:     PetscLayoutDestroy(&mat->cmap);
7283:     mat->cmap = nmap;
7284:     mat->cmap->mapping = l2g;
7285:   }
7286:   PetscLayoutSetBlockSize(mat->rmap,rbs);
7287:   PetscLayoutSetBlockSize(mat->cmap,cbs);
7288:   return(0);
7289: }

7291: /*@
7292:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

7294:    Logically Collective on Mat

7296:    Input Parameters:
7297: +  mat - the matrix
7298: .  fromRow - matrix from which to copy row block size
7299: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

7301:    Level: developer

7303:    Concepts: matrices^block size

7305: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7306: @*/
7307: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7308: {

7315:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7316:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7317:   return(0);
7318: }

7320: /*@
7321:    MatResidual - Default routine to calculate the residual.

7323:    Collective on Mat and Vec

7325:    Input Parameters:
7326: +  mat - the matrix
7327: .  b   - the right-hand-side
7328: -  x   - the approximate solution

7330:    Output Parameter:
7331: .  r - location to store the residual

7333:    Level: developer

7335: .keywords: MG, default, multigrid, residual

7337: .seealso: PCMGSetResidual()
7338: @*/
7339: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7340: {

7349:   MatCheckPreallocated(mat,1);
7350:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7351:   if (!mat->ops->residual) {
7352:     MatMult(mat,x,r);
7353:     VecAYPX(r,-1.0,b);
7354:   } else {
7355:     (*mat->ops->residual)(mat,b,x,r);
7356:   }
7357:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7358:   return(0);
7359: }

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

7364:    Collective on Mat

7366:     Input Parameters:
7367: +   mat - the matrix
7368: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7369: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7370: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7371:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7372:                  always used.

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

7381:     Level: developer

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

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

7388:     Fortran Notes:
7389:     In Fortran use
7390: $
7391: $      PetscInt ia(1), ja(1)
7392: $      PetscOffset iia, jja
7393: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7394: $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)

7396:      or
7397: $
7398: $    PetscInt, pointer :: ia(:),ja(:)
7399: $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7400: $    ! Access the ith and jth entries via ia(i) and ja(j)

7402: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7403: @*/
7404: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7405: {

7415:   MatCheckPreallocated(mat,1);
7416:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7417:   else {
7418:     *done = PETSC_TRUE;
7419:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7420:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7421:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7422:   }
7423:   return(0);
7424: }

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

7429:     Collective on Mat

7431:     Input Parameters:
7432: +   mat - the matrix
7433: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7434: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7435:                 symmetrized
7436: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7437:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7438:                  always used.
7439: .   n - number of columns in the (possibly compressed) matrix
7440: .   ia - the column pointers
7441: -   ja - the row indices

7443:     Output Parameters:
7444: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

7446:     Note:
7447:     This routine zeros out n, ia, and ja. This is to prevent accidental
7448:     us of the array after it has been restored. If you pass NULL, it will
7449:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

7451:     Level: developer

7453: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7454: @*/
7455: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7456: {

7466:   MatCheckPreallocated(mat,1);
7467:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7468:   else {
7469:     *done = PETSC_TRUE;
7470:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7471:   }
7472:   return(0);
7473: }

7475: /*@C
7476:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7477:     MatGetRowIJ().

7479:     Collective on Mat

7481:     Input Parameters:
7482: +   mat - the matrix
7483: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7484: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7485:                 symmetrized
7486: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7487:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7488:                  always used.
7489: .   n - size of (possibly compressed) matrix
7490: .   ia - the row pointers
7491: -   ja - the column indices

7493:     Output Parameters:
7494: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7496:     Note:
7497:     This routine zeros out n, ia, and ja. This is to prevent accidental
7498:     us of the array after it has been restored. If you pass NULL, it will
7499:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

7501:     Level: developer

7503: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7504: @*/
7505: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7506: {

7515:   MatCheckPreallocated(mat,1);

7517:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7518:   else {
7519:     *done = PETSC_TRUE;
7520:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7521:     if (n)  *n = 0;
7522:     if (ia) *ia = NULL;
7523:     if (ja) *ja = NULL;
7524:   }
7525:   return(0);
7526: }

7528: /*@C
7529:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7530:     MatGetColumnIJ().

7532:     Collective on Mat

7534:     Input Parameters:
7535: +   mat - the matrix
7536: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7537: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7538:                 symmetrized
7539: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7540:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7541:                  always used.

7543:     Output Parameters:
7544: +   n - size of (possibly compressed) matrix
7545: .   ia - the column pointers
7546: .   ja - the row indices
7547: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7549:     Level: developer

7551: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7552: @*/
7553: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7554: {

7563:   MatCheckPreallocated(mat,1);

7565:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7566:   else {
7567:     *done = PETSC_TRUE;
7568:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7569:     if (n)  *n = 0;
7570:     if (ia) *ia = NULL;
7571:     if (ja) *ja = NULL;
7572:   }
7573:   return(0);
7574: }

7576: /*@C
7577:     MatColoringPatch -Used inside matrix coloring routines that
7578:     use MatGetRowIJ() and/or MatGetColumnIJ().

7580:     Collective on Mat

7582:     Input Parameters:
7583: +   mat - the matrix
7584: .   ncolors - max color value
7585: .   n   - number of entries in colorarray
7586: -   colorarray - array indicating color for each column

7588:     Output Parameters:
7589: .   iscoloring - coloring generated using colorarray information

7591:     Level: developer

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

7595: @*/
7596: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7597: {

7605:   MatCheckPreallocated(mat,1);

7607:   if (!mat->ops->coloringpatch) {
7608:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7609:   } else {
7610:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7611:   }
7612:   return(0);
7613: }


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

7619:    Logically Collective on Mat

7621:    Input Parameter:
7622: .  mat - the factored matrix to be reset

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

7631:    Note that one can specify in-place ILU(0) factorization by calling
7632: .vb
7633:      PCType(pc,PCILU);
7634:      PCFactorSeUseInPlace(pc);
7635: .ve
7636:    or by using the options -pc_type ilu -pc_factor_in_place

7638:    In-place factorization ILU(0) can also be used as a local
7639:    solver for the blocks within the block Jacobi or additive Schwarz
7640:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7641:    for details on setting local solver options.

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

7647:    Level: developer

7649: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()

7651:    Concepts: matrices^unfactored

7653: @*/
7654: PetscErrorCode MatSetUnfactored(Mat mat)
7655: {

7661:   MatCheckPreallocated(mat,1);
7662:   mat->factortype = MAT_FACTOR_NONE;
7663:   if (!mat->ops->setunfactored) return(0);
7664:   (*mat->ops->setunfactored)(mat);
7665:   return(0);
7666: }

7668: /*MC
7669:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7671:     Synopsis:
7672:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7674:     Not collective

7676:     Input Parameter:
7677: .   x - matrix

7679:     Output Parameters:
7680: +   xx_v - the Fortran90 pointer to the array
7681: -   ierr - error code

7683:     Example of Usage:
7684: .vb
7685:       PetscScalar, pointer xx_v(:,:)
7686:       ....
7687:       call MatDenseGetArrayF90(x,xx_v,ierr)
7688:       a = xx_v(3)
7689:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7690: .ve

7692:     Level: advanced

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

7696:     Concepts: matrices^accessing array

7698: M*/

7700: /*MC
7701:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7702:     accessed with MatDenseGetArrayF90().

7704:     Synopsis:
7705:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7707:     Not collective

7709:     Input Parameters:
7710: +   x - matrix
7711: -   xx_v - the Fortran90 pointer to the array

7713:     Output Parameter:
7714: .   ierr - error code

7716:     Example of Usage:
7717: .vb
7718:        PetscScalar, pointer xx_v(:,:)
7719:        ....
7720:        call MatDenseGetArrayF90(x,xx_v,ierr)
7721:        a = xx_v(3)
7722:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7723: .ve

7725:     Level: advanced

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

7729: M*/


7732: /*MC
7733:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7735:     Synopsis:
7736:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7738:     Not collective

7740:     Input Parameter:
7741: .   x - matrix

7743:     Output Parameters:
7744: +   xx_v - the Fortran90 pointer to the array
7745: -   ierr - error code

7747:     Example of Usage:
7748: .vb
7749:       PetscScalar, pointer xx_v(:)
7750:       ....
7751:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7752:       a = xx_v(3)
7753:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7754: .ve

7756:     Level: advanced

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

7760:     Concepts: matrices^accessing array

7762: M*/

7764: /*MC
7765:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7766:     accessed with MatSeqAIJGetArrayF90().

7768:     Synopsis:
7769:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7771:     Not collective

7773:     Input Parameters:
7774: +   x - matrix
7775: -   xx_v - the Fortran90 pointer to the array

7777:     Output Parameter:
7778: .   ierr - error code

7780:     Example of Usage:
7781: .vb
7782:        PetscScalar, pointer xx_v(:)
7783:        ....
7784:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7785:        a = xx_v(3)
7786:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7787: .ve

7789:     Level: advanced

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

7793: M*/


7796: /*@
7797:     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7798:                       as the original matrix.

7800:     Collective on Mat

7802:     Input Parameters:
7803: +   mat - the original matrix
7804: .   isrow - parallel IS containing the rows this processor should obtain
7805: .   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.
7806: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7808:     Output Parameter:
7809: .   newmat - the new submatrix, of the same type as the old

7811:     Level: advanced

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

7816:     Some matrix types place restrictions on the row and column indices, such
7817:     as that they be sorted or that they be equal to each other.

7819:     The index sets may not have duplicate entries.

7821:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7822:    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7823:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7824:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7825:    you are finished using it.

7827:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7828:     the input matrix.

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

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

7838: .vb
7839:             1  2  0  |  0  3  0  |  0  4
7840:     Proc0   0  5  6  |  7  0  0  |  8  0
7841:             9  0 10  | 11  0  0  | 12  0
7842:     -------------------------------------
7843:            13  0 14  | 15 16 17  |  0  0
7844:     Proc1   0 18  0  | 19 20 21  |  0  0
7845:             0  0  0  | 22 23  0  | 24  0
7846:     -------------------------------------
7847:     Proc2  25 26 27  |  0  0 28  | 29  0
7848:            30  0  0  | 31 32 33  |  0 34
7849: .ve

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

7853: .vb
7854:             2  0  |  0  3  0  |  0
7855:     Proc0   5  6  |  7  0  0  |  8
7856:     -------------------------------
7857:     Proc1  18  0  | 19 20 21  |  0
7858:     -------------------------------
7859:     Proc2  26 27  |  0  0 28  | 29
7860:             0  0  | 31 32 33  |  0
7861: .ve


7864:     Concepts: matrices^submatrices

7866: .seealso: MatCreateSubMatrices()
7867: @*/
7868: PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7869: {
7871:   PetscMPIInt    size;
7872:   Mat            *local;
7873:   IS             iscoltmp;

7882:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7883:   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");

7885:   MatCheckPreallocated(mat,1);
7886:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7888:   if (!iscol || isrow == iscol) {
7889:     PetscBool   stride;
7890:     PetscMPIInt grabentirematrix = 0,grab;
7891:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7892:     if (stride) {
7893:       PetscInt first,step,n,rstart,rend;
7894:       ISStrideGetInfo(isrow,&first,&step);
7895:       if (step == 1) {
7896:         MatGetOwnershipRange(mat,&rstart,&rend);
7897:         if (rstart == first) {
7898:           ISGetLocalSize(isrow,&n);
7899:           if (n == rend-rstart) {
7900:             grabentirematrix = 1;
7901:           }
7902:         }
7903:       }
7904:     }
7905:     MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7906:     if (grab) {
7907:       PetscInfo(mat,"Getting entire matrix as submatrix\n");
7908:       if (cll == MAT_INITIAL_MATRIX) {
7909:         *newmat = mat;
7910:         PetscObjectReference((PetscObject)mat);
7911:       }
7912:       return(0);
7913:     }
7914:   }

7916:   if (!iscol) {
7917:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7918:   } else {
7919:     iscoltmp = iscol;
7920:   }

7922:   /* if original matrix is on just one processor then use submatrix generated */
7923:   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7924:     MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7925:     if (!iscol) {ISDestroy(&iscoltmp);}
7926:     return(0);
7927:   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7928:     MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7929:     *newmat = *local;
7930:     PetscFree(local);
7931:     if (!iscol) {ISDestroy(&iscoltmp);}
7932:     return(0);
7933:   } else if (!mat->ops->createsubmatrix) {
7934:     /* Create a new matrix type that implements the operation using the full matrix */
7935:     PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7936:     switch (cll) {
7937:     case MAT_INITIAL_MATRIX:
7938:       MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);
7939:       break;
7940:     case MAT_REUSE_MATRIX:
7941:       MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);
7942:       break;
7943:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7944:     }
7945:     PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);
7946:     if (!iscol) {ISDestroy(&iscoltmp);}
7947:     return(0);
7948:   }

7950:   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7951:   PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7952:   (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7953:   PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);

7955:   /* Propagate symmetry information for diagonal blocks */
7956:   if (isrow == iscoltmp) {
7957:     if (mat->symmetric_set && mat->symmetric) {
7958:       MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);
7959:     }
7960:     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
7961:       MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
7962:     }
7963:     if (mat->hermitian_set && mat->hermitian) {
7964:       MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);
7965:     }
7966:     if (mat->spd_set && mat->spd) {
7967:       MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);
7968:     }
7969:   }

7971:   if (!iscol) {ISDestroy(&iscoltmp);}
7972:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7973:   return(0);
7974: }

7976: /*@
7977:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7978:    used during the assembly process to store values that belong to
7979:    other processors.

7981:    Not Collective

7983:    Input Parameters:
7984: +  mat   - the matrix
7985: .  size  - the initial size of the stash.
7986: -  bsize - the initial size of the block-stash(if used).

7988:    Options Database Keys:
7989: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7990: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7992:    Level: intermediate

7994:    Notes:
7995:      The block-stash is used for values set with MatSetValuesBlocked() while
7996:      the stash is used for values set with MatSetValues()

7998:      Run with the option -info and look for output of the form
7999:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8000:      to determine the appropriate value, MM, to use for size and
8001:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8002:      to determine the value, BMM to use for bsize

8004:    Concepts: stash^setting matrix size
8005:    Concepts: matrices^stash

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

8009: @*/
8010: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8011: {

8017:   MatStashSetInitialSize_Private(&mat->stash,size);
8018:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
8019:   return(0);
8020: }

8022: /*@
8023:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8024:      the matrix

8026:    Neighbor-wise Collective on Mat

8028:    Input Parameters:
8029: +  mat   - the matrix
8030: .  x,y - the vectors
8031: -  w - where the result is stored

8033:    Level: intermediate

8035:    Notes:
8036:     w may be the same vector as y.

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

8041:     Concepts: interpolation

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

8045: @*/
8046: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8047: {
8049:   PetscInt       M,N,Ny;

8057:   MatCheckPreallocated(A,1);
8058:   MatGetSize(A,&M,&N);
8059:   VecGetSize(y,&Ny);
8060:   if (M == Ny) {
8061:     MatMultAdd(A,x,y,w);
8062:   } else {
8063:     MatMultTransposeAdd(A,x,y,w);
8064:   }
8065:   return(0);
8066: }

8068: /*@
8069:    MatInterpolate - y = A*x or A'*x depending on the shape of
8070:      the matrix

8072:    Neighbor-wise Collective on Mat

8074:    Input Parameters:
8075: +  mat   - the matrix
8076: -  x,y - the vectors

8078:    Level: intermediate

8080:    Notes:
8081:     This allows one to use either the restriction or interpolation (its transpose)
8082:     matrix to do the interpolation

8084:    Concepts: matrices^interpolation

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

8088: @*/
8089: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8090: {
8092:   PetscInt       M,N,Ny;

8099:   MatCheckPreallocated(A,1);
8100:   MatGetSize(A,&M,&N);
8101:   VecGetSize(y,&Ny);
8102:   if (M == Ny) {
8103:     MatMult(A,x,y);
8104:   } else {
8105:     MatMultTranspose(A,x,y);
8106:   }
8107:   return(0);
8108: }

8110: /*@
8111:    MatRestrict - y = A*x or A'*x

8113:    Neighbor-wise Collective on Mat

8115:    Input Parameters:
8116: +  mat   - the matrix
8117: -  x,y - the vectors

8119:    Level: intermediate

8121:    Notes:
8122:     This allows one to use either the restriction or interpolation (its transpose)
8123:     matrix to do the restriction

8125:    Concepts: matrices^restriction

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

8129: @*/
8130: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8131: {
8133:   PetscInt       M,N,Ny;

8140:   MatCheckPreallocated(A,1);

8142:   MatGetSize(A,&M,&N);
8143:   VecGetSize(y,&Ny);
8144:   if (M == Ny) {
8145:     MatMult(A,x,y);
8146:   } else {
8147:     MatMultTranspose(A,x,y);
8148:   }
8149:   return(0);
8150: }

8152: /*@C
8153:    MatGetNullSpace - retrieves the null space of a matrix.

8155:    Logically Collective on Mat and MatNullSpace

8157:    Input Parameters:
8158: +  mat - the matrix
8159: -  nullsp - the null space object

8161:    Level: developer

8163:    Concepts: null space^attaching to matrix

8165: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8166: @*/
8167: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8168: {
8172:   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8173:   return(0);
8174: }

8176: /*@C
8177:    MatSetNullSpace - attaches a null space to a matrix.

8179:    Logically Collective on Mat and MatNullSpace

8181:    Input Parameters:
8182: +  mat - the matrix
8183: -  nullsp - the null space object

8185:    Level: advanced

8187:    Notes:
8188:       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached

8190:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8191:       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.

8193:       You can remove the null space by calling this routine with an nullsp of NULL


8196:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8197:    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).
8198:    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
8199:    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
8200:    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).

8202:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

8204:     If the matrix is known to be symmetric because it is an SBAIJ matrix or one as called MatSetOption(mat,MAT_SYMMETRIC or MAT_SYMMETRIC_ETERNAL,PETSC_TRUE); this
8205:     routine also automatically calls MatSetTransposeNullSpace().

8207:    Concepts: null space^attaching to matrix

8209: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8210: @*/
8211: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8212: {

8218:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8219:   MatNullSpaceDestroy(&mat->nullsp);
8220:   mat->nullsp = nullsp;
8221:   if (mat->symmetric_set && mat->symmetric) {
8222:     MatSetTransposeNullSpace(mat,nullsp);
8223:   }
8224:   return(0);
8225: }

8227: /*@
8228:    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.

8230:    Logically Collective on Mat and MatNullSpace

8232:    Input Parameters:
8233: +  mat - the matrix
8234: -  nullsp - the null space object

8236:    Level: developer

8238:    Concepts: null space^attaching to matrix

8240: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8241: @*/
8242: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8243: {
8248:   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8249:   return(0);
8250: }

8252: /*@
8253:    MatSetTransposeNullSpace - attaches a null space to a matrix.

8255:    Logically Collective on Mat and MatNullSpace

8257:    Input Parameters:
8258: +  mat - the matrix
8259: -  nullsp - the null space object

8261:    Level: advanced

8263:    Notes:
8264:       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.
8265:       You must also call MatSetNullSpace()


8268:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8269:    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).
8270:    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
8271:    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
8272:    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).

8274:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

8276:    Concepts: null space^attaching to matrix

8278: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8279: @*/
8280: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8281: {

8288:   MatCheckPreallocated(mat,1);
8289:   PetscObjectReference((PetscObject)nullsp);
8290:   MatNullSpaceDestroy(&mat->transnullsp);
8291:   mat->transnullsp = nullsp;
8292:   return(0);
8293: }

8295: /*@
8296:    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8297:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

8299:    Logically Collective on Mat and MatNullSpace

8301:    Input Parameters:
8302: +  mat - the matrix
8303: -  nullsp - the null space object

8305:    Level: advanced

8307:    Notes:
8308:       Overwrites any previous near null space that may have been attached

8310:       You can remove the null space by calling this routine with an nullsp of NULL

8312:    Concepts: null space^attaching to matrix

8314: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8315: @*/
8316: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8317: {

8324:   MatCheckPreallocated(mat,1);
8325:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8326:   MatNullSpaceDestroy(&mat->nearnullsp);
8327:   mat->nearnullsp = nullsp;
8328:   return(0);
8329: }

8331: /*@
8332:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

8334:    Not Collective

8336:    Input Parameters:
8337: .  mat - the matrix

8339:    Output Parameters:
8340: .  nullsp - the null space object, NULL if not set

8342:    Level: developer

8344:    Concepts: null space^attaching to matrix

8346: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8347: @*/
8348: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8349: {
8354:   MatCheckPreallocated(mat,1);
8355:   *nullsp = mat->nearnullsp;
8356:   return(0);
8357: }

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

8362:    Collective on Mat

8364:    Input Parameters:
8365: +  mat - the matrix
8366: .  row - row/column permutation
8367: .  fill - expected fill factor >= 1.0
8368: -  level - level of fill, for ICC(k)

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

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

8378:    Level: developer

8380:    Concepts: matrices^incomplete Cholesky factorization
8381:    Concepts: Cholesky factorization

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

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

8388: @*/
8389: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8390: {

8398:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8399:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8400:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8401:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8402:   MatCheckPreallocated(mat,1);
8403:   (*mat->ops->iccfactor)(mat,row,info);
8404:   PetscObjectStateIncrease((PetscObject)mat);
8405:   return(0);
8406: }

8408: /*@
8409:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8410:          ghosted ones.

8412:    Not Collective

8414:    Input Parameters:
8415: +  mat - the matrix
8416: -  diag = the diagonal values, including ghost ones

8418:    Level: developer

8420:    Notes:
8421:     Works only for MPIAIJ and MPIBAIJ matrices

8423: .seealso: MatDiagonalScale()
8424: @*/
8425: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8426: {
8428:   PetscMPIInt    size;


8435:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8436:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8437:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8438:   if (size == 1) {
8439:     PetscInt n,m;
8440:     VecGetSize(diag,&n);
8441:     MatGetSize(mat,0,&m);
8442:     if (m == n) {
8443:       MatDiagonalScale(mat,0,diag);
8444:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8445:   } else {
8446:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8447:   }
8448:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8449:   PetscObjectStateIncrease((PetscObject)mat);
8450:   return(0);
8451: }

8453: /*@
8454:    MatGetInertia - Gets the inertia from a factored matrix

8456:    Collective on Mat

8458:    Input Parameter:
8459: .  mat - the matrix

8461:    Output Parameters:
8462: +   nneg - number of negative eigenvalues
8463: .   nzero - number of zero eigenvalues
8464: -   npos - number of positive eigenvalues

8466:    Level: advanced

8468:    Notes:
8469:     Matrix must have been factored by MatCholeskyFactor()


8472: @*/
8473: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8474: {

8480:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8481:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8482:   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8483:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8484:   return(0);
8485: }

8487: /* ----------------------------------------------------------------*/
8488: /*@C
8489:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

8491:    Neighbor-wise Collective on Mat and Vecs

8493:    Input Parameters:
8494: +  mat - the factored matrix
8495: -  b - the right-hand-side vectors

8497:    Output Parameter:
8498: .  x - the result vectors

8500:    Notes:
8501:    The vectors b and x cannot be the same.  I.e., one cannot
8502:    call MatSolves(A,x,x).

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

8509:    Level: developer

8511:    Concepts: matrices^triangular solves

8513: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8514: @*/
8515: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8516: {

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

8526:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8527:   MatCheckPreallocated(mat,1);
8528:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8529:   (*mat->ops->solves)(mat,b,x);
8530:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8531:   return(0);
8532: }

8534: /*@
8535:    MatIsSymmetric - Test whether a matrix is symmetric

8537:    Collective on Mat

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

8543:    Output Parameters:
8544: .  flg - the result

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

8549:    Level: intermediate

8551:    Concepts: matrix^symmetry

8553: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8554: @*/
8555: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8556: {


8563:   if (!A->symmetric_set) {
8564:     if (!A->ops->issymmetric) {
8565:       MatType mattype;
8566:       MatGetType(A,&mattype);
8567:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8568:     }
8569:     (*A->ops->issymmetric)(A,tol,flg);
8570:     if (!tol) {
8571:       A->symmetric_set = PETSC_TRUE;
8572:       A->symmetric     = *flg;
8573:       if (A->symmetric) {
8574:         A->structurally_symmetric_set = PETSC_TRUE;
8575:         A->structurally_symmetric     = PETSC_TRUE;
8576:       }
8577:     }
8578:   } else if (A->symmetric) {
8579:     *flg = PETSC_TRUE;
8580:   } else if (!tol) {
8581:     *flg = PETSC_FALSE;
8582:   } else {
8583:     if (!A->ops->issymmetric) {
8584:       MatType mattype;
8585:       MatGetType(A,&mattype);
8586:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8587:     }
8588:     (*A->ops->issymmetric)(A,tol,flg);
8589:   }
8590:   return(0);
8591: }

8593: /*@
8594:    MatIsHermitian - Test whether a matrix is Hermitian

8596:    Collective on Mat

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

8602:    Output Parameters:
8603: .  flg - the result

8605:    Level: intermediate

8607:    Concepts: matrix^symmetry

8609: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8610:           MatIsSymmetricKnown(), MatIsSymmetric()
8611: @*/
8612: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8613: {


8620:   if (!A->hermitian_set) {
8621:     if (!A->ops->ishermitian) {
8622:       MatType mattype;
8623:       MatGetType(A,&mattype);
8624:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8625:     }
8626:     (*A->ops->ishermitian)(A,tol,flg);
8627:     if (!tol) {
8628:       A->hermitian_set = PETSC_TRUE;
8629:       A->hermitian     = *flg;
8630:       if (A->hermitian) {
8631:         A->structurally_symmetric_set = PETSC_TRUE;
8632:         A->structurally_symmetric     = PETSC_TRUE;
8633:       }
8634:     }
8635:   } else if (A->hermitian) {
8636:     *flg = PETSC_TRUE;
8637:   } else if (!tol) {
8638:     *flg = PETSC_FALSE;
8639:   } else {
8640:     if (!A->ops->ishermitian) {
8641:       MatType mattype;
8642:       MatGetType(A,&mattype);
8643:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8644:     }
8645:     (*A->ops->ishermitian)(A,tol,flg);
8646:   }
8647:   return(0);
8648: }

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

8653:    Not Collective

8655:    Input Parameter:
8656: .  A - the matrix to check

8658:    Output Parameters:
8659: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8660: -  flg - the result

8662:    Level: advanced

8664:    Concepts: matrix^symmetry

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

8669: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8670: @*/
8671: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8672: {
8677:   if (A->symmetric_set) {
8678:     *set = PETSC_TRUE;
8679:     *flg = A->symmetric;
8680:   } else {
8681:     *set = PETSC_FALSE;
8682:   }
8683:   return(0);
8684: }

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

8689:    Not Collective

8691:    Input Parameter:
8692: .  A - the matrix to check

8694:    Output Parameters:
8695: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8696: -  flg - the result

8698:    Level: advanced

8700:    Concepts: matrix^symmetry

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

8705: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8706: @*/
8707: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8708: {
8713:   if (A->hermitian_set) {
8714:     *set = PETSC_TRUE;
8715:     *flg = A->hermitian;
8716:   } else {
8717:     *set = PETSC_FALSE;
8718:   }
8719:   return(0);
8720: }

8722: /*@
8723:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8725:    Collective on Mat

8727:    Input Parameter:
8728: .  A - the matrix to test

8730:    Output Parameters:
8731: .  flg - the result

8733:    Level: intermediate

8735:    Concepts: matrix^symmetry

8737: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8738: @*/
8739: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8740: {

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

8750:     A->structurally_symmetric_set = PETSC_TRUE;
8751:   }
8752:   *flg = A->structurally_symmetric;
8753:   return(0);
8754: }

8756: /*@
8757:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8758:        to be communicated to other processors during the MatAssemblyBegin/End() process

8760:     Not collective

8762:    Input Parameter:
8763: .   vec - the vector

8765:    Output Parameters:
8766: +   nstash   - the size of the stash
8767: .   reallocs - the number of additional mallocs incurred.
8768: .   bnstash   - the size of the block stash
8769: -   breallocs - the number of additional mallocs incurred.in the block stash

8771:    Level: advanced

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

8775: @*/
8776: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8777: {

8781:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8782:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8783:   return(0);
8784: }

8786: /*@C
8787:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8788:      parallel layout

8790:    Collective on Mat

8792:    Input Parameter:
8793: .  mat - the matrix

8795:    Output Parameter:
8796: +   right - (optional) vector that the matrix can be multiplied against
8797: -   left - (optional) vector that the matrix vector product can be stored in

8799:    Notes:
8800:     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().

8802:   Notes:
8803:     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed

8805:   Level: advanced

8807: .seealso: MatCreate(), VecDestroy()
8808: @*/
8809: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8810: {

8816:   if (mat->ops->getvecs) {
8817:     (*mat->ops->getvecs)(mat,right,left);
8818:   } else {
8819:     PetscInt rbs,cbs;
8820:     MatGetBlockSizes(mat,&rbs,&cbs);
8821:     if (right) {
8822:       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8823:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8824:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8825:       VecSetBlockSize(*right,cbs);
8826:       VecSetType(*right,VECSTANDARD);
8827:       PetscLayoutReference(mat->cmap,&(*right)->map);
8828:     }
8829:     if (left) {
8830:       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8831:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8832:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8833:       VecSetBlockSize(*left,rbs);
8834:       VecSetType(*left,VECSTANDARD);
8835:       PetscLayoutReference(mat->rmap,&(*left)->map);
8836:     }
8837:   }
8838:   return(0);
8839: }

8841: /*@C
8842:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8843:      with default values.

8845:    Not Collective

8847:    Input Parameters:
8848: .    info - the MatFactorInfo data structure


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

8855:    Level: developer

8857: .seealso: MatFactorInfo

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

8862: @*/

8864: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8865: {

8869:   PetscMemzero(info,sizeof(MatFactorInfo));
8870:   return(0);
8871: }

8873: /*@
8874:    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed

8876:    Collective on Mat

8878:    Input Parameters:
8879: +  mat - the factored matrix
8880: -  is - the index set defining the Schur indices (0-based)

8882:    Notes:
8883:     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.

8885:    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.

8887:    Level: developer

8889:    Concepts:

8891: .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8892:           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()

8894: @*/
8895: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8896: {
8897:   PetscErrorCode ierr,(*f)(Mat,IS);

8905:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8906:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8907:   if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
8908:   if (mat->schur) {
8909:     MatDestroy(&mat->schur);
8910:   }
8911:   (*f)(mat,is);
8912:   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8913:   MatFactorSetUpInPlaceSchur_Private(mat);
8914:   return(0);
8915: }

8917: /*@
8918:   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step

8920:    Logically Collective on Mat

8922:    Input Parameters:
8923: +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8924: .  S - location where to return the Schur complement, can be NULL
8925: -  status - the status of the Schur complement matrix, can be NULL

8927:    Notes:
8928:    You must call MatFactorSetSchurIS() before calling this routine.

8930:    The routine provides a copy of the Schur matrix stored within the solver data structures.
8931:    The caller must destroy the object when it is no longer needed.
8932:    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.

8934:    Use MatFactorGetSchurComplement() to get access to the Schur complement matrix inside the factored matrix instead of making a copy of it (which this function does)

8936:    Developer Notes:
8937:     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
8938:    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.

8940:    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.

8942:    Level: advanced

8944:    References:

8946: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8947: @*/
8948: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8949: {

8956:   if (S) {
8957:     PetscErrorCode (*f)(Mat,Mat*);

8959:     PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);
8960:     if (f) {
8961:       (*f)(F,S);
8962:     } else {
8963:       MatDuplicate(F->schur,MAT_COPY_VALUES,S);
8964:     }
8965:   }
8966:   if (status) *status = F->schur_status;
8967:   return(0);
8968: }

8970: /*@
8971:   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix

8973:    Logically Collective on Mat

8975:    Input Parameters:
8976: +  F - the factored matrix obtained by calling MatGetFactor()
8977: .  *S - location where to return the Schur complement, can be NULL
8978: -  status - the status of the Schur complement matrix, can be NULL

8980:    Notes:
8981:    You must call MatFactorSetSchurIS() before calling this routine.

8983:    Schur complement mode is currently implemented for sequential matrices.
8984:    The routine returns a the Schur Complement stored within the data strutures of the solver.
8985:    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8986:    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.

8988:    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix

8990:    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.

8992:    Level: advanced

8994:    References:

8996: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8997: @*/
8998: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8999: {
9004:   if (S) *S = F->schur;
9005:   if (status) *status = F->schur_status;
9006:   return(0);
9007: }

9009: /*@
9010:   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement

9012:    Logically Collective on Mat

9014:    Input Parameters:
9015: +  F - the factored matrix obtained by calling MatGetFactor()
9016: .  *S - location where the Schur complement is stored
9017: -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)

9019:    Notes:

9021:    Level: advanced

9023:    References:

9025: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9026: @*/
9027: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9028: {

9033:   if (S) {
9035:     *S = NULL;
9036:   }
9037:   F->schur_status = status;
9038:   MatFactorUpdateSchurStatus_Private(F);
9039:   return(0);
9040: }

9042: /*@
9043:   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step

9045:    Logically Collective on Mat

9047:    Input Parameters:
9048: +  F - the factored matrix obtained by calling MatGetFactor()
9049: .  rhs - location where the right hand side of the Schur complement system is stored
9050: -  sol - location where the solution of the Schur complement system has to be returned

9052:    Notes:
9053:    The sizes of the vectors should match the size of the Schur complement

9055:    Must be called after MatFactorSetSchurIS()

9057:    Level: advanced

9059:    References:

9061: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9062: @*/
9063: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9064: {

9076:   MatFactorFactorizeSchurComplement(F);
9077:   switch (F->schur_status) {
9078:   case MAT_FACTOR_SCHUR_FACTORED:
9079:     MatSolveTranspose(F->schur,rhs,sol);
9080:     break;
9081:   case MAT_FACTOR_SCHUR_INVERTED:
9082:     MatMultTranspose(F->schur,rhs,sol);
9083:     break;
9084:   default:
9085:     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9086:     break;
9087:   }
9088:   return(0);
9089: }

9091: /*@
9092:   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step

9094:    Logically Collective on Mat

9096:    Input Parameters:
9097: +  F - the factored matrix obtained by calling MatGetFactor()
9098: .  rhs - location where the right hand side of the Schur complement system is stored
9099: -  sol - location where the solution of the Schur complement system has to be returned

9101:    Notes:
9102:    The sizes of the vectors should match the size of the Schur complement

9104:    Must be called after MatFactorSetSchurIS()

9106:    Level: advanced

9108:    References:

9110: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9111: @*/
9112: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9113: {

9125:   MatFactorFactorizeSchurComplement(F);
9126:   switch (F->schur_status) {
9127:   case MAT_FACTOR_SCHUR_FACTORED:
9128:     MatSolve(F->schur,rhs,sol);
9129:     break;
9130:   case MAT_FACTOR_SCHUR_INVERTED:
9131:     MatMult(F->schur,rhs,sol);
9132:     break;
9133:   default:
9134:     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9135:     break;
9136:   }
9137:   return(0);
9138: }

9140: /*@
9141:   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step

9143:    Logically Collective on Mat

9145:    Input Parameters:
9146: +  F - the factored matrix obtained by calling MatGetFactor()

9148:    Notes:
9149:     Must be called after MatFactorSetSchurIS().

9151:    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.

9153:    Level: advanced

9155:    References:

9157: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9158: @*/
9159: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9160: {

9166:   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) return(0);
9167:   MatFactorFactorizeSchurComplement(F);
9168:   MatFactorInvertSchurComplement_Private(F);
9169:   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9170:   return(0);
9171: }

9173: /*@
9174:   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step

9176:    Logically Collective on Mat

9178:    Input Parameters:
9179: +  F - the factored matrix obtained by calling MatGetFactor()

9181:    Notes:
9182:     Must be called after MatFactorSetSchurIS().

9184:    Level: advanced

9186:    References:

9188: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9189: @*/
9190: PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9191: {

9197:   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) return(0);
9198:   MatFactorFactorizeSchurComplement_Private(F);
9199:   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9200:   return(0);
9201: }

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

9206:    Neighbor-wise Collective on Mat

9208:    Input Parameters:
9209: +  A - the matrix
9210: .  P - the projection matrix
9211: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9212: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9213:           if the result is a dense matrix this is irrelevent

9215:    Output Parameters:
9216: .  C - the product matrix

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

9221:    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9222:    which inherit from AIJ.

9224:    Level: intermediate

9226: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9227: @*/
9228: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9229: {
9231:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9232:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9233:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9234:   PetscBool      sametype;

9239:   MatCheckPreallocated(A,1);
9240:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9241:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9242:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9245:   MatCheckPreallocated(P,2);
9246:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9247:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9249:   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);
9250:   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);
9251:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9252:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9254:   if (scall == MAT_REUSE_MATRIX) {

9258:     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9259:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9260:     PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9261:     (*(*C)->ops->ptapnumeric)(A,P,*C);
9262:     PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9263:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9264:     return(0);
9265:   }

9267:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9268:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9270:   fA = A->ops->ptap;
9271:   fP = P->ops->ptap;
9272:   PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);
9273:   if (fP == fA && sametype) {
9274:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9275:     ptap = fA;
9276:   } else {
9277:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9278:     char ptapname[256];
9279:     PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));
9280:     PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));
9281:     PetscStrlcat(ptapname,"_",sizeof(ptapname));
9282:     PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));
9283:     PetscStrlcat(ptapname,"_C",sizeof(ptapname)); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9284:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9285:     if (!ptap) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s (Misses composed function %s)",((PetscObject)A)->type_name,((PetscObject)P)->type_name,ptapname);
9286:   }

9288:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9289:   (*ptap)(A,P,scall,fill,C);
9290:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9291:   return(0);
9292: }

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

9297:    Neighbor-wise Collective on Mat

9299:    Input Parameters:
9300: +  A - the matrix
9301: -  P - the projection matrix

9303:    Output Parameters:
9304: .  C - the product matrix

9306:    Notes:
9307:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9308:    the user using MatDeatroy().

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

9313:    Level: intermediate

9315: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9316: @*/
9317: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9318: {

9324:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9325:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9328:   MatCheckPreallocated(P,2);
9329:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9330:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9333:   MatCheckPreallocated(C,3);
9334:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9335:   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);
9336:   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);
9337:   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);
9338:   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);
9339:   MatCheckPreallocated(A,1);

9341:   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9342:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9343:   (*C->ops->ptapnumeric)(A,P,C);
9344:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9345:   return(0);
9346: }

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

9351:    Neighbor-wise Collective on Mat

9353:    Input Parameters:
9354: +  A - the matrix
9355: -  P - the projection matrix

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

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

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

9367:    Level: intermediate

9369: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9370: @*/
9371: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9372: {

9378:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9379:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9380:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9383:   MatCheckPreallocated(P,2);
9384:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9385:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9388:   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);
9389:   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);
9390:   MatCheckPreallocated(A,1);

9392:   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9393:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9394:   (*A->ops->ptapsymbolic)(A,P,fill,C);
9395:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

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

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

9404:    Neighbor-wise Collective on Mat

9406:    Input Parameters:
9407: +  A - the matrix
9408: .  R - the projection matrix
9409: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9410: -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9411:           if the result is a dense matrix this is irrelevent

9413:    Output Parameters:
9414: .  C - the product matrix

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

9419:    This routine is currently only implemented for pairs of AIJ matrices and classes
9420: