Actual source code: matrix.c

petsc-master 2018-04-26
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;
 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_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, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
 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:       PetscViewerASCIIPushTab(viewer);
1015:       MatGetSize(mat,&rows,&cols);
1016:       MatGetBlockSizes(mat,&rbs,&cbs);
1017:       if (rbs != 1 || cbs != 1) {
1018:         if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
1019:         else            {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
1020:       } else {
1021:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
1022:       }
1023:       if (mat->factortype) {
1024:         MatSolverType solver;
1025:         MatFactorGetSolverType(mat,&solver);
1026:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
1027:       }
1028:       if (mat->ops->getinfo) {
1029:         MatInfo info;
1030:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
1031:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
1032:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
1033:       }
1034:       if (mat->nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached null space\n");}
1035:       if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");}
1036:     }
1037: #if defined(PETSC_HAVE_SAWS)
1038:   } else if (issaws) {
1039:     PetscMPIInt rank;

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

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

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

1087:    Collective on PetscViewer

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

1094:    Options Database Keys:
1095:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1096:    block size
1097: .    -matload_block_size <bs>

1099:    Level: beginner

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

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

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

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

1122:    Notes for advanced users:
1123:    Most users should not need to know the details of the binary storage
1124:    format, since MatLoad() and MatView() completely hide these details.
1125:    But for anyone who's interested, the standard binary matrix storage
1126:    format is

1128: $    int    MAT_FILE_CLASSID
1129: $    int    number of rows
1130: $    int    number of columns
1131: $    int    total number of nonzeros
1132: $    int    *number nonzeros in each row
1133: $    int    *column indices of all nonzeros (starting index is zero)
1134: $    PetscScalar *values of all nonzeros

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

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

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

1146:  @*/
1147: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1148: {
1150:   PetscBool      isbinary,flg;

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

1158:   if (!((PetscObject)newmat)->type_name) {
1159:     MatSetType(newmat,MATAIJ);
1160:   }

1162:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1163:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1164:   (*newmat->ops->load)(newmat,viewer);
1165:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

1167:   flg  = PETSC_FALSE;
1168:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1169:   if (flg) {
1170:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1171:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1172:   }
1173:   flg  = PETSC_FALSE;
1174:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1175:   if (flg) {
1176:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1177:   }
1178:   return(0);
1179: }

1181: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1182: {
1184:   Mat_Redundant  *redund = *redundant;
1185:   PetscInt       i;

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

1204:     if (redund->subcomm) {
1205:       PetscCommDestroy(&redund->subcomm);
1206:     }
1207:     PetscFree(redund);
1208:   }
1209:   return(0);
1210: }

1212: /*@
1213:    MatDestroy - Frees space taken by a matrix.

1215:    Collective on Mat

1217:    Input Parameter:
1218: .  A - the matrix

1220:    Level: beginner

1222: @*/
1223: PetscErrorCode MatDestroy(Mat *A)
1224: {

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

1232:   /* if memory was published with SAWs then destroy it */
1233:   PetscObjectSAWsViewOff((PetscObject)*A);
1234:   if ((*A)->ops->destroy) {
1235:     (*(*A)->ops->destroy)(*A);
1236:   }

1238:   PetscFree((*A)->solvertype);
1239:   MatDestroy_Redundant(&(*A)->redundant);
1240:   MatNullSpaceDestroy(&(*A)->nullsp);
1241:   MatNullSpaceDestroy(&(*A)->transnullsp);
1242:   MatNullSpaceDestroy(&(*A)->nearnullsp);
1243:   MatDestroy(&(*A)->schur);
1244:   PetscLayoutDestroy(&(*A)->rmap);
1245:   PetscLayoutDestroy(&(*A)->cmap);
1246:   PetscHeaderDestroy(A);
1247:   return(0);
1248: }

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

1255:    Not Collective

1257:    Input Parameters:
1258: +  mat - the matrix
1259: .  v - a logically two-dimensional array of values
1260: .  m, idxm - the number of rows and their global indices
1261: .  n, idxn - the number of columns and their global indices
1262: -  addv - either ADD_VALUES or INSERT_VALUES, where
1263:    ADD_VALUES adds values to any existing entries, and
1264:    INSERT_VALUES replaces existing entries with new values

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

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

1272:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1273:    options cannot be mixed without intervening calls to the assembly
1274:    routines.

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

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

1284:    Efficiency Alert:
1285:    The routine MatSetValuesBlocked() may offer much better efficiency
1286:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1288:    Level: beginner

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

1294:    Concepts: matrices^putting entries in

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

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

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

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


1350: /*@
1351:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1352:         values into a matrix

1354:    Not Collective

1356:    Input Parameters:
1357: +  mat - the matrix
1358: .  row - the (block) row to set
1359: -  v - a logically two-dimensional array of values

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

1364:    All the nonzeros in the row must be provided

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

1368:    The row must belong to this process

1370:    Level: intermediate

1372:    Concepts: matrices^putting entries in

1374: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1375:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1376: @*/
1377: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1378: {
1380:   PetscInt       globalrow;

1386:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1387:   MatSetValuesRow(mat,globalrow,v);
1388: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
1389:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1390:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1391:   }
1392: #endif
1393:   return(0);
1394: }

1396: /*@
1397:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1398:         values into a matrix

1400:    Not Collective

1402:    Input Parameters:
1403: +  mat - the matrix
1404: .  row - the (block) row to set
1405: -  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

1407:    Notes:
1408:    The values, v, are column-oriented for the block version.

1410:    All the nonzeros in the row must be provided

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

1414:    The row must belong to this process

1416:    Level: advanced

1418:    Concepts: matrices^putting entries in

1420: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1421:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1422: @*/
1423: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1424: {

1430:   MatCheckPreallocated(mat,1);
1432: #if defined(PETSC_USE_DEBUG)
1433:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1434:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1435: #endif
1436:   mat->insertmode = INSERT_VALUES;

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

1454: /*@
1455:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1456:      Using structured grid indexing

1458:    Not Collective

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

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

1474:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1475:    options cannot be mixed without intervening calls to the assembly
1476:    routines.

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

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

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

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

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

1494:    In Fortran idxm and idxn should be declared as
1495: $     MatStencil idxm(4,m),idxn(4,n)
1496:    and the values inserted using
1497: $    idxm(MatStencil_i,1) = i
1498: $    idxm(MatStencil_j,1) = j
1499: $    idxm(MatStencil_k,1) = k
1500: $    idxm(MatStencil_c,1) = c
1501:    etc

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

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

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

1514:    Efficiency Alert:
1515:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1516:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1518:    Level: beginner

1520:    Concepts: matrices^putting entries in

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

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

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

1571: /*@
1572:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1573:      Using structured grid indexing

1575:    Not Collective

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

1588:    Notes:
1589:    By default the values, v, are row-oriented and unsorted.
1590:    See MatSetOption() for other options.

1592:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1593:    options cannot be mixed without intervening calls to the assembly
1594:    routines.

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

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

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

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

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

1612:    In Fortran idxm and idxn should be declared as
1613: $     MatStencil idxm(4,m),idxn(4,n)
1614:    and the values inserted using
1615: $    idxm(MatStencil_i,1) = i
1616: $    idxm(MatStencil_j,1) = j
1617: $    idxm(MatStencil_k,1) = k
1618:    etc

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

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

1628:    Level: beginner

1630:    Concepts: matrices^putting entries in

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

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

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

1687: /*@
1688:    MatSetStencil - Sets the grid information for setting values into a matrix via
1689:         MatSetValuesStencil()

1691:    Not Collective

1693:    Input Parameters:
1694: +  mat - the matrix
1695: .  dim - dimension of the grid 1, 2, or 3
1696: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1697: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1698: -  dof - number of degrees of freedom per node


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

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

1707:    Level: beginner

1709:    Concepts: matrices^putting entries in

1711: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1712:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1713: @*/
1714: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1715: {
1716:   PetscInt i;


1723:   mat->stencil.dim = dim + (dof > 1);
1724:   for (i=0; i<dim; i++) {
1725:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1726:     mat->stencil.starts[i] = starts[dim-i-1];
1727:   }
1728:   mat->stencil.dims[dim]   = dof;
1729:   mat->stencil.starts[dim] = 0;
1730:   mat->stencil.noc         = (PetscBool)(dof == 1);
1731:   return(0);
1732: }

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

1737:    Not Collective

1739:    Input Parameters:
1740: +  mat - the matrix
1741: .  v - a logically two-dimensional array of values
1742: .  m, idxm - the number of block rows and their global block indices
1743: .  n, idxn - the number of block columns and their global block indices
1744: -  addv - either ADD_VALUES or INSERT_VALUES, where
1745:    ADD_VALUES adds values to any existing entries, and
1746:    INSERT_VALUES replaces existing entries with new values

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

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

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

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

1764:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1765:    options cannot be mixed without intervening calls to the assembly
1766:    routines.

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

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

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

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

1797:    Level: intermediate

1799:    Concepts: matrices^putting entries in blocked

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

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

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

1863: /*@
1864:    MatGetValues - Gets a block of values from a matrix.

1866:    Not Collective; currently only returns a local block

1868:    Input Parameters:
1869: +  mat - the matrix
1870: .  v - a logically two-dimensional array for storing the values
1871: .  m, idxm - the number of rows and their global indices
1872: -  n, idxn - the number of columns and their global indices

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

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

1882:    MatGetValues() requires that the matrix has been assembled
1883:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1884:    MatSetValues() and MatGetValues() CANNOT be made in succession
1885:    without intermediate matrix assembly.

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

1890:    Level: advanced

1892:    Concepts: matrices^accessing values

1894: .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1895: @*/
1896: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1897: {

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

1912:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1913:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1914:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1915:   return(0);
1916: }

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

1922:   Not Collective

1924:   Input Parameters:
1925: + mat - the matrix
1926: . nb - the number of blocks
1927: . bs - the number of rows (and columns) in each block
1928: . rows - a concatenation of the rows for each block
1929: - v - a concatenation of logically two-dimensional arrays of values

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

1934:   Level: advanced

1936:   Concepts: matrices^putting entries in

1938: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1939:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1940: @*/
1941: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1942: {

1950: #if defined(PETSC_USE_DEBUG)
1951:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1952: #endif

1954:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1955:   if (mat->ops->setvaluesbatch) {
1956:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1957:   } else {
1958:     PetscInt b;
1959:     for (b = 0; b < nb; ++b) {
1960:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1961:     }
1962:   }
1963:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1964:   return(0);
1965: }

1967: /*@
1968:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1969:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1970:    using a local (per-processor) numbering.

1972:    Not Collective

1974:    Input Parameters:
1975: +  x - the matrix
1976: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
1977: - cmapping - column mapping

1979:    Level: intermediate

1981:    Concepts: matrices^local to global mapping
1982:    Concepts: local to global mapping^for matrices

1984: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1985: @*/
1986: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1987: {


1996:   if (x->ops->setlocaltoglobalmapping) {
1997:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1998:   } else {
1999:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
2000:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
2001:   }
2002:   return(0);
2003: }


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

2009:    Not Collective

2011:    Input Parameters:
2012: .  A - the matrix

2014:    Output Parameters:
2015: + rmapping - row mapping
2016: - cmapping - column mapping

2018:    Level: advanced

2020:    Concepts: matrices^local to global mapping
2021:    Concepts: local to global mapping^for matrices

2023: .seealso:  MatSetValuesLocal()
2024: @*/
2025: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2026: {
2032:   if (rmapping) *rmapping = A->rmap->mapping;
2033:   if (cmapping) *cmapping = A->cmap->mapping;
2034:   return(0);
2035: }

2037: /*@
2038:    MatGetLayouts - Gets the PetscLayout objects for rows and columns

2040:    Not Collective

2042:    Input Parameters:
2043: .  A - the matrix

2045:    Output Parameters:
2046: + rmap - row layout
2047: - cmap - column layout

2049:    Level: advanced

2051: .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2052: @*/
2053: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2054: {
2060:   if (rmap) *rmap = A->rmap;
2061:   if (cmap) *cmap = A->cmap;
2062:   return(0);
2063: }

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

2069:    Not Collective

2071:    Input Parameters:
2072: +  mat - the matrix
2073: .  nrow, irow - number of rows and their local indices
2074: .  ncol, icol - number of columns and their local indices
2075: .  y -  a logically two-dimensional array of values
2076: -  addv - either INSERT_VALUES or ADD_VALUES, where
2077:    ADD_VALUES adds values to any existing entries, and
2078:    INSERT_VALUES replaces existing entries with new values

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

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

2086:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2087:    options cannot be mixed without intervening calls to the assembly
2088:    routines.

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

2093:    Level: intermediate

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

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

2101: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2102:            MatSetValueLocal()
2103: @*/
2104: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2105: {

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

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

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

2158:    Not Collective

2160:    Input Parameters:
2161: +  x - the matrix
2162: .  nrow, irow - number of rows and their local indices
2163: .  ncol, icol - number of columns and their local indices
2164: .  y -  a logically two-dimensional array of values
2165: -  addv - either INSERT_VALUES or ADD_VALUES, where
2166:    ADD_VALUES adds values to any existing entries, and
2167:    INSERT_VALUES replaces existing entries with new values

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

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

2176:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2177:    options cannot be mixed without intervening calls to the assembly
2178:    routines.

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

2183:    Level: intermediate

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

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

2191: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2192:            MatSetValuesLocal(),  MatSetValuesBlocked()
2193: @*/
2194: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2195: {

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

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

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

2247:    Collective on Mat and Vec

2249:    Input Parameters:
2250: +  mat - the matrix
2251: -  x   - the vector to be multiplied

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

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

2260:    Level: developer

2262:    Concepts: matrix-vector product

2264: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2265: @*/
2266: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2267: {


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

2281:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2282:   (*mat->ops->multdiagonalblock)(mat,x,y);
2283:   PetscObjectStateIncrease((PetscObject)y);
2284:   return(0);
2285: }

2287: /* --------------------------------------------------------*/
2288: /*@
2289:    MatMult - Computes the matrix-vector product, y = Ax.

2291:    Neighbor-wise Collective on Mat and Vec

2293:    Input Parameters:
2294: +  mat - the matrix
2295: -  x   - the vector to be multiplied

2297:    Output Parameters:
2298: .  y - the result

2300:    Notes:
2301:    The vectors x and y cannot be the same.  I.e., one cannot
2302:    call MatMult(A,y,y).

2304:    Level: beginner

2306:    Concepts: matrix-vector product

2308: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2309: @*/
2310: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2311: {

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

2331:   VecLockPush(x);
2332:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2333:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2334:   (*mat->ops->mult)(mat,x,y);
2335:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2336:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2337:   VecLockPop(x);
2338:   return(0);
2339: }

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

2344:    Neighbor-wise Collective on Mat and Vec

2346:    Input Parameters:
2347: +  mat - the matrix
2348: -  x   - the vector to be multiplied

2350:    Output Parameters:
2351: .  y - the result

2353:    Notes:
2354:    The vectors x and y cannot be the same.  I.e., one cannot
2355:    call MatMultTranspose(A,y,y).

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

2360:    Level: beginner

2362:    Concepts: matrix vector product^transpose

2364: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2365: @*/
2366: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2367: {


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

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

2397: /*@
2398:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2400:    Neighbor-wise Collective on Mat and Vec

2402:    Input Parameters:
2403: +  mat - the matrix
2404: -  x   - the vector to be multilplied

2406:    Output Parameters:
2407: .  y - the result

2409:    Notes:
2410:    The vectors x and y cannot be the same.  I.e., one cannot
2411:    call MatMultHermitianTranspose(A,y,y).

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

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

2417:    Level: beginner

2419:    Concepts: matrix vector product^transpose

2421: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2422: @*/
2423: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2424: {
2426:   Vec            w;


2434:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2435:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2436:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2437: #if !defined(PETSC_HAVE_CONSTRAINTS)
2438:   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);
2439:   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);
2440: #endif
2441:   MatCheckPreallocated(mat,1);

2443:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2444:   if (mat->ops->multhermitiantranspose) {
2445:     VecLockPush(x);
2446:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2447:     VecLockPop(x);
2448:   } else {
2449:     VecDuplicate(x,&w);
2450:     VecCopy(x,w);
2451:     VecConjugate(w);
2452:     MatMultTranspose(mat,w,y);
2453:     VecDestroy(&w);
2454:     VecConjugate(y);
2455:   }
2456:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2457:   PetscObjectStateIncrease((PetscObject)y);
2458:   return(0);
2459: }

2461: /*@
2462:     MatMultAdd -  Computes v3 = v2 + A * v1.

2464:     Neighbor-wise Collective on Mat and Vec

2466:     Input Parameters:
2467: +   mat - the matrix
2468: -   v1, v2 - the vectors

2470:     Output Parameters:
2471: .   v3 - the result

2473:     Notes:
2474:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2475:     call MatMultAdd(A,v1,v2,v1).

2477:     Level: beginner

2479:     Concepts: matrix vector product^addition

2481: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2482: @*/
2483: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2484: {


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

2504:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2505:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2506:   VecLockPush(v1);
2507:   (*mat->ops->multadd)(mat,v1,v2,v3);
2508:   VecLockPop(v1);
2509:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2510:   PetscObjectStateIncrease((PetscObject)v3);
2511:   return(0);
2512: }

2514: /*@
2515:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2517:    Neighbor-wise Collective on Mat and Vec

2519:    Input Parameters:
2520: +  mat - the matrix
2521: -  v1, v2 - the vectors

2523:    Output Parameters:
2524: .  v3 - the result

2526:    Notes:
2527:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2528:    call MatMultTransposeAdd(A,v1,v2,v1).

2530:    Level: beginner

2532:    Concepts: matrix vector product^transpose and addition

2534: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2535: @*/
2536: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2537: {


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

2556:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2557:   VecLockPush(v1);
2558:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2559:   VecLockPop(v1);
2560:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2561:   PetscObjectStateIncrease((PetscObject)v3);
2562:   return(0);
2563: }

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

2568:    Neighbor-wise Collective on Mat and Vec

2570:    Input Parameters:
2571: +  mat - the matrix
2572: -  v1, v2 - the vectors

2574:    Output Parameters:
2575: .  v3 - the result

2577:    Notes:
2578:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2579:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2581:    Level: beginner

2583:    Concepts: matrix vector product^transpose and addition

2585: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2586: @*/
2587: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2588: {


2598:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2599:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2600:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2601:   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);
2602:   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);
2603:   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);
2604:   MatCheckPreallocated(mat,1);

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

2628: /*@
2629:    MatMultConstrained - The inner multiplication routine for a
2630:    constrained matrix P^T A P.

2632:    Neighbor-wise Collective on Mat and Vec

2634:    Input Parameters:
2635: +  mat - the matrix
2636: -  x   - the vector to be multilplied

2638:    Output Parameters:
2639: .  y - the result

2641:    Notes:
2642:    The vectors x and y cannot be the same.  I.e., one cannot
2643:    call MatMult(A,y,y).

2645:    Level: beginner

2647: .keywords: matrix, multiply, matrix-vector product, constraint
2648: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2649: @*/
2650: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2651: {

2658:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2659:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2660:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2661:   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);
2662:   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);
2663:   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);

2665:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2666:   VecLockPush(x);
2667:   (*mat->ops->multconstrained)(mat,x,y);
2668:   VecLockPop(x);
2669:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2670:   PetscObjectStateIncrease((PetscObject)y);
2671:   return(0);
2672: }

2674: /*@
2675:    MatMultTransposeConstrained - The inner multiplication routine for a
2676:    constrained matrix P^T A^T P.

2678:    Neighbor-wise Collective on Mat and Vec

2680:    Input Parameters:
2681: +  mat - the matrix
2682: -  x   - the vector to be multilplied

2684:    Output Parameters:
2685: .  y - the result

2687:    Notes:
2688:    The vectors x and y cannot be the same.  I.e., one cannot
2689:    call MatMult(A,y,y).

2691:    Level: beginner

2693: .keywords: matrix, multiply, matrix-vector product, constraint
2694: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2695: @*/
2696: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2697: {

2704:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2705:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2706:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2707:   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);
2708:   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);

2710:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2711:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2712:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2713:   PetscObjectStateIncrease((PetscObject)y);
2714:   return(0);
2715: }

2717: /*@C
2718:    MatGetFactorType - gets the type of factorization it is

2720:    Note Collective
2721:    as the flag

2723:    Input Parameters:
2724: .  mat - the matrix

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

2729:     Level: intermediate

2731: .seealso:    MatFactorType, MatGetFactor()
2732: @*/
2733: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2734: {
2738:   *t = mat->factortype;
2739:   return(0);
2740: }

2742: /* ------------------------------------------------------------*/
2743: /*@C
2744:    MatGetInfo - Returns information about matrix storage (number of
2745:    nonzeros, memory, etc.).

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

2749:    Input Parameters:
2750: .  mat - the matrix

2752:    Output Parameters:
2753: +  flag - flag indicating the type of parameters to be returned
2754:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2755:    MAT_GLOBAL_SUM - sum over all processors)
2756: -  info - matrix information context

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

2767:    Example for C/C++ Users:
2768:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2769:    data within the MatInfo context.  For example,
2770: .vb
2771:       MatInfo info;
2772:       Mat     A;
2773:       double  mal, nz_a, nz_u;

2775:       MatGetInfo(A,MAT_LOCAL,&info);
2776:       mal  = info.mallocs;
2777:       nz_a = info.nz_allocated;
2778: .ve

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

2791:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2792:       mal = info(MAT_INFO_MALLOCS)
2793:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2794: .ve

2796:     Level: intermediate

2798:     Concepts: matrices^getting information on

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

2803: .seealso: MatStashGetInfo()

2805: @*/
2806: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2807: {

2814:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2815:   MatCheckPreallocated(mat,1);
2816:   (*mat->ops->getinfo)(mat,flag,info);
2817:   return(0);
2818: }

2820: /*
2821:    This is used by external packages where it is not easy to get the info from the actual
2822:    matrix factorization.
2823: */
2824: PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2825: {

2829:   PetscMemzero(info,sizeof(MatInfo));
2830:   return(0);
2831: }

2833: /* ----------------------------------------------------------*/

2835: /*@C
2836:    MatLUFactor - Performs in-place LU factorization of matrix.

2838:    Collective on Mat

2840:    Input Parameters:
2841: +  mat - the matrix
2842: .  row - row permutation
2843: .  col - column permutation
2844: -  info - options for factorization, includes
2845: $          fill - expected fill as ratio of original fill.
2846: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2847: $                   Run with the option -info to determine an optimal value to use

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

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

2857:    Level: developer

2859:    Concepts: matrices^LU factorization

2861: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2862:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2867: @*/
2868: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2869: {
2871:   MatFactorInfo  tinfo;

2879:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2880:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2881:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2882:   MatCheckPreallocated(mat,1);
2883:   if (!info) {
2884:     MatFactorInfoInitialize(&tinfo);
2885:     info = &tinfo;
2886:   }

2888:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2889:   (*mat->ops->lufactor)(mat,row,col,info);
2890:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2891:   PetscObjectStateIncrease((PetscObject)mat);
2892:   return(0);
2893: }

2895: /*@C
2896:    MatILUFactor - Performs in-place ILU factorization of matrix.

2898:    Collective on Mat

2900:    Input Parameters:
2901: +  mat - the matrix
2902: .  row - row permutation
2903: .  col - column permutation
2904: -  info - structure containing
2905: $      levels - number of levels of fill.
2906: $      expected fill - as ratio of original fill.
2907: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2908:                 missing diagonal entries)

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

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

2918:    Level: developer

2920:    Concepts: matrices^ILU factorization

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

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

2927: @*/
2928: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2929: {

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

2944:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2945:   (*mat->ops->ilufactor)(mat,row,col,info);
2946:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2947:   PetscObjectStateIncrease((PetscObject)mat);
2948:   return(0);
2949: }

2951: /*@C
2952:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2953:    Call this routine before calling MatLUFactorNumeric().

2955:    Collective on Mat

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


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

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

2974:    Level: developer

2976:    Concepts: matrices^LU symbolic factorization

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

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

2983: @*/
2984: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2985: {

2995:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2996:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2997:   if (!(fact)->ops->lufactorsymbolic) {
2998:     MatSolverType spackage;
2999:     MatFactorGetSolverType(fact,&spackage);
3000:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3001:   }
3002:   MatCheckPreallocated(mat,2);

3004:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
3005:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
3006:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
3007:   PetscObjectStateIncrease((PetscObject)fact);
3008:   return(0);
3009: }

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

3015:    Collective on Mat

3017:    Input Parameters:
3018: +  fact - the factor matrix obtained with MatGetFactor()
3019: .  mat - the matrix
3020: -  info - options for factorization

3022:    Notes:
3023:    See MatLUFactor() for in-place factorization.  See
3024:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

3030:    Level: developer

3032:    Concepts: matrices^LU numeric factorization

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

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

3039: @*/
3040: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3041: {

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

3052:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3053:   MatCheckPreallocated(mat,2);
3054:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
3055:   (fact->ops->lufactornumeric)(fact,mat,info);
3056:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
3057:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3058:   PetscObjectStateIncrease((PetscObject)fact);
3059:   return(0);
3060: }

3062: /*@C
3063:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3064:    symmetric matrix.

3066:    Collective on Mat

3068:    Input Parameters:
3069: +  mat - the matrix
3070: .  perm - row and column permutations
3071: -  f - expected fill as ratio of original fill

3073:    Notes:
3074:    See MatLUFactor() for the nonsymmetric case.  See also
3075:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

3081:    Level: developer

3083:    Concepts: matrices^Cholesky factorization

3085: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3086:           MatGetOrdering()

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

3091: @*/
3092: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3093: {

3101:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3102:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3103:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3104:   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);
3105:   MatCheckPreallocated(mat,1);

3107:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3108:   (*mat->ops->choleskyfactor)(mat,perm,info);
3109:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3110:   PetscObjectStateIncrease((PetscObject)mat);
3111:   return(0);
3112: }

3114: /*@C
3115:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3116:    of a symmetric matrix.

3118:    Collective on Mat

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

3129:    Notes:
3130:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3131:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

3137:    Level: developer

3139:    Concepts: matrices^Cholesky symbolic factorization

3141: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3142:           MatGetOrdering()

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

3147: @*/
3148: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3149: {

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

3168:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3169:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3170:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3171:   PetscObjectStateIncrease((PetscObject)fact);
3172:   return(0);
3173: }

3175: /*@C
3176:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3177:    of a symmetric matrix. Call this routine after first calling
3178:    MatCholeskyFactorSymbolic().

3180:    Collective on Mat

3182:    Input Parameters:
3183: +  fact - the factor matrix obtained with MatGetFactor()
3184: .  mat - the initial matrix
3185: .  info - options for factorization
3186: -  fact - the symbolic factor of mat


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

3194:    Level: developer

3196:    Concepts: matrices^Cholesky numeric factorization

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

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

3203: @*/
3204: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3205: {

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

3218:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3219:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3220:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3221:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
3222:   PetscObjectStateIncrease((PetscObject)fact);
3223:   return(0);
3224: }

3226: /* ----------------------------------------------------------------*/
3227: /*@
3228:    MatSolve - Solves A x = b, given a factored matrix.

3230:    Neighbor-wise Collective on Mat and Vec

3232:    Input Parameters:
3233: +  mat - the factored matrix
3234: -  b - the right-hand-side vector

3236:    Output Parameter:
3237: .  x - the result vector

3239:    Notes:
3240:    The vectors b and x cannot be the same.  I.e., one cannot
3241:    call MatSolve(A,x,x).

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

3248:    Level: developer

3250:    Concepts: matrices^triangular solves

3252: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3253: @*/
3254: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3255: {

3265:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3266:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3267:   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);
3268:   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);
3269:   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);
3270:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3271:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3272:   MatCheckPreallocated(mat,1);

3274:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3275:   if (mat->factorerrortype) {
3276:     PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3277:     VecSetInf(x);
3278:   } else {
3279:     (*mat->ops->solve)(mat,b,x);
3280:   }
3281:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3282:   PetscObjectStateIncrease((PetscObject)x);
3283:   return(0);
3284: }

3286: static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3287: {
3289:   Vec            b,x;
3290:   PetscInt       m,N,i;
3291:   PetscScalar    *bb,*xx;
3292:   PetscBool      flg;

3295:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3296:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3297:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3298:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

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

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

3326:    Neighbor-wise Collective on Mat

3328:    Input Parameters:
3329: +  A - the factored matrix
3330: -  B - the right-hand-side matrix  (dense matrix)

3332:    Output Parameter:
3333: .  X - the result matrix (dense matrix)

3335:    Notes:
3336:    The matrices b and x cannot be the same.  I.e., one cannot
3337:    call MatMatSolve(A,x,x).

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

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

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

3350:    Level: developer

3352:    Concepts: matrices^triangular solves

3354: .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3355: @*/
3356: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3357: {

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

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

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

3391:    Neighbor-wise Collective on Mat

3393:    Input Parameters:
3394: +  A - the factored matrix
3395: -  B - the right-hand-side matrix  (dense matrix)

3397:    Output Parameter:
3398: .  X - the result matrix (dense matrix)

3400:    Notes:
3401:    The matrices b and x cannot be the same.  I.e., one cannot
3402:    call MatMatSolveTranspose(A,x,x).

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

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

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

3415:    Level: developer

3417:    Concepts: matrices^triangular solves

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

3432:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3433:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
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:   MatCheckPreallocated(A,1);

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

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

3457:    Neighbor-wise Collective on Mat and Vec

3459:    Input Parameters:
3460: +  mat - the factored matrix
3461: -  b - the right-hand-side vector

3463:    Output Parameter:
3464: .  x - the result vector

3466:    Notes:
3467:    MatSolve() should be used for most applications, as it performs
3468:    a forward solve followed by a backward solve.

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

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

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

3483:    Level: developer

3485:    Concepts: matrices^forward solves

3487: .seealso: MatSolve(), MatBackwardSolve()
3488: @*/
3489: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3490: {

3500:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3501:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3502:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3503:   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);
3504:   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);
3505:   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);
3506:   MatCheckPreallocated(mat,1);
3507:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3508:   (*mat->ops->forwardsolve)(mat,b,x);
3509:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3510:   PetscObjectStateIncrease((PetscObject)x);
3511:   return(0);
3512: }

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

3518:    Neighbor-wise Collective on Mat and Vec

3520:    Input Parameters:
3521: +  mat - the factored matrix
3522: -  b - the right-hand-side vector

3524:    Output Parameter:
3525: .  x - the result vector

3527:    Notes:
3528:    MatSolve() should be used for most applications, as it performs
3529:    a forward solve followed by a backward solve.

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

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

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

3544:    Level: developer

3546:    Concepts: matrices^backward solves

3548: .seealso: MatSolve(), MatForwardSolve()
3549: @*/
3550: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3551: {

3561:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3562:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3563:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3564:   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);
3565:   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);
3566:   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);
3567:   MatCheckPreallocated(mat,1);

3569:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3570:   (*mat->ops->backwardsolve)(mat,b,x);
3571:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3572:   PetscObjectStateIncrease((PetscObject)x);
3573:   return(0);
3574: }

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

3579:    Neighbor-wise Collective on Mat and Vec

3581:    Input Parameters:
3582: +  mat - the factored matrix
3583: .  b - the right-hand-side vector
3584: -  y - the vector to be added to

3586:    Output Parameter:
3587: .  x - the result vector

3589:    Notes:
3590:    The vectors b and x cannot be the same.  I.e., one cannot
3591:    call MatSolveAdd(A,x,y,x).

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

3597:    Level: developer

3599:    Concepts: matrices^triangular solves

3601: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3602: @*/
3603: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3604: {
3605:   PetscScalar    one = 1.0;
3606:   Vec            tmp;

3618:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3619:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
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 != 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);
3623:   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);
3624:   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);
3625:   MatCheckPreallocated(mat,1);

3627:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3628:   if (mat->ops->solveadd) {
3629:     (*mat->ops->solveadd)(mat,b,y,x);
3630:   } else {
3631:     /* do the solve then the add manually */
3632:     if (x != y) {
3633:       MatSolve(mat,b,x);
3634:       VecAXPY(x,one,y);
3635:     } else {
3636:       VecDuplicate(x,&tmp);
3637:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3638:       VecCopy(x,tmp);
3639:       MatSolve(mat,b,x);
3640:       VecAXPY(x,one,tmp);
3641:       VecDestroy(&tmp);
3642:     }
3643:   }
3644:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3645:   PetscObjectStateIncrease((PetscObject)x);
3646:   return(0);
3647: }

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

3652:    Neighbor-wise Collective on Mat and Vec

3654:    Input Parameters:
3655: +  mat - the factored matrix
3656: -  b - the right-hand-side vector

3658:    Output Parameter:
3659: .  x - the result vector

3661:    Notes:
3662:    The vectors b and x cannot be the same.  I.e., one cannot
3663:    call MatSolveTranspose(A,x,x).

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

3669:    Level: developer

3671:    Concepts: matrices^triangular solves

3673: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3674: @*/
3675: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3676: {

3686:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3687:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3688:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3689:   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);
3690:   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);
3691:   MatCheckPreallocated(mat,1);
3692:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3693:   if (mat->factorerrortype) {
3694:     PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3695:     VecSetInf(x);
3696:   } else {
3697:     (*mat->ops->solvetranspose)(mat,b,x);
3698:   }
3699:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3700:   PetscObjectStateIncrease((PetscObject)x);
3701:   return(0);
3702: }

3704: /*@
3705:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3706:                       factored matrix.

3708:    Neighbor-wise Collective on Mat and Vec

3710:    Input Parameters:
3711: +  mat - the factored matrix
3712: .  b - the right-hand-side vector
3713: -  y - the vector to be added to

3715:    Output Parameter:
3716: .  x - the result vector

3718:    Notes:
3719:    The vectors b and x cannot be the same.  I.e., one cannot
3720:    call MatSolveTransposeAdd(A,x,y,x).

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

3726:    Level: developer

3728:    Concepts: matrices^triangular solves

3730: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3731: @*/
3732: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3733: {
3734:   PetscScalar    one = 1.0;
3736:   Vec            tmp;

3747:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3748:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3749:   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);
3750:   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);
3751:   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);
3752:   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);
3753:   MatCheckPreallocated(mat,1);

3755:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3756:   if (mat->ops->solvetransposeadd) {
3757:     if (mat->factorerrortype) {
3758:       PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3759:       VecSetInf(x);
3760:     } else {
3761:       (*mat->ops->solvetransposeadd)(mat,b,y,x);
3762:     }
3763:   } else {
3764:     /* do the solve then the add manually */
3765:     if (x != y) {
3766:       MatSolveTranspose(mat,b,x);
3767:       VecAXPY(x,one,y);
3768:     } else {
3769:       VecDuplicate(x,&tmp);
3770:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3771:       VecCopy(x,tmp);
3772:       MatSolveTranspose(mat,b,x);
3773:       VecAXPY(x,one,tmp);
3774:       VecDestroy(&tmp);
3775:     }
3776:   }
3777:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3778:   PetscObjectStateIncrease((PetscObject)x);
3779:   return(0);
3780: }
3781: /* ----------------------------------------------------------------*/

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

3786:    Neighbor-wise Collective on Mat and Vec

3788:    Input Parameters:
3789: +  mat - the matrix
3790: .  b - the right hand side
3791: .  omega - the relaxation factor
3792: .  flag - flag indicating the type of SOR (see below)
3793: .  shift -  diagonal shift
3794: .  its - the number of iterations
3795: -  lits - the number of local iterations

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

3800:    SOR Flags:
3801: .     SOR_FORWARD_SWEEP - forward SOR
3802: .     SOR_BACKWARD_SWEEP - backward SOR
3803: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3804: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3805: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3806: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3807: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3808:          upper/lower triangular part of matrix to
3809:          vector (with omega)
3810: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3812:    Notes:
3813:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3814:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3815:    on each processor.

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

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

3823:    Notes for Advanced Users:
3824:    The flags are implemented as bitwise inclusive or operations.
3825:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3826:    to specify a zero initial guess for SSOR.

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

3832:    Vectors x and b CANNOT be the same

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

3836:    Level: developer

3838:    Concepts: matrices^relaxation
3839:    Concepts: matrices^SOR
3840:    Concepts: matrices^Gauss-Seidel

3842: @*/
3843: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3844: {

3854:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3855:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3856:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3857:   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);
3858:   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);
3859:   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);
3860:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3861:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3862:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3864:   MatCheckPreallocated(mat,1);
3865:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3866:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3867:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3868:   PetscObjectStateIncrease((PetscObject)x);
3869:   return(0);
3870: }

3872: /*
3873:       Default matrix copy routine.
3874: */
3875: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3876: {
3877:   PetscErrorCode    ierr;
3878:   PetscInt          i,rstart = 0,rend = 0,nz;
3879:   const PetscInt    *cwork;
3880:   const PetscScalar *vwork;

3883:   if (B->assembled) {
3884:     MatZeroEntries(B);
3885:   }
3886:   MatGetOwnershipRange(A,&rstart,&rend);
3887:   for (i=rstart; i<rend; i++) {
3888:     MatGetRow(A,i,&nz,&cwork,&vwork);
3889:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3890:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3891:   }
3892:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3893:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3894:   return(0);
3895: }

3897: /*@
3898:    MatCopy - Copys a matrix to another matrix.

3900:    Collective on Mat

3902:    Input Parameters:
3903: +  A - the matrix
3904: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3906:    Output Parameter:
3907: .  B - where the copy is put

3909:    Notes:
3910:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3911:    same nonzero pattern or the routine will crash.

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

3917:    Level: intermediate

3919:    Concepts: matrices^copying

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

3923: @*/
3924: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3925: {
3927:   PetscInt       i;

3935:   MatCheckPreallocated(B,2);
3936:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3937:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3938:   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);
3939:   MatCheckPreallocated(A,1);
3940:   if (A == B) return(0);

3942:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3943:   if (A->ops->copy) {
3944:     (*A->ops->copy)(A,B,str);
3945:   } else { /* generic conversion */
3946:     MatCopy_Basic(A,B,str);
3947:   }

3949:   B->stencil.dim = A->stencil.dim;
3950:   B->stencil.noc = A->stencil.noc;
3951:   for (i=0; i<=A->stencil.dim; i++) {
3952:     B->stencil.dims[i]   = A->stencil.dims[i];
3953:     B->stencil.starts[i] = A->stencil.starts[i];
3954:   }

3956:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3957:   PetscObjectStateIncrease((PetscObject)B);
3958:   return(0);
3959: }

3961: /*@C
3962:    MatConvert - Converts a matrix to another matrix, either of the same
3963:    or different type.

3965:    Collective on Mat

3967:    Input Parameters:
3968: +  mat - the matrix
3969: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3970:    same type as the original matrix.
3971: -  reuse - denotes if the destination matrix is to be created or reused.
3972:    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
3973:    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).

3975:    Output Parameter:
3976: .  M - pointer to place new matrix

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

3983:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3984:    the MPI communicator of the generated matrix is always the same as the communicator
3985:    of the input matrix.

3987:    Level: intermediate

3989:    Concepts: matrices^converting between storage formats

3991: .seealso: MatCopy(), MatDuplicate()
3992: @*/
3993: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3994: {
3996:   PetscBool      sametype,issame,flg;
3997:   char           convname[256],mtype[256];
3998:   Mat            B;

4004:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4005:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4006:   MatCheckPreallocated(mat,1);
4007:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

4009:   PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
4010:   if (flg) {
4011:     newtype = mtype;
4012:   }
4013:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
4014:   PetscStrcmp(newtype,"same",&issame);
4015:   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4016:   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");

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

4020:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4021:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
4022:   } else {
4023:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4024:     const char     *prefix[3] = {"seq","mpi",""};
4025:     PetscInt       i;
4026:     /*
4027:        Order of precedence:
4028:        1) See if a specialized converter is known to the current matrix.
4029:        2) See if a specialized converter is known to the desired matrix class.
4030:        3) See if a good general converter is registered for the desired class
4031:           (as of 6/27/03 only MATMPIADJ falls into this category).
4032:        4) See if a good general converter is known for the current matrix.
4033:        5) Use a really basic converter.
4034:     */

4036:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4037:     for (i=0; i<3; i++) {
4038:       PetscStrncpy(convname,"MatConvert_",sizeof(convname));
4039:       PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));
4040:       PetscStrlcat(convname,"_",sizeof(convname));
4041:       PetscStrlcat(convname,prefix[i],sizeof(convname));
4042:       PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));
4043:       PetscStrlcat(convname,"_C",sizeof(convname));
4044:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4045:       if (conv) goto foundconv;
4046:     }

4048:     /* 2)  See if a specialized converter is known to the desired matrix class. */
4049:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
4050:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
4051:     MatSetType(B,newtype);
4052:     for (i=0; i<3; i++) {
4053:       PetscStrncpy(convname,"MatConvert_",sizeof(convname));
4054:       PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));
4055:       PetscStrlcat(convname,"_",sizeof(convname));
4056:       PetscStrlcat(convname,prefix[i],sizeof(convname));
4057:       PetscStrlcat(convname,newtype,sizeof(convname));
4058:       PetscStrlcat(convname,"_C",sizeof(convname));
4059:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
4060:       if (conv) {
4061:         MatDestroy(&B);
4062:         goto foundconv;
4063:       }
4064:     }

4066:     /* 3) See if a good general converter is registered for the desired class */
4067:     conv = B->ops->convertfrom;
4068:     MatDestroy(&B);
4069:     if (conv) goto foundconv;

4071:     /* 4) See if a good general converter is known for the current matrix */
4072:     if (mat->ops->convert) {
4073:       conv = mat->ops->convert;
4074:     }
4075:     if (conv) goto foundconv;

4077:     /* 5) Use a really basic converter. */
4078:     conv = MatConvert_Basic;

4080: foundconv:
4081:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4082:     (*conv)(mat,newtype,reuse,M);
4083:     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4084:       /* the block sizes must be same if the mappings are copied over */
4085:       (*M)->rmap->bs = mat->rmap->bs;
4086:       (*M)->cmap->bs = mat->cmap->bs;
4087:       PetscObjectReference((PetscObject)mat->rmap->mapping);
4088:       PetscObjectReference((PetscObject)mat->cmap->mapping);
4089:       (*M)->rmap->mapping = mat->rmap->mapping;
4090:       (*M)->cmap->mapping = mat->cmap->mapping;
4091:     }
4092:     (*M)->stencil.dim = mat->stencil.dim;
4093:     (*M)->stencil.noc = mat->stencil.noc;
4094:     for (i=0; i<=mat->stencil.dim; i++) {
4095:       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4096:       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4097:     }
4098:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4099:   }
4100:   PetscObjectStateIncrease((PetscObject)*M);

4102:   /* Copy Mat options */
4103:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
4104:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
4105:   return(0);
4106: }

4108: /*@C
4109:    MatFactorGetSolverType - Returns name of the package providing the factorization routines

4111:    Not Collective

4113:    Input Parameter:
4114: .  mat - the matrix, must be a factored matrix

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

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

4123:    Level: intermediate

4125: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4126: @*/
4127: PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4128: {
4129:   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);

4134:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4135:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);
4136:   if (!conv) {
4137:     *type = MATSOLVERPETSC;
4138:   } else {
4139:     (*conv)(mat,type);
4140:   }
4141:   return(0);
4142: }

4144: typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4145: struct _MatSolverTypeForSpecifcType {
4146:   MatType                        mtype;
4147:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4148:   MatSolverTypeForSpecifcType next;
4149: };

4151: typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4152: struct _MatSolverTypeHolder {
4153:   char                           *name;
4154:   MatSolverTypeForSpecifcType handlers;
4155:   MatSolverTypeHolder         next;
4156: };

4158: static MatSolverTypeHolder MatSolverTypeHolders = NULL;

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

4163:    Input Parameters:
4164: +    package - name of the package, for example petsc or superlu
4165: .    mtype - the matrix type that works with this package
4166: .    ftype - the type of factorization supported by the package
4167: -    getfactor - routine that will create the factored matrix ready to be used

4169:     Level: intermediate

4171: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4172: @*/
4173: PetscErrorCode MatSolverTypeRegister(MatSolverType package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4174: {
4175:   PetscErrorCode              ierr;
4176:   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4177:   PetscBool                   flg;
4178:   MatSolverTypeForSpecifcType inext,iprev = NULL;

4181:   if (!next) {
4182:     PetscNew(&MatSolverTypeHolders);
4183:     PetscStrallocpy(package,&MatSolverTypeHolders->name);
4184:     PetscNew(&MatSolverTypeHolders->handlers);
4185:     PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);
4186:     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4187:     return(0);
4188:   }
4189:   while (next) {
4190:     PetscStrcasecmp(package,next->name,&flg);
4191:     if (flg) {
4192:       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4193:       inext = next->handlers;
4194:       while (inext) {
4195:         PetscStrcasecmp(mtype,inext->mtype,&flg);
4196:         if (flg) {
4197:           inext->getfactor[(int)ftype-1] = getfactor;
4198:           return(0);
4199:         }
4200:         iprev = inext;
4201:         inext = inext->next;
4202:       }
4203:       PetscNew(&iprev->next);
4204:       PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4205:       iprev->next->getfactor[(int)ftype-1] = getfactor;
4206:       return(0);
4207:     }
4208:     prev = next;
4209:     next = next->next;
4210:   }
4211:   PetscNew(&prev->next);
4212:   PetscStrallocpy(package,&prev->next->name);
4213:   PetscNew(&prev->next->handlers);
4214:   PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4215:   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4216:   return(0);
4217: }

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

4222:    Input Parameters:
4223: +    package - name of the package, for example petsc or superlu
4224: .    ftype - the type of factorization supported by the package
4225: -    mtype - the matrix type that works with this package

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

4232:     Level: intermediate

4234: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4235: @*/
4236: PetscErrorCode MatSolverTypeGet(MatSolverType package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4237: {
4238:   PetscErrorCode                 ierr;
4239:   MatSolverTypeHolder         next = MatSolverTypeHolders;
4240:   PetscBool                      flg;
4241:   MatSolverTypeForSpecifcType inext;

4244:   if (foundpackage) *foundpackage = PETSC_FALSE;
4245:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4246:   if (getfactor)    *getfactor    = NULL;

4248:   if (package) {
4249:     while (next) {
4250:       PetscStrcasecmp(package,next->name,&flg);
4251:       if (flg) {
4252:         if (foundpackage) *foundpackage = PETSC_TRUE;
4253:         inext = next->handlers;
4254:         while (inext) {
4255:           PetscStrbeginswith(mtype,inext->mtype,&flg);
4256:           if (flg) {
4257:             if (foundmtype) *foundmtype = PETSC_TRUE;
4258:             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4259:             return(0);
4260:           }
4261:           inext = inext->next;
4262:         }
4263:       }
4264:       next = next->next;
4265:     }
4266:   } else {
4267:     while (next) {
4268:       inext = next->handlers;
4269:       while (inext) {
4270:         PetscStrbeginswith(mtype,inext->mtype,&flg);
4271:         if (flg && inext->getfactor[(int)ftype-1]) {
4272:           if (foundpackage) *foundpackage = PETSC_TRUE;
4273:           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4274:           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4275:           return(0);
4276:         }
4277:         inext = inext->next;
4278:       }
4279:       next = next->next;
4280:     }
4281:   }
4282:   return(0);
4283: }

4285: PetscErrorCode MatSolverTypeDestroy(void)
4286: {
4287:   PetscErrorCode              ierr;
4288:   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4289:   MatSolverTypeForSpecifcType inext,iprev;

4292:   while (next) {
4293:     PetscFree(next->name);
4294:     inext = next->handlers;
4295:     while (inext) {
4296:       PetscFree(inext->mtype);
4297:       iprev = inext;
4298:       inext = inext->next;
4299:       PetscFree(iprev);
4300:     }
4301:     prev = next;
4302:     next = next->next;
4303:     PetscFree(prev);
4304:   }
4305:   MatSolverTypeHolders = NULL;
4306:   return(0);
4307: }

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

4312:    Collective on Mat

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

4319:    Output Parameters:
4320: .  f - the factor matrix used with MatXXFactorSymbolic() calls

4322:    Notes:
4323:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4324:      such as pastix, superlu, mumps etc.

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

4328:    Level: intermediate

4330: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4331: @*/
4332: PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4333: {
4334:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4335:   PetscBool      foundpackage,foundmtype;


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

4344:   MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4345:   if (!foundpackage) {
4346:     if (type) {
4347:       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4348:     } else {
4349:       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4350:     }
4351:   }

4353:   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4354:   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);

4356: #if defined(PETSC_USE_COMPLEX)
4357:   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");
4358: #endif

4360:   (*conv)(mat,ftype,f);
4361:   return(0);
4362: }

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

4367:    Not Collective

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

4374:    Output Parameter:
4375: .    flg - PETSC_TRUE if the factorization is available

4377:    Notes:
4378:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4379:      such as pastix, superlu, mumps etc.

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

4383:    Level: intermediate

4385: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4386: @*/
4387: PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4388: {
4389:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);


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

4398:   *flg = PETSC_FALSE;
4399:   MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4400:   if (gconv) {
4401:     *flg = PETSC_TRUE;
4402:   }
4403:   return(0);
4404: }

4406:  #include <petscdmtypes.h>

4408: /*@
4409:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4411:    Collective on Mat

4413:    Input Parameters:
4414: +  mat - the matrix
4415: -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4416:         See the manual page for MatDuplicateOption for an explanation of these options.

4418:    Output Parameter:
4419: .  M - pointer to place new matrix

4421:    Level: intermediate

4423:    Concepts: matrices^duplicating

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

4428: .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4429: @*/
4430: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4431: {
4433:   Mat            B;
4434:   PetscInt       i;
4435:   DM             dm;

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

4445:   *M = 0;
4446:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4447:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4448:   (*mat->ops->duplicate)(mat,op,M);
4449:   B    = *M;

4451:   B->stencil.dim = mat->stencil.dim;
4452:   B->stencil.noc = mat->stencil.noc;
4453:   for (i=0; i<=mat->stencil.dim; i++) {
4454:     B->stencil.dims[i]   = mat->stencil.dims[i];
4455:     B->stencil.starts[i] = mat->stencil.starts[i];
4456:   }

4458:   B->nooffproczerorows = mat->nooffproczerorows;
4459:   B->nooffprocentries  = mat->nooffprocentries;

4461:   PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4462:   if (dm) {
4463:     PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4464:   }
4465:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4466:   PetscObjectStateIncrease((PetscObject)B);
4467:   return(0);
4468: }

4470: /*@
4471:    MatGetDiagonal - Gets the diagonal of a matrix.

4473:    Logically Collective on Mat and Vec

4475:    Input Parameters:
4476: +  mat - the matrix
4477: -  v - the vector for storing the diagonal

4479:    Output Parameter:
4480: .  v - the diagonal of the matrix

4482:    Level: intermediate

4484:    Note:
4485:    Currently only correct in parallel for square matrices.

4487:    Concepts: matrices^accessing diagonals

4489: .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4490: @*/
4491: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4492: {

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

4503:   (*mat->ops->getdiagonal)(mat,v);
4504:   PetscObjectStateIncrease((PetscObject)v);
4505:   return(0);
4506: }

4508: /*@C
4509:    MatGetRowMin - Gets the minimum value (of the real part) of each
4510:         row of the matrix

4512:    Logically Collective on Mat and Vec

4514:    Input Parameters:
4515: .  mat - the matrix

4517:    Output Parameter:
4518: +  v - the vector for storing the maximums
4519: -  idx - the indices of the column found for each row (optional)

4521:    Level: intermediate

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

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

4529:    Concepts: matrices^getting row maximums

4531: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4532:           MatGetRowMax()
4533: @*/
4534: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4535: {

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

4546:   (*mat->ops->getrowmin)(mat,v,idx);
4547:   PetscObjectStateIncrease((PetscObject)v);
4548:   return(0);
4549: }

4551: /*@C
4552:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4553:         row of the matrix

4555:    Logically Collective on Mat and Vec

4557:    Input Parameters:
4558: .  mat - the matrix

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

4564:    Level: intermediate

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

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

4572:    Concepts: matrices^getting row maximums

4574: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4575: @*/
4576: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4577: {

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

4589:   (*mat->ops->getrowminabs)(mat,v,idx);
4590:   PetscObjectStateIncrease((PetscObject)v);
4591:   return(0);
4592: }

4594: /*@C
4595:    MatGetRowMax - Gets the maximum value (of the real part) of each
4596:         row of the matrix

4598:    Logically Collective on Mat and Vec

4600:    Input Parameters:
4601: .  mat - the matrix

4603:    Output Parameter:
4604: +  v - the vector for storing the maximums
4605: -  idx - the indices of the column found for each row (optional)

4607:    Level: intermediate

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

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

4615:    Concepts: matrices^getting row maximums

4617: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4618: @*/
4619: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4620: {

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

4631:   (*mat->ops->getrowmax)(mat,v,idx);
4632:   PetscObjectStateIncrease((PetscObject)v);
4633:   return(0);
4634: }

4636: /*@C
4637:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4638:         row of the matrix

4640:    Logically Collective on Mat and Vec

4642:    Input Parameters:
4643: .  mat - the matrix

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

4649:    Level: intermediate

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

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

4657:    Concepts: matrices^getting row maximums

4659: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4660: @*/
4661: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4662: {

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

4674:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4675:   PetscObjectStateIncrease((PetscObject)v);
4676:   return(0);
4677: }

4679: /*@
4680:    MatGetRowSum - Gets the sum of each row of the matrix

4682:    Logically or Neighborhood Collective on Mat and Vec

4684:    Input Parameters:
4685: .  mat - the matrix

4687:    Output Parameter:
4688: .  v - the vector for storing the sum of rows

4690:    Level: intermediate

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

4695:    Concepts: matrices^getting row sums

4697: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4698: @*/
4699: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4700: {
4701:   Vec            ones;

4708:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4709:   MatCheckPreallocated(mat,1);
4710:   MatCreateVecs(mat,&ones,NULL);
4711:   VecSet(ones,1.);
4712:   MatMult(mat,ones,v);
4713:   VecDestroy(&ones);
4714:   return(0);
4715: }

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

4720:    Collective on Mat

4722:    Input Parameter:
4723: +  mat - the matrix to transpose
4724: -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX

4726:    Output Parameters:
4727: .  B - the transpose

4729:    Notes:
4730:      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B

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

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

4736:    Level: intermediate

4738:    Concepts: matrices^transposing

4740: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4741: @*/
4742: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4743: {

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

4756:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4757:   (*mat->ops->transpose)(mat,reuse,B);
4758:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4759:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4760:   return(0);
4761: }

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

4767:    Collective on Mat

4769:    Input Parameter:
4770: +  A - the matrix to test
4771: -  B - the matrix to test against, this can equal the first parameter

4773:    Output Parameters:
4774: .  flg - the result

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

4781:    Level: intermediate

4783:    Concepts: matrices^transposing, matrix^symmetry

4785: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4786: @*/
4787: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4788: {
4789:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4795:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4796:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4797:   *flg = PETSC_FALSE;
4798:   if (f && g) {
4799:     if (f == g) {
4800:       (*f)(A,B,tol,flg);
4801:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4802:   } else {
4803:     MatType mattype;
4804:     if (!f) {
4805:       MatGetType(A,&mattype);
4806:     } else {
4807:       MatGetType(B,&mattype);
4808:     }
4809:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4810:   }
4811:   return(0);
4812: }

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

4817:    Collective on Mat

4819:    Input Parameter:
4820: +  mat - the matrix to transpose and complex conjugate
4821: -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose

4823:    Output Parameters:
4824: .  B - the Hermitian

4826:    Level: intermediate

4828:    Concepts: matrices^transposing, complex conjugatex

4830: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4831: @*/
4832: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4833: {

4837:   MatTranspose(mat,reuse,B);
4838: #if defined(PETSC_USE_COMPLEX)
4839:   MatConjugate(*B);
4840: #endif
4841:   return(0);
4842: }

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

4847:    Collective on Mat

4849:    Input Parameter:
4850: +  A - the matrix to test
4851: -  B - the matrix to test against, this can equal the first parameter

4853:    Output Parameters:
4854: .  flg - the result

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

4861:    Level: intermediate

4863:    Concepts: matrices^transposing, matrix^symmetry

4865: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4866: @*/
4867: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4868: {
4869:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

4875:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4876:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4877:   if (f && g) {
4878:     if (f==g) {
4879:       (*f)(A,B,tol,flg);
4880:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4881:   }
4882:   return(0);
4883: }

4885: /*@
4886:    MatPermute - Creates a new matrix with rows and columns permuted from the
4887:    original.

4889:    Collective on Mat

4891:    Input Parameters:
4892: +  mat - the matrix to permute
4893: .  row - row permutation, each processor supplies only the permutation for its rows
4894: -  col - column permutation, each processor supplies only the permutation for its columns

4896:    Output Parameters:
4897: .  B - the permuted matrix

4899:    Level: advanced

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

4905:    Concepts: matrices^permuting

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

4909: @*/
4910: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4911: {

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

4925:   (*mat->ops->permute)(mat,row,col,B);
4926:   PetscObjectStateIncrease((PetscObject)*B);
4927:   return(0);
4928: }

4930: /*@
4931:    MatEqual - Compares two matrices.

4933:    Collective on Mat

4935:    Input Parameters:
4936: +  A - the first matrix
4937: -  B - the second matrix

4939:    Output Parameter:
4940: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4942:    Level: intermediate

4944:    Concepts: matrices^equality between
4945: @*/
4946: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4947: {

4957:   MatCheckPreallocated(B,2);
4958:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4959:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4960:   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);
4961:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4962:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4963:   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);
4964:   MatCheckPreallocated(A,1);

4966:   (*A->ops->equal)(A,B,flg);
4967:   return(0);
4968: }

4970: /*@C
4971:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4972:    matrices that are stored as vectors.  Either of the two scaling
4973:    matrices can be NULL.

4975:    Collective on Mat

4977:    Input Parameters:
4978: +  mat - the matrix to be scaled
4979: .  l - the left scaling vector (or NULL)
4980: -  r - the right scaling vector (or NULL)

4982:    Notes:
4983:    MatDiagonalScale() computes A = LAR, where
4984:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4985:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4987:    Level: intermediate

4989:    Concepts: matrices^diagonal scaling
4990:    Concepts: diagonal scaling of matrices

4992: .seealso: MatScale(), MatShift(), MatDiagonalSet()
4993: @*/
4994: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4995: {

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

5008:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5009:   (*mat->ops->diagonalscale)(mat,l,r);
5010:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5011:   PetscObjectStateIncrease((PetscObject)mat);
5012: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5013:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5014:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5015:   }
5016: #endif
5017:   return(0);
5018: }

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

5023:     Logically Collective on Mat

5025:     Input Parameters:
5026: +   mat - the matrix to be scaled
5027: -   a  - the scaling value

5029:     Output Parameter:
5030: .   mat - the scaled matrix

5032:     Level: intermediate

5034:     Concepts: matrices^scaling all entries

5036: .seealso: MatDiagonalScale()
5037: @*/
5038: PetscErrorCode MatScale(Mat mat,PetscScalar a)
5039: {

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

5051:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5052:   if (a != (PetscScalar)1.0) {
5053:     (*mat->ops->scale)(mat,a);
5054:     PetscObjectStateIncrease((PetscObject)mat);
5055: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5056:     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5057:       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5058:     }
5059: #endif
5060:   }
5061:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5062:   return(0);
5063: }

5065: /*@
5066:    MatNorm - Calculates various norms of a matrix.

5068:    Collective on Mat

5070:    Input Parameters:
5071: +  mat - the matrix
5072: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

5074:    Output Parameters:
5075: .  nrm - the resulting norm

5077:    Level: intermediate

5079:    Concepts: matrices^norm
5080:    Concepts: norm^of matrix
5081: @*/
5082: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5083: {


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

5096:   (*mat->ops->norm)(mat,type,nrm);
5097:   return(0);
5098: }

5100: /*
5101:      This variable is used to prevent counting of MatAssemblyBegin() that
5102:    are called from within a MatAssemblyEnd().
5103: */
5104: static PetscInt MatAssemblyEnd_InUse = 0;
5105: /*@
5106:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5107:    be called after completing all calls to MatSetValues().

5109:    Collective on Mat

5111:    Input Parameters:
5112: +  mat - the matrix
5113: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5115:    Notes:
5116:    MatSetValues() generally caches the values.  The matrix is ready to
5117:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5118:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5119:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5120:    using the matrix.

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

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

5130:    Level: beginner

5132:    Concepts: matrices^assembling

5134: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5135: @*/
5136: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5137: {

5143:   MatCheckPreallocated(mat,1);
5144:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5145:   if (mat->assembled) {
5146:     mat->was_assembled = PETSC_TRUE;
5147:     mat->assembled     = PETSC_FALSE;
5148:   }
5149:   if (!MatAssemblyEnd_InUse) {
5150:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5151:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5152:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5153:   } else if (mat->ops->assemblybegin) {
5154:     (*mat->ops->assemblybegin)(mat,type);
5155:   }
5156:   return(0);
5157: }

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

5163:    Not Collective

5165:    Input Parameter:
5166: .  mat - the matrix

5168:    Output Parameter:
5169: .  assembled - PETSC_TRUE or PETSC_FALSE

5171:    Level: advanced

5173:    Concepts: matrices^assembled?

5175: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5176: @*/
5177: PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5178: {
5183:   *assembled = mat->assembled;
5184:   return(0);
5185: }

5187: /*@
5188:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5189:    be called after MatAssemblyBegin().

5191:    Collective on Mat

5193:    Input Parameters:
5194: +  mat - the matrix
5195: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

5197:    Options Database Keys:
5198: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5199: .  -mat_view ::ascii_info_detail - Prints more detailed info
5200: .  -mat_view - Prints matrix in ASCII format
5201: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5202: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5203: .  -display <name> - Sets display name (default is host)
5204: .  -draw_pause <sec> - Sets number of seconds to pause after display
5205: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 12 Using MATLAB with PETSc )
5206: .  -viewer_socket_machine <machine> - Machine to use for socket
5207: .  -viewer_socket_port <port> - Port number to use for socket
5208: -  -mat_view binary:filename[:append] - Save matrix to file in binary format

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

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

5221:    Level: beginner

5223: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5224: @*/
5225: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5226: {
5227:   PetscErrorCode  ierr;
5228:   static PetscInt inassm = 0;
5229:   PetscBool       flg    = PETSC_FALSE;


5235:   inassm++;
5236:   MatAssemblyEnd_InUse++;
5237:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5238:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5239:     if (mat->ops->assemblyend) {
5240:       (*mat->ops->assemblyend)(mat,type);
5241:     }
5242:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5243:   } else if (mat->ops->assemblyend) {
5244:     (*mat->ops->assemblyend)(mat,type);
5245:   }

5247:   /* Flush assembly is not a true assembly */
5248:   if (type != MAT_FLUSH_ASSEMBLY) {
5249:     mat->assembled = PETSC_TRUE; mat->num_ass++;
5250:   }
5251:   mat->insertmode = NOT_SET_VALUES;
5252:   MatAssemblyEnd_InUse--;
5253:   PetscObjectStateIncrease((PetscObject)mat);
5254:   if (!mat->symmetric_eternal) {
5255:     mat->symmetric_set              = PETSC_FALSE;
5256:     mat->hermitian_set              = PETSC_FALSE;
5257:     mat->structurally_symmetric_set = PETSC_FALSE;
5258:   }
5259: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5260:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5261:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5262:   }
5263: #endif
5264:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5265:     MatViewFromOptions(mat,NULL,"-mat_view");

5267:     if (mat->checksymmetryonassembly) {
5268:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5269:       if (flg) {
5270:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5271:       } else {
5272:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5273:       }
5274:     }
5275:     if (mat->nullsp && mat->checknullspaceonassembly) {
5276:       MatNullSpaceTest(mat->nullsp,mat,NULL);
5277:     }
5278:   }
5279:   inassm--;
5280:   return(0);
5281: }

5283: /*@
5284:    MatSetOption - Sets a parameter option for a matrix. Some options
5285:    may be specific to certain storage formats.  Some options
5286:    determine how values will be inserted (or added). Sorted,
5287:    row-oriented input will generally assemble the fastest. The default
5288:    is row-oriented.

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

5292:    Input Parameters:
5293: +  mat - the matrix
5294: .  option - the option, one of those listed below (and possibly others),
5295: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5297:   Options Describing Matrix Structure:
5298: +    MAT_SPD - symmetric positive definite
5299: .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5300: .    MAT_HERMITIAN - transpose is the complex conjugation
5301: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5302: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5303:                             you set to be kept with all future use of the matrix
5304:                             including after MatAssemblyBegin/End() which could
5305:                             potentially change the symmetry structure, i.e. you
5306:                             KNOW the matrix will ALWAYS have the property you set.


5309:    Options For Use with MatSetValues():
5310:    Insert a logically dense subblock, which can be
5311: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

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

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

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

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

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

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

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

5365:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5366:    searches during matrix assembly. When this flag is set, the hash table
5367:    is created during the first Matrix Assembly. This hash table is
5368:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5369:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5370:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5371:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5390:    Level: intermediate

5392:    Concepts: matrices^setting options

5394: .seealso:  MatOption, Mat

5396: @*/
5397: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5398: {

5404:   if (op > 0) {
5407:   }

5409:   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);
5410:   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()");

5412:   switch (op) {
5413:   case MAT_NO_OFF_PROC_ENTRIES:
5414:     mat->nooffprocentries = flg;
5415:     return(0);
5416:     break;
5417:   case MAT_SUBSET_OFF_PROC_ENTRIES:
5418:     mat->subsetoffprocentries = flg;
5419:     return(0);
5420:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5421:     mat->nooffproczerorows = flg;
5422:     return(0);
5423:     break;
5424:   case MAT_SPD:
5425:     mat->spd_set = PETSC_TRUE;
5426:     mat->spd     = flg;
5427:     if (flg) {
5428:       mat->symmetric                  = PETSC_TRUE;
5429:       mat->structurally_symmetric     = PETSC_TRUE;
5430:       mat->symmetric_set              = PETSC_TRUE;
5431:       mat->structurally_symmetric_set = PETSC_TRUE;
5432:     }
5433:     break;
5434:   case MAT_SYMMETRIC:
5435:     mat->symmetric = flg;
5436:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5437:     mat->symmetric_set              = PETSC_TRUE;
5438:     mat->structurally_symmetric_set = flg;
5439: #if !defined(PETSC_USE_COMPLEX)
5440:     mat->hermitian     = flg;
5441:     mat->hermitian_set = PETSC_TRUE;
5442: #endif
5443:     break;
5444:   case MAT_HERMITIAN:
5445:     mat->hermitian = flg;
5446:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5447:     mat->hermitian_set              = PETSC_TRUE;
5448:     mat->structurally_symmetric_set = flg;
5449: #if !defined(PETSC_USE_COMPLEX)
5450:     mat->symmetric     = flg;
5451:     mat->symmetric_set = PETSC_TRUE;
5452: #endif
5453:     break;
5454:   case MAT_STRUCTURALLY_SYMMETRIC:
5455:     mat->structurally_symmetric     = flg;
5456:     mat->structurally_symmetric_set = PETSC_TRUE;
5457:     break;
5458:   case MAT_SYMMETRY_ETERNAL:
5459:     mat->symmetric_eternal = flg;
5460:     break;
5461:   case MAT_STRUCTURE_ONLY:
5462:     mat->structure_only = flg;
5463:     break;
5464:   default:
5465:     break;
5466:   }
5467:   if (mat->ops->setoption) {
5468:     (*mat->ops->setoption)(mat,op,flg);
5469:   }
5470:   return(0);
5471: }

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

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

5478:    Input Parameters:
5479: +  mat - the matrix
5480: -  option - the option, this only responds to certain options, check the code for which ones

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

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

5488:    Level: intermediate

5490:    Concepts: matrices^setting options

5492: .seealso:  MatOption, MatSetOption()

5494: @*/
5495: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5496: {

5501:   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);
5502:   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()");

5504:   switch (op) {
5505:   case MAT_NO_OFF_PROC_ENTRIES:
5506:     *flg = mat->nooffprocentries;
5507:     break;
5508:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5509:     *flg = mat->nooffproczerorows;
5510:     break;
5511:   case MAT_SYMMETRIC:
5512:     *flg = mat->symmetric;
5513:     break;
5514:   case MAT_HERMITIAN:
5515:     *flg = mat->hermitian;
5516:     break;
5517:   case MAT_STRUCTURALLY_SYMMETRIC:
5518:     *flg = mat->structurally_symmetric;
5519:     break;
5520:   case MAT_SYMMETRY_ETERNAL:
5521:     *flg = mat->symmetric_eternal;
5522:     break;
5523:   case MAT_SPD:
5524:     *flg = mat->spd;
5525:     break;
5526:   default:
5527:     break;
5528:   }
5529:   return(0);
5530: }

5532: /*@
5533:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5534:    this routine retains the old nonzero structure.

5536:    Logically Collective on Mat

5538:    Input Parameters:
5539: .  mat - the matrix

5541:    Level: intermediate

5543:    Notes:
5544:     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.
5545:    See the Performance chapter of the users manual for information on preallocating matrices.

5547:    Concepts: matrices^zeroing

5549: .seealso: MatZeroRows()
5550: @*/
5551: PetscErrorCode MatZeroEntries(Mat mat)
5552: {

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

5563:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5564:   (*mat->ops->zeroentries)(mat);
5565:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5566:   PetscObjectStateIncrease((PetscObject)mat);
5567: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5568:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5569:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5570:   }
5571: #endif
5572:   return(0);
5573: }

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

5579:    Collective on Mat

5581:    Input Parameters:
5582: +  mat - the matrix
5583: .  numRows - the number of rows to remove
5584: .  rows - the global row indices
5585: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5586: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5587: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5606:    Level: intermediate

5608:    Concepts: matrices^zeroing rows

5610: .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5611:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5612: @*/
5613: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5614: {

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

5626:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5627:   MatViewFromOptions(mat,NULL,"-mat_view");
5628:   PetscObjectStateIncrease((PetscObject)mat);
5629: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5630:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5631:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5632:   }
5633: #endif
5634:   return(0);
5635: }

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

5641:    Collective on Mat

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

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

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

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

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

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

5667:    Level: intermediate

5669:    Concepts: matrices^zeroing rows

5671: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5672:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5673: @*/
5674: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5675: {
5677:   PetscInt       numRows;
5678:   const PetscInt *rows;

5685:   ISGetLocalSize(is,&numRows);
5686:   ISGetIndices(is,&rows);
5687:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5688:   ISRestoreIndices(is,&rows);
5689:   return(0);
5690: }

5692: /*@C
5693:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5694:    of a set of rows of a matrix.

5696:    Collective on Mat

5698:    Input Parameters:
5699: +  mat - the matrix
5700: .  numRows - the number of rows to remove
5701: .  rows - the global row indices
5702: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5703: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5704: -  b - optional vector of right hand side, that will be adjusted by provided solution

5706:    Notes:
5707:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5708:    but does not release memory.  For the dense and block diagonal
5709:    formats this does not alter the nonzero structure.

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

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

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

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

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

5730:    Level: intermediate

5732:    Concepts: matrices^zeroing rows

5734: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5735:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5736: @*/
5737: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5738: {

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

5750:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5751:   MatViewFromOptions(mat,NULL,"-mat_view");
5752:   PetscObjectStateIncrease((PetscObject)mat);
5753: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
5754:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5755:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5756:   }
5757: #endif
5758:   return(0);
5759: }

5761: /*@C
5762:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5763:    of a set of rows of a matrix.

5765:    Collective on Mat

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

5774:    Notes:
5775:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5776:    but does not release memory.  For the dense and block diagonal
5777:    formats this does not alter the nonzero structure.

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

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

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

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

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

5798:    Level: intermediate

5800:    Concepts: matrices^zeroing rows

5802: .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5803:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5804: @*/
5805: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5806: {
5807:   PetscInt       numRows;
5808:   const PetscInt *rows;

5815:   ISGetLocalSize(is,&numRows);
5816:   ISGetIndices(is,&rows);
5817:   MatZeroRows(mat,numRows,rows,diag,x,b);
5818:   ISRestoreIndices(is,&rows);
5819:   return(0);
5820: }

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

5826:    Collective on Mat

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

5836:    Notes:
5837:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5838:    but does not release memory.  For the dense and block diagonal
5839:    formats this does not alter the nonzero structure.

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

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

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

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

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

5859:    In Fortran idxm and idxn should be declared as
5860: $     MatStencil idxm(4,m)
5861:    and the values inserted using
5862: $    idxm(MatStencil_i,1) = i
5863: $    idxm(MatStencil_j,1) = j
5864: $    idxm(MatStencil_k,1) = k
5865: $    idxm(MatStencil_c,1) = c
5866:    etc

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

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

5876:    Level: intermediate

5878:    Concepts: matrices^zeroing rows

5880: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5881:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5882: @*/
5883: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5884: {
5885:   PetscInt       dim     = mat->stencil.dim;
5886:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5887:   PetscInt       *dims   = mat->stencil.dims+1;
5888:   PetscInt       *starts = mat->stencil.starts;
5889:   PetscInt       *dxm    = (PetscInt*) rows;
5890:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5898:   PetscMalloc1(numRows, &jdxm);
5899:   for (i = 0; i < numRows; ++i) {
5900:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5901:     for (j = 0; j < 3-sdim; ++j) dxm++;
5902:     /* Local index in X dir */
5903:     tmp = *dxm++ - starts[0];
5904:     /* Loop over remaining dimensions */
5905:     for (j = 0; j < dim-1; ++j) {
5906:       /* If nonlocal, set index to be negative */
5907:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5908:       /* Update local index */
5909:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5910:     }
5911:     /* Skip component slot if necessary */
5912:     if (mat->stencil.noc) dxm++;
5913:     /* Local row number */
5914:     if (tmp >= 0) {
5915:       jdxm[numNewRows++] = tmp;
5916:     }
5917:   }
5918:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5919:   PetscFree(jdxm);
5920:   return(0);
5921: }

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

5927:    Collective on Mat

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

5937:    Notes:
5938:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5939:    but does not release memory.  For the dense and block diagonal
5940:    formats this does not alter the nonzero structure.

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

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

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

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

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

5960:    In Fortran idxm and idxn should be declared as
5961: $     MatStencil idxm(4,m)
5962:    and the values inserted using
5963: $    idxm(MatStencil_i,1) = i
5964: $    idxm(MatStencil_j,1) = j
5965: $    idxm(MatStencil_k,1) = k
5966: $    idxm(MatStencil_c,1) = c
5967:    etc

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

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

5977:    Level: intermediate

5979:    Concepts: matrices^zeroing rows

5981: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5982:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
5983: @*/
5984: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5985: {
5986:   PetscInt       dim     = mat->stencil.dim;
5987:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5988:   PetscInt       *dims   = mat->stencil.dims+1;
5989:   PetscInt       *starts = mat->stencil.starts;
5990:   PetscInt       *dxm    = (PetscInt*) rows;
5991:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;


5999:   PetscMalloc1(numRows, &jdxm);
6000:   for (i = 0; i < numRows; ++i) {
6001:     /* Skip unused dimensions (they are ordered k, j, i, c) */
6002:     for (j = 0; j < 3-sdim; ++j) dxm++;
6003:     /* Local index in X dir */
6004:     tmp = *dxm++ - starts[0];
6005:     /* Loop over remaining dimensions */
6006:     for (j = 0; j < dim-1; ++j) {
6007:       /* If nonlocal, set index to be negative */
6008:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6009:       /* Update local index */
6010:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6011:     }
6012:     /* Skip component slot if necessary */
6013:     if (mat->stencil.noc) dxm++;
6014:     /* Local row number */
6015:     if (tmp >= 0) {
6016:       jdxm[numNewRows++] = tmp;
6017:     }
6018:   }
6019:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
6020:   PetscFree(jdxm);
6021:   return(0);
6022: }

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

6028:    Collective on Mat

6030:    Input Parameters:
6031: +  mat - the matrix
6032: .  numRows - the number of rows to remove
6033: .  rows - the global row indices
6034: .  diag - value put in all diagonals of eliminated rows
6035: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6036: -  b - optional vector of right hand side, that will be adjusted by provided solution

6038:    Notes:
6039:    Before calling MatZeroRowsLocal(), the user must first set the
6040:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6042:    For the AIJ matrix formats this removes the old nonzero structure,
6043:    but does not release memory.  For the dense and block diagonal
6044:    formats this does not alter the nonzero structure.

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

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

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

6057:    Level: intermediate

6059:    Concepts: matrices^zeroing

6061: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6062:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6063: @*/
6064: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6065: {

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

6076:   if (mat->ops->zerorowslocal) {
6077:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6078:   } else {
6079:     IS             is, newis;
6080:     const PetscInt *newRows;

6082:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6083:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6084:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6085:     ISGetIndices(newis,&newRows);
6086:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6087:     ISRestoreIndices(newis,&newRows);
6088:     ISDestroy(&newis);
6089:     ISDestroy(&is);
6090:   }
6091:   PetscObjectStateIncrease((PetscObject)mat);
6092: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6093:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6094:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6095:   }
6096: #endif
6097:   return(0);
6098: }

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

6104:    Collective on Mat

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

6113:    Notes:
6114:    Before calling MatZeroRowsLocalIS(), the user must first set the
6115:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

6117:    For the AIJ matrix formats this removes the old nonzero structure,
6118:    but does not release memory.  For the dense and block diagonal
6119:    formats this does not alter the nonzero structure.

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

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

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

6132:    Level: intermediate

6134:    Concepts: matrices^zeroing

6136: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6137:           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6138: @*/
6139: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6140: {
6142:   PetscInt       numRows;
6143:   const PetscInt *rows;

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

6153:   ISGetLocalSize(is,&numRows);
6154:   ISGetIndices(is,&rows);
6155:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6156:   ISRestoreIndices(is,&rows);
6157:   return(0);
6158: }

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

6164:    Collective on Mat

6166:    Input Parameters:
6167: +  mat - the matrix
6168: .  numRows - the number of rows to remove
6169: .  rows - the global row indices
6170: .  diag - value put in all diagonals of eliminated rows
6171: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6172: -  b - optional vector of right hand side, that will be adjusted by provided solution

6174:    Notes:
6175:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6176:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6182:    Level: intermediate

6184:    Concepts: matrices^zeroing

6186: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6187:           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6188: @*/
6189: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6190: {
6192:   IS             is, newis;
6193:   const PetscInt *newRows;

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

6203:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6204:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6205:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6206:   ISGetIndices(newis,&newRows);
6207:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6208:   ISRestoreIndices(newis,&newRows);
6209:   ISDestroy(&newis);
6210:   ISDestroy(&is);
6211:   PetscObjectStateIncrease((PetscObject)mat);
6212: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
6213:   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6214:     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6215:   }
6216: #endif
6217:   return(0);
6218: }

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

6224:    Collective on Mat

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

6233:    Notes:
6234:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6235:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

6241:    Level: intermediate

6243:    Concepts: matrices^zeroing

6245: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6246:           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6247: @*/
6248: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6249: {
6251:   PetscInt       numRows;
6252:   const PetscInt *rows;

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

6262:   ISGetLocalSize(is,&numRows);
6263:   ISGetIndices(is,&rows);
6264:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6265:   ISRestoreIndices(is,&rows);
6266:   return(0);
6267: }

6269: /*@C
6270:    MatGetSize - Returns the numbers of rows and columns in a matrix.

6272:    Not Collective

6274:    Input Parameter:
6275: .  mat - the matrix

6277:    Output Parameters:
6278: +  m - the number of global rows
6279: -  n - the number of global columns

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

6283:    Level: beginner

6285:    Concepts: matrices^size

6287: .seealso: MatGetLocalSize()
6288: @*/
6289: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6290: {
6293:   if (m) *m = mat->rmap->N;
6294:   if (n) *n = mat->cmap->N;
6295:   return(0);
6296: }

6298: /*@C
6299:    MatGetLocalSize - Returns the number of rows and columns in a matrix
6300:    stored locally.  This information may be implementation dependent, so
6301:    use with care.

6303:    Not Collective

6305:    Input Parameters:
6306: .  mat - the matrix

6308:    Output Parameters:
6309: +  m - the number of local rows
6310: -  n - the number of local columns

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

6314:    Level: beginner

6316:    Concepts: matrices^local size

6318: .seealso: MatGetSize()
6319: @*/
6320: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6321: {
6326:   if (m) *m = mat->rmap->n;
6327:   if (n) *n = mat->cmap->n;
6328:   return(0);
6329: }

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

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

6337:    Input Parameters:
6338: .  mat - the matrix

6340:    Output Parameters:
6341: +  m - the global index of the first local column
6342: -  n - one more than the global index of the last local column

6344:    Notes:
6345:     both output parameters can be NULL on input.

6347:    Level: developer

6349:    Concepts: matrices^column ownership

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

6353: @*/
6354: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6355: {
6361:   MatCheckPreallocated(mat,1);
6362:   if (m) *m = mat->cmap->rstart;
6363:   if (n) *n = mat->cmap->rend;
6364:   return(0);
6365: }

6367: /*@C
6368:    MatGetOwnershipRange - Returns the range of matrix rows owned by
6369:    this processor, assuming that the matrix is laid out with the first
6370:    n1 rows on the first processor, the next n2 rows on the second, etc.
6371:    For certain parallel layouts this range may not be well defined.

6373:    Not Collective

6375:    Input Parameters:
6376: .  mat - the matrix

6378:    Output Parameters:
6379: +  m - the global index of the first local row
6380: -  n - one more than the global index of the last local row

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

6387:    Level: beginner

6389:    Concepts: matrices^row ownership

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

6393: @*/
6394: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6395: {
6401:   MatCheckPreallocated(mat,1);
6402:   if (m) *m = mat->rmap->rstart;
6403:   if (n) *n = mat->rmap->rend;
6404:   return(0);
6405: }

6407: /*@C
6408:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6409:    each process

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

6413:    Input Parameters:
6414: .  mat - the matrix

6416:    Output Parameters:
6417: .  ranges - start of each processors portion plus one more than the total length at the end

6419:    Level: beginner

6421:    Concepts: matrices^row ownership

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

6425: @*/
6426: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6427: {

6433:   MatCheckPreallocated(mat,1);
6434:   PetscLayoutGetRanges(mat->rmap,ranges);
6435:   return(0);
6436: }

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

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

6444:    Input Parameters:
6445: .  mat - the matrix

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

6450:    Level: beginner

6452:    Concepts: matrices^column ownership

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

6456: @*/
6457: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6458: {

6464:   MatCheckPreallocated(mat,1);
6465:   PetscLayoutGetRanges(mat->cmap,ranges);
6466:   return(0);
6467: }

6469: /*@C
6470:    MatGetOwnershipIS - Get row and column ownership as index sets

6472:    Not Collective

6474:    Input Arguments:
6475: .  A - matrix of type Elemental

6477:    Output Arguments:
6478: +  rows - rows in which this process owns elements
6479: .  cols - columns in which this process owns elements

6481:    Level: intermediate

6483: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6484: @*/
6485: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6486: {
6487:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

6490:   MatCheckPreallocated(A,1);
6491:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6492:   if (f) {
6493:     (*f)(A,rows,cols);
6494:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6495:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6496:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6497:   }
6498:   return(0);
6499: }

6501: /*@C
6502:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6503:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6504:    to complete the factorization.

6506:    Collective on Mat

6508:    Input Parameters:
6509: +  mat - the matrix
6510: .  row - row permutation
6511: .  column - column permutation
6512: -  info - structure containing
6513: $      levels - number of levels of fill.
6514: $      expected fill - as ratio of original fill.
6515: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6516:                 missing diagonal entries)

6518:    Output Parameters:
6519: .  fact - new matrix that has been symbolically factored

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

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

6528:    Level: developer

6530:   Concepts: matrices^symbolic LU factorization
6531:   Concepts: matrices^factorization
6532:   Concepts: LU^symbolic factorization

6534: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6535:           MatGetOrdering(), MatFactorInfo

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

6540: @*/
6541: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6542: {

6552:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6553:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6554:   if (!(fact)->ops->ilufactorsymbolic) {
6555:     MatSolverType spackage;
6556:     MatFactorGetSolverType(fact,&spackage);
6557:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6558:   }
6559:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6560:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6561:   MatCheckPreallocated(mat,2);

6563:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6564:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6565:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6566:   return(0);
6567: }

6569: /*@C
6570:    MatICCFactorSymbolic - Performs symbolic incomplete
6571:    Cholesky factorization for a symmetric matrix.  Use
6572:    MatCholeskyFactorNumeric() to complete the factorization.

6574:    Collective on Mat

6576:    Input Parameters:
6577: +  mat - the matrix
6578: .  perm - row and column permutation
6579: -  info - structure containing
6580: $      levels - number of levels of fill.
6581: $      expected fill - as ratio of original fill.

6583:    Output Parameter:
6584: .  fact - the factored matrix

6586:    Notes:
6587:    Most users should employ the KSP interface for linear solvers
6588:    instead of working directly with matrix algebra routines such as this.
6589:    See, e.g., KSPCreate().

6591:    Level: developer

6593:   Concepts: matrices^symbolic incomplete Cholesky factorization
6594:   Concepts: matrices^factorization
6595:   Concepts: Cholsky^symbolic factorization

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

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

6602: @*/
6603: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6604: {

6613:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6614:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6615:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6616:   if (!(fact)->ops->iccfactorsymbolic) {
6617:     MatSolverType spackage;
6618:     MatFactorGetSolverType(fact,&spackage);
6619:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6620:   }
6621:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6622:   MatCheckPreallocated(mat,2);

6624:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6625:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6626:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6627:   return(0);
6628: }

6630: /*@C
6631:    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6632:    points to an array of valid matrices, they may be reused to store the new
6633:    submatrices.

6635:    Collective on Mat

6637:    Input Parameters:
6638: +  mat - the matrix
6639: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6640: .  irow, icol - index sets of rows and columns to extract
6641: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6643:    Output Parameter:
6644: .  submat - the array of submatrices

6646:    Notes:
6647:    MatCreateSubMatrices() can extract ONLY sequential submatrices
6648:    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6649:    to extract a parallel submatrix.

6651:    Some matrix types place restrictions on the row and column
6652:    indices, such as that they be sorted or that they be equal to each other.

6654:    The index sets may not have duplicate entries.

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

6660:    When finished using the submatrices, the user should destroy
6661:    them with MatDestroySubMatrices().

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

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

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

6674:    Fortran Note:
6675:    The Fortran interface is slightly different from that given below; it
6676:    requires one to pass in  as submat a Mat (integer) array of size at least n+1.

6678:    Level: advanced

6680:    Concepts: matrices^accessing submatrices
6681:    Concepts: submatrices

6683: .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6684: @*/
6685: PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6686: {
6688:   PetscInt       i;
6689:   PetscBool      eq;

6694:   if (n) {
6699:   }
6701:   if (n && scall == MAT_REUSE_MATRIX) {
6704:   }
6705:   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6706:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6707:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6708:   MatCheckPreallocated(mat,1);

6710:   PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6711:   (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);
6712:   PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6713:   for (i=0; i<n; i++) {
6714:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6715:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6716:       ISEqual(irow[i],icol[i],&eq);
6717:       if (eq) {
6718:         if (mat->symmetric) {
6719:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6720:         } else if (mat->hermitian) {
6721:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6722:         } else if (mat->structurally_symmetric) {
6723:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6724:         }
6725:       }
6726:     }
6727:   }
6728:   return(0);
6729: }

6731: /*@C
6732:    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).

6734:    Collective on Mat

6736:    Input Parameters:
6737: +  mat - the matrix
6738: .  n   - the number of submatrixes to be extracted
6739: .  irow, icol - index sets of rows and columns to extract
6740: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6742:    Output Parameter:
6743: .  submat - the array of submatrices

6745:    Level: advanced

6747:    Concepts: matrices^accessing submatrices
6748:    Concepts: submatrices

6750: .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6751: @*/
6752: PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6753: {
6755:   PetscInt       i;
6756:   PetscBool      eq;

6761:   if (n) {
6766:   }
6768:   if (n && scall == MAT_REUSE_MATRIX) {
6771:   }
6772:   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6773:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6774:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6775:   MatCheckPreallocated(mat,1);

6777:   PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6778:   (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6779:   PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6780:   for (i=0; i<n; i++) {
6781:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6782:       ISEqual(irow[i],icol[i],&eq);
6783:       if (eq) {
6784:         if (mat->symmetric) {
6785:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6786:         } else if (mat->hermitian) {
6787:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6788:         } else if (mat->structurally_symmetric) {
6789:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6790:         }
6791:       }
6792:     }
6793:   }
6794:   return(0);
6795: }

6797: /*@C
6798:    MatDestroyMatrices - Destroys an array of matrices.

6800:    Collective on Mat

6802:    Input Parameters:
6803: +  n - the number of local matrices
6804: -  mat - the matrices (note that this is a pointer to the array of matrices)

6806:    Level: advanced

6808:     Notes:
6809:     Frees not only the matrices, but also the array that contains the matrices
6810:            In Fortran will not free the array.

6812: .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6813: @*/
6814: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6815: {
6817:   PetscInt       i;

6820:   if (!*mat) return(0);
6821:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);

6824:   for (i=0; i<n; i++) {
6825:     MatDestroy(&(*mat)[i]);
6826:   }

6828:   /* memory is allocated even if n = 0 */
6829:   PetscFree(*mat);
6830:   return(0);
6831: }

6833: /*@C
6834:    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().

6836:    Collective on Mat

6838:    Input Parameters:
6839: +  n - the number of local matrices
6840: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6841:                        sequence of MatCreateSubMatrices())

6843:    Level: advanced

6845:     Notes:
6846:     Frees not only the matrices, but also the array that contains the matrices
6847:            In Fortran will not free the array.

6849: .seealso: MatCreateSubMatrices()
6850: @*/
6851: PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6852: {
6854:   Mat            mat0;

6857:   if (!*mat) return(0);
6858:   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6859:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);

6862:   mat0 = (*mat)[0];
6863:   if (mat0 && mat0->ops->destroysubmatrices) {
6864:     (mat0->ops->destroysubmatrices)(n,mat);
6865:   } else {
6866:     MatDestroyMatrices(n,mat);
6867:   }
6868:   return(0);
6869: }

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

6874:    Collective on Mat

6876:    Input Parameters:
6877: .  mat - the matrix

6879:    Output Parameter:
6880: .  matstruct - the sequential matrix with the nonzero structure of mat

6882:   Level: intermediate

6884: .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6885: @*/
6886: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6887: {


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

6898:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6899:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6900:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6901:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6902:   return(0);
6903: }

6905: /*@C
6906:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6908:    Collective on Mat

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

6914:    Level: advanced

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

6919: .seealso: MatGetSeqNonzeroStructure()
6920: @*/
6921: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6922: {

6927:   MatDestroy(mat);
6928:   return(0);
6929: }

6931: /*@
6932:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6933:    replaces the index sets by larger ones that represent submatrices with
6934:    additional overlap.

6936:    Collective on Mat

6938:    Input Parameters:
6939: +  mat - the matrix
6940: .  n   - the number of index sets
6941: .  is  - the array of index sets (these index sets will changed during the call)
6942: -  ov  - the additional overlap requested

6944:    Options Database:
6945: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

6947:    Level: developer

6949:    Concepts: overlap
6950:    Concepts: ASM^computing overlap

6952: .seealso: MatCreateSubMatrices()
6953: @*/
6954: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6955: {

6961:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6962:   if (n) {
6965:   }
6966:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6967:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6968:   MatCheckPreallocated(mat,1);

6970:   if (!ov) return(0);
6971:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6972:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6973:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6974:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6975:   return(0);
6976: }


6979: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);

6981: /*@
6982:    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6983:    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6984:    additional overlap.

6986:    Collective on Mat

6988:    Input Parameters:
6989: +  mat - the matrix
6990: .  n   - the number of index sets
6991: .  is  - the array of index sets (these index sets will changed during the call)
6992: -  ov  - the additional overlap requested

6994:    Options Database:
6995: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

6997:    Level: developer

6999:    Concepts: overlap
7000:    Concepts: ASM^computing overlap

7002: .seealso: MatCreateSubMatrices()
7003: @*/
7004: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7005: {
7006:   PetscInt       i;

7012:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7013:   if (n) {
7016:   }
7017:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7018:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7019:   MatCheckPreallocated(mat,1);
7020:   if (!ov) return(0);
7021:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
7022:   for(i=0; i<n; i++){
7023:          MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
7024:   }
7025:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
7026:   return(0);
7027: }




7032: /*@
7033:    MatGetBlockSize - Returns the matrix block size.

7035:    Not Collective

7037:    Input Parameter:
7038: .  mat - the matrix

7040:    Output Parameter:
7041: .  bs - block size

7043:    Notes:
7044:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

7046:    If the block size has not been set yet this routine returns 1.

7048:    Level: intermediate

7050:    Concepts: matrices^block size

7052: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7053: @*/
7054: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7055: {
7059:   *bs = PetscAbs(mat->rmap->bs);
7060:   return(0);
7061: }

7063: /*@
7064:    MatGetBlockSizes - Returns the matrix block row and column sizes.

7066:    Not Collective

7068:    Input Parameter:
7069: .  mat - the matrix

7071:    Output Parameter:
7072: .  rbs - row block size
7073: .  cbs - column block size

7075:    Notes:
7076:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7077:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

7079:    If a block size has not been set yet this routine returns 1.

7081:    Level: intermediate

7083:    Concepts: matrices^block size

7085: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7086: @*/
7087: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7088: {
7093:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7094:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7095:   return(0);
7096: }

7098: /*@
7099:    MatSetBlockSize - Sets the matrix block size.

7101:    Logically Collective on Mat

7103:    Input Parameters:
7104: +  mat - the matrix
7105: -  bs - block size

7107:    Notes:
7108:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7109:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.

7111:     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7112:     is compatible with the matrix local sizes.

7114:    Level: intermediate

7116:    Concepts: matrices^block size

7118: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7119: @*/
7120: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7121: {

7127:   MatSetBlockSizes(mat,bs,bs);
7128:   return(0);
7129: }

7131: /*@
7132:    MatSetBlockSizes - Sets the matrix block row and column sizes.

7134:    Logically Collective on Mat

7136:    Input Parameters:
7137: +  mat - the matrix
7138: -  rbs - row block size
7139: -  cbs - column block size

7141:    Notes:
7142:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7143:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7144:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

7146:     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7147:     are compatible with the matrix local sizes.

7149:     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().

7151:    Level: intermediate

7153:    Concepts: matrices^block size

7155: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7156: @*/
7157: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7158: {

7165:   if (mat->ops->setblocksizes) {
7166:     (*mat->ops->setblocksizes)(mat,rbs,cbs);
7167:   }
7168:   if (mat->rmap->refcnt) {
7169:     ISLocalToGlobalMapping l2g = NULL;
7170:     PetscLayout            nmap = NULL;

7172:     PetscLayoutDuplicate(mat->rmap,&nmap);
7173:     if (mat->rmap->mapping) {
7174:       ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);
7175:     }
7176:     PetscLayoutDestroy(&mat->rmap);
7177:     mat->rmap = nmap;
7178:     mat->rmap->mapping = l2g;
7179:   }
7180:   if (mat->cmap->refcnt) {
7181:     ISLocalToGlobalMapping l2g = NULL;
7182:     PetscLayout            nmap = NULL;

7184:     PetscLayoutDuplicate(mat->cmap,&nmap);
7185:     if (mat->cmap->mapping) {
7186:       ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);
7187:     }
7188:     PetscLayoutDestroy(&mat->cmap);
7189:     mat->cmap = nmap;
7190:     mat->cmap->mapping = l2g;
7191:   }
7192:   PetscLayoutSetBlockSize(mat->rmap,rbs);
7193:   PetscLayoutSetBlockSize(mat->cmap,cbs);
7194:   return(0);
7195: }

7197: /*@
7198:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

7200:    Logically Collective on Mat

7202:    Input Parameters:
7203: +  mat - the matrix
7204: .  fromRow - matrix from which to copy row block size
7205: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

7207:    Level: developer

7209:    Concepts: matrices^block size

7211: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7212: @*/
7213: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7214: {

7221:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7222:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7223:   return(0);
7224: }

7226: /*@
7227:    MatResidual - Default routine to calculate the residual.

7229:    Collective on Mat and Vec

7231:    Input Parameters:
7232: +  mat - the matrix
7233: .  b   - the right-hand-side
7234: -  x   - the approximate solution

7236:    Output Parameter:
7237: .  r - location to store the residual

7239:    Level: developer

7241: .keywords: MG, default, multigrid, residual

7243: .seealso: PCMGSetResidual()
7244: @*/
7245: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7246: {

7255:   MatCheckPreallocated(mat,1);
7256:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7257:   if (!mat->ops->residual) {
7258:     MatMult(mat,x,r);
7259:     VecAYPX(r,-1.0,b);
7260:   } else {
7261:     (*mat->ops->residual)(mat,b,x,r);
7262:   }
7263:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7264:   return(0);
7265: }

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

7270:    Collective on Mat

7272:     Input Parameters:
7273: +   mat - the matrix
7274: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7275: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7276: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7277:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7278:                  always used.

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

7287:     Level: developer

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

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

7294:     Fortran Notes:
7295:     In Fortran use
7296: $
7297: $      PetscInt ia(1), ja(1)
7298: $      PetscOffset iia, jja
7299: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7300: $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)

7302:      or
7303: $
7304: $    PetscInt, pointer :: ia(:),ja(:)
7305: $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7306: $    ! Access the ith and jth entries via ia(i) and ja(j)

7308: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7309: @*/
7310: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7311: {

7321:   MatCheckPreallocated(mat,1);
7322:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7323:   else {
7324:     *done = PETSC_TRUE;
7325:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7326:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7327:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7328:   }
7329:   return(0);
7330: }

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

7335:     Collective on Mat

7337:     Input Parameters:
7338: +   mat - the matrix
7339: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7340: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7341:                 symmetrized
7342: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7343:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7344:                  always used.
7345: .   n - number of columns in the (possibly compressed) matrix
7346: .   ia - the column pointers
7347: -   ja - the row indices

7349:     Output Parameters:
7350: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

7352:     Note:
7353:     This routine zeros out n, ia, and ja. This is to prevent accidental
7354:     us of the array after it has been restored. If you pass NULL, it will
7355:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

7357:     Level: developer

7359: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7360: @*/
7361: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7362: {

7372:   MatCheckPreallocated(mat,1);
7373:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7374:   else {
7375:     *done = PETSC_TRUE;
7376:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7377:   }
7378:   return(0);
7379: }

7381: /*@C
7382:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7383:     MatGetRowIJ().

7385:     Collective on Mat

7387:     Input Parameters:
7388: +   mat - the matrix
7389: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7390: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7391:                 symmetrized
7392: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7393:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7394:                  always used.
7395: .   n - size of (possibly compressed) matrix
7396: .   ia - the row pointers
7397: -   ja - the column indices

7399:     Output Parameters:
7400: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7402:     Note:
7403:     This routine zeros out n, ia, and ja. This is to prevent accidental
7404:     us of the array after it has been restored. If you pass NULL, it will
7405:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

7407:     Level: developer

7409: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7410: @*/
7411: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7412: {

7421:   MatCheckPreallocated(mat,1);

7423:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7424:   else {
7425:     *done = PETSC_TRUE;
7426:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7427:     if (n)  *n = 0;
7428:     if (ia) *ia = NULL;
7429:     if (ja) *ja = NULL;
7430:   }
7431:   return(0);
7432: }

7434: /*@C
7435:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7436:     MatGetColumnIJ().

7438:     Collective on Mat

7440:     Input Parameters:
7441: +   mat - the matrix
7442: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7443: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7444:                 symmetrized
7445: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7446:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7447:                  always used.

7449:     Output Parameters:
7450: +   n - size of (possibly compressed) matrix
7451: .   ia - the column pointers
7452: .   ja - the row indices
7453: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

7455:     Level: developer

7457: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7458: @*/
7459: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7460: {

7469:   MatCheckPreallocated(mat,1);

7471:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7472:   else {
7473:     *done = PETSC_TRUE;
7474:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7475:     if (n)  *n = 0;
7476:     if (ia) *ia = NULL;
7477:     if (ja) *ja = NULL;
7478:   }
7479:   return(0);
7480: }

7482: /*@C
7483:     MatColoringPatch -Used inside matrix coloring routines that
7484:     use MatGetRowIJ() and/or MatGetColumnIJ().

7486:     Collective on Mat

7488:     Input Parameters:
7489: +   mat - the matrix
7490: .   ncolors - max color value
7491: .   n   - number of entries in colorarray
7492: -   colorarray - array indicating color for each column

7494:     Output Parameters:
7495: .   iscoloring - coloring generated using colorarray information

7497:     Level: developer

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

7501: @*/
7502: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7503: {

7511:   MatCheckPreallocated(mat,1);

7513:   if (!mat->ops->coloringpatch) {
7514:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7515:   } else {
7516:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7517:   }
7518:   return(0);
7519: }


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

7525:    Logically Collective on Mat

7527:    Input Parameter:
7528: .  mat - the factored matrix to be reset

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

7537:    Note that one can specify in-place ILU(0) factorization by calling
7538: .vb
7539:      PCType(pc,PCILU);
7540:      PCFactorSeUseInPlace(pc);
7541: .ve
7542:    or by using the options -pc_type ilu -pc_factor_in_place

7544:    In-place factorization ILU(0) can also be used as a local
7545:    solver for the blocks within the block Jacobi or additive Schwarz
7546:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7547:    for details on setting local solver options.

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

7553:    Level: developer

7555: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()

7557:    Concepts: matrices^unfactored

7559: @*/
7560: PetscErrorCode MatSetUnfactored(Mat mat)
7561: {

7567:   MatCheckPreallocated(mat,1);
7568:   mat->factortype = MAT_FACTOR_NONE;
7569:   if (!mat->ops->setunfactored) return(0);
7570:   (*mat->ops->setunfactored)(mat);
7571:   return(0);
7572: }

7574: /*MC
7575:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

7577:     Synopsis:
7578:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7580:     Not collective

7582:     Input Parameter:
7583: .   x - matrix

7585:     Output Parameters:
7586: +   xx_v - the Fortran90 pointer to the array
7587: -   ierr - error code

7589:     Example of Usage:
7590: .vb
7591:       PetscScalar, pointer xx_v(:,:)
7592:       ....
7593:       call MatDenseGetArrayF90(x,xx_v,ierr)
7594:       a = xx_v(3)
7595:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7596: .ve

7598:     Level: advanced

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

7602:     Concepts: matrices^accessing array

7604: M*/

7606: /*MC
7607:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7608:     accessed with MatDenseGetArrayF90().

7610:     Synopsis:
7611:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7613:     Not collective

7615:     Input Parameters:
7616: +   x - matrix
7617: -   xx_v - the Fortran90 pointer to the array

7619:     Output Parameter:
7620: .   ierr - error code

7622:     Example of Usage:
7623: .vb
7624:        PetscScalar, pointer xx_v(:,:)
7625:        ....
7626:        call MatDenseGetArrayF90(x,xx_v,ierr)
7627:        a = xx_v(3)
7628:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7629: .ve

7631:     Level: advanced

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

7635: M*/


7638: /*MC
7639:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

7641:     Synopsis:
7642:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7644:     Not collective

7646:     Input Parameter:
7647: .   x - matrix

7649:     Output Parameters:
7650: +   xx_v - the Fortran90 pointer to the array
7651: -   ierr - error code

7653:     Example of Usage:
7654: .vb
7655:       PetscScalar, pointer xx_v(:)
7656:       ....
7657:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7658:       a = xx_v(3)
7659:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7660: .ve

7662:     Level: advanced

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

7666:     Concepts: matrices^accessing array

7668: M*/

7670: /*MC
7671:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7672:     accessed with MatSeqAIJGetArrayF90().

7674:     Synopsis:
7675:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7677:     Not collective

7679:     Input Parameters:
7680: +   x - matrix
7681: -   xx_v - the Fortran90 pointer to the array

7683:     Output Parameter:
7684: .   ierr - error code

7686:     Example of Usage:
7687: .vb
7688:        PetscScalar, pointer xx_v(:)
7689:        ....
7690:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7691:        a = xx_v(3)
7692:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7693: .ve

7695:     Level: advanced

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

7699: M*/


7702: /*@
7703:     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7704:                       as the original matrix.

7706:     Collective on Mat

7708:     Input Parameters:
7709: +   mat - the original matrix
7710: .   isrow - parallel IS containing the rows this processor should obtain
7711: .   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.
7712: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7714:     Output Parameter:
7715: .   newmat - the new submatrix, of the same type as the old

7717:     Level: advanced

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

7722:     Some matrix types place restrictions on the row and column indices, such
7723:     as that they be sorted or that they be equal to each other.

7725:     The index sets may not have duplicate entries.

7727:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7728:    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7729:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7730:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7731:    you are finished using it.

7733:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7734:     the input matrix.

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

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

7744: .vb
7745:             1  2  0  |  0  3  0  |  0  4
7746:     Proc0   0  5  6  |  7  0  0  |  8  0
7747:             9  0 10  | 11  0  0  | 12  0
7748:     -------------------------------------
7749:            13  0 14  | 15 16 17  |  0  0
7750:     Proc1   0 18  0  | 19 20 21  |  0  0
7751:             0  0  0  | 22 23  0  | 24  0
7752:     -------------------------------------
7753:     Proc2  25 26 27  |  0  0 28  | 29  0
7754:            30  0  0  | 31 32 33  |  0 34
7755: .ve

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

7759: .vb
7760:             2  0  |  0  3  0  |  0
7761:     Proc0   5  6  |  7  0  0  |  8
7762:     -------------------------------
7763:     Proc1  18  0  | 19 20 21  |  0
7764:     -------------------------------
7765:     Proc2  26 27  |  0  0 28  | 29
7766:             0  0  | 31 32 33  |  0
7767: .ve


7770:     Concepts: matrices^submatrices

7772: .seealso: MatCreateSubMatrices()
7773: @*/
7774: PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7775: {
7777:   PetscMPIInt    size;
7778:   Mat            *local;
7779:   IS             iscoltmp;

7788:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7789:   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");

7791:   MatCheckPreallocated(mat,1);
7792:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

7794:   if (!iscol || isrow == iscol) {
7795:     PetscBool   stride;
7796:     PetscMPIInt grabentirematrix = 0,grab;
7797:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7798:     if (stride) {
7799:       PetscInt first,step,n,rstart,rend;
7800:       ISStrideGetInfo(isrow,&first,&step);
7801:       if (step == 1) {
7802:         MatGetOwnershipRange(mat,&rstart,&rend);
7803:         if (rstart == first) {
7804:           ISGetLocalSize(isrow,&n);
7805:           if (n == rend-rstart) {
7806:             grabentirematrix = 1;
7807:           }
7808:         }
7809:       }
7810:     }
7811:     MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7812:     if (grab) {
7813:       PetscInfo(mat,"Getting entire matrix as submatrix\n");
7814:       if (cll == MAT_INITIAL_MATRIX) {
7815:         *newmat = mat;
7816:         PetscObjectReference((PetscObject)mat);
7817:       }
7818:       return(0);
7819:     }
7820:   }

7822:   if (!iscol) {
7823:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7824:   } else {
7825:     iscoltmp = iscol;
7826:   }

7828:   /* if original matrix is on just one processor then use submatrix generated */
7829:   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7830:     MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7831:     if (!iscol) {ISDestroy(&iscoltmp);}
7832:     return(0);
7833:   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7834:     MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7835:     *newmat = *local;
7836:     PetscFree(local);
7837:     if (!iscol) {ISDestroy(&iscoltmp);}
7838:     return(0);
7839:   } else if (!mat->ops->createsubmatrix) {
7840:     /* Create a new matrix type that implements the operation using the full matrix */
7841:     PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7842:     switch (cll) {
7843:     case MAT_INITIAL_MATRIX:
7844:       MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);
7845:       break;
7846:     case MAT_REUSE_MATRIX:
7847:       MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);
7848:       break;
7849:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7850:     }
7851:     PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);
7852:     if (!iscol) {ISDestroy(&iscoltmp);}
7853:     return(0);
7854:   }

7856:   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7857:   PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7858:   (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7859:   PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);
7860:   if (!iscol) {ISDestroy(&iscoltmp);}
7861:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7862:   return(0);
7863: }

7865: /*@
7866:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7867:    used during the assembly process to store values that belong to
7868:    other processors.

7870:    Not Collective

7872:    Input Parameters:
7873: +  mat   - the matrix
7874: .  size  - the initial size of the stash.
7875: -  bsize - the initial size of the block-stash(if used).

7877:    Options Database Keys:
7878: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7879: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7881:    Level: intermediate

7883:    Notes:
7884:      The block-stash is used for values set with MatSetValuesBlocked() while
7885:      the stash is used for values set with MatSetValues()

7887:      Run with the option -info and look for output of the form
7888:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7889:      to determine the appropriate value, MM, to use for size and
7890:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7891:      to determine the value, BMM to use for bsize

7893:    Concepts: stash^setting matrix size
7894:    Concepts: matrices^stash

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

7898: @*/
7899: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7900: {

7906:   MatStashSetInitialSize_Private(&mat->stash,size);
7907:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7908:   return(0);
7909: }

7911: /*@
7912:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7913:      the matrix

7915:    Neighbor-wise Collective on Mat

7917:    Input Parameters:
7918: +  mat   - the matrix
7919: .  x,y - the vectors
7920: -  w - where the result is stored

7922:    Level: intermediate

7924:    Notes:
7925:     w may be the same vector as y.

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

7930:     Concepts: interpolation

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

7934: @*/
7935: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7936: {
7938:   PetscInt       M,N,Ny;

7946:   MatCheckPreallocated(A,1);
7947:   MatGetSize(A,&M,&N);
7948:   VecGetSize(y,&Ny);
7949:   if (M == Ny) {
7950:     MatMultAdd(A,x,y,w);
7951:   } else {
7952:     MatMultTransposeAdd(A,x,y,w);
7953:   }
7954:   return(0);
7955: }

7957: /*@
7958:    MatInterpolate - y = A*x or A'*x depending on the shape of
7959:      the matrix

7961:    Neighbor-wise Collective on Mat

7963:    Input Parameters:
7964: +  mat   - the matrix
7965: -  x,y - the vectors

7967:    Level: intermediate

7969:    Notes:
7970:     This allows one to use either the restriction or interpolation (its transpose)
7971:     matrix to do the interpolation

7973:    Concepts: matrices^interpolation

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

7977: @*/
7978: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7979: {
7981:   PetscInt       M,N,Ny;

7988:   MatCheckPreallocated(A,1);
7989:   MatGetSize(A,&M,&N);
7990:   VecGetSize(y,&Ny);
7991:   if (M == Ny) {
7992:     MatMult(A,x,y);
7993:   } else {
7994:     MatMultTranspose(A,x,y);
7995:   }
7996:   return(0);
7997: }

7999: /*@
8000:    MatRestrict - y = A*x or A'*x

8002:    Neighbor-wise Collective on Mat

8004:    Input Parameters:
8005: +  mat   - the matrix
8006: -  x,y - the vectors

8008:    Level: intermediate

8010:    Notes:
8011:     This allows one to use either the restriction or interpolation (its transpose)
8012:     matrix to do the restriction

8014:    Concepts: matrices^restriction

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

8018: @*/
8019: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8020: {
8022:   PetscInt       M,N,Ny;

8029:   MatCheckPreallocated(A,1);

8031:   MatGetSize(A,&M,&N);
8032:   VecGetSize(y,&Ny);
8033:   if (M == Ny) {
8034:     MatMult(A,x,y);
8035:   } else {
8036:     MatMultTranspose(A,x,y);
8037:   }
8038:   return(0);
8039: }

8041: /*@C
8042:    MatGetNullSpace - retrieves the null space to a matrix.

8044:    Logically Collective on Mat and MatNullSpace

8046:    Input Parameters:
8047: +  mat - the matrix
8048: -  nullsp - the null space object

8050:    Level: developer

8052:    Concepts: null space^attaching to matrix

8054: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8055: @*/
8056: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8057: {
8061:   *nullsp = mat->nullsp;
8062:   return(0);
8063: }

8065: /*@C
8066:    MatSetNullSpace - attaches a null space to a matrix.

8068:    Logically Collective on Mat and MatNullSpace

8070:    Input Parameters:
8071: +  mat - the matrix
8072: -  nullsp - the null space object

8074:    Level: advanced

8076:    Notes:
8077:       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached

8079:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8080:       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.

8082:       You can remove the null space by calling this routine with an nullsp of NULL


8085:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8086:    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).
8087:    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
8088:    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
8089:    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).

8091:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

8093:     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
8094:     routine also automatically calls MatSetTransposeNullSpace().

8096:    Concepts: null space^attaching to matrix

8098: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8099: @*/
8100: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8101: {

8107:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8108:   MatNullSpaceDestroy(&mat->nullsp);
8109:   mat->nullsp = nullsp;
8110:   if (mat->symmetric_set && mat->symmetric) {
8111:     MatSetTransposeNullSpace(mat,nullsp);
8112:   }
8113:   return(0);
8114: }

8116: /*@
8117:    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.

8119:    Logically Collective on Mat and MatNullSpace

8121:    Input Parameters:
8122: +  mat - the matrix
8123: -  nullsp - the null space object

8125:    Level: developer

8127:    Concepts: null space^attaching to matrix

8129: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8130: @*/
8131: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8132: {
8137:   *nullsp = mat->transnullsp;
8138:   return(0);
8139: }

8141: /*@
8142:    MatSetTransposeNullSpace - attaches a null space to a matrix.

8144:    Logically Collective on Mat and MatNullSpace

8146:    Input Parameters:
8147: +  mat - the matrix
8148: -  nullsp - the null space object

8150:    Level: advanced

8152:    Notes:
8153:       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.
8154:       You must also call MatSetNullSpace()


8157:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8158:    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).
8159:    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
8160:    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
8161:    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).

8163:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

8165:    Concepts: null space^attaching to matrix

8167: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8168: @*/
8169: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8170: {

8177:   MatCheckPreallocated(mat,1);
8178:   PetscObjectReference((PetscObject)nullsp);
8179:   MatNullSpaceDestroy(&mat->transnullsp);
8180:   mat->transnullsp = nullsp;
8181:   return(0);
8182: }

8184: /*@
8185:    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8186:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

8188:    Logically Collective on Mat and MatNullSpace

8190:    Input Parameters:
8191: +  mat - the matrix
8192: -  nullsp - the null space object

8194:    Level: advanced

8196:    Notes:
8197:       Overwrites any previous near null space that may have been attached

8199:       You can remove the null space by calling this routine with an nullsp of NULL

8201:    Concepts: null space^attaching to matrix

8203: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8204: @*/
8205: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8206: {

8213:   MatCheckPreallocated(mat,1);
8214:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8215:   MatNullSpaceDestroy(&mat->nearnullsp);
8216:   mat->nearnullsp = nullsp;
8217:   return(0);
8218: }

8220: /*@
8221:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

8223:    Not Collective

8225:    Input Parameters:
8226: .  mat - the matrix

8228:    Output Parameters:
8229: .  nullsp - the null space object, NULL if not set

8231:    Level: developer

8233:    Concepts: null space^attaching to matrix

8235: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8236: @*/
8237: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8238: {
8243:   MatCheckPreallocated(mat,1);
8244:   *nullsp = mat->nearnullsp;
8245:   return(0);
8246: }

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

8251:    Collective on Mat

8253:    Input Parameters:
8254: +  mat - the matrix
8255: .  row - row/column permutation
8256: .  fill - expected fill factor >= 1.0
8257: -  level - level of fill, for ICC(k)

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

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

8267:    Level: developer

8269:    Concepts: matrices^incomplete Cholesky factorization
8270:    Concepts: Cholesky factorization

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

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

8277: @*/
8278: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8279: {

8287:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8288:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8289:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8290:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8291:   MatCheckPreallocated(mat,1);
8292:   (*mat->ops->iccfactor)(mat,row,info);
8293:   PetscObjectStateIncrease((PetscObject)mat);
8294:   return(0);
8295: }

8297: /*@
8298:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8299:          ghosted ones.

8301:    Not Collective

8303:    Input Parameters:
8304: +  mat - the matrix
8305: -  diag = the diagonal values, including ghost ones

8307:    Level: developer

8309:    Notes:
8310:     Works only for MPIAIJ and MPIBAIJ matrices

8312: .seealso: MatDiagonalScale()
8313: @*/
8314: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8315: {
8317:   PetscMPIInt    size;


8324:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8325:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8326:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8327:   if (size == 1) {
8328:     PetscInt n,m;
8329:     VecGetSize(diag,&n);
8330:     MatGetSize(mat,0,&m);
8331:     if (m == n) {
8332:       MatDiagonalScale(mat,0,diag);
8333:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8334:   } else {
8335:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8336:   }
8337:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8338:   PetscObjectStateIncrease((PetscObject)mat);
8339:   return(0);
8340: }

8342: /*@
8343:    MatGetInertia - Gets the inertia from a factored matrix

8345:    Collective on Mat

8347:    Input Parameter:
8348: .  mat - the matrix

8350:    Output Parameters:
8351: +   nneg - number of negative eigenvalues
8352: .   nzero - number of zero eigenvalues
8353: -   npos - number of positive eigenvalues

8355:    Level: advanced

8357:    Notes:
8358:     Matrix must have been factored by MatCholeskyFactor()


8361: @*/
8362: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8363: {

8369:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8370:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8371:   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8372:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8373:   return(0);
8374: }

8376: /* ----------------------------------------------------------------*/
8377: /*@C
8378:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

8380:    Neighbor-wise Collective on Mat and Vecs

8382:    Input Parameters:
8383: +  mat - the factored matrix
8384: -  b - the right-hand-side vectors

8386:    Output Parameter:
8387: .  x - the result vectors

8389:    Notes:
8390:    The vectors b and x cannot be the same.  I.e., one cannot
8391:    call MatSolves(A,x,x).

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

8398:    Level: developer

8400:    Concepts: matrices^triangular solves

8402: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8403: @*/
8404: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8405: {

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

8415:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8416:   MatCheckPreallocated(mat,1);
8417:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8418:   (*mat->ops->solves)(mat,b,x);
8419:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8420:   return(0);
8421: }

8423: /*@
8424:    MatIsSymmetric - Test whether a matrix is symmetric

8426:    Collective on Mat

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

8432:    Output Parameters:
8433: .  flg - the result

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

8438:    Level: intermediate

8440:    Concepts: matrix^symmetry

8442: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8443: @*/
8444: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8445: {


8452:   if (!A->symmetric_set) {
8453:     if (!A->ops->issymmetric) {
8454:       MatType mattype;
8455:       MatGetType(A,&mattype);
8456:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8457:     }
8458:     (*A->ops->issymmetric)(A,tol,flg);
8459:     if (!tol) {
8460:       A->symmetric_set = PETSC_TRUE;
8461:       A->symmetric     = *flg;
8462:       if (A->symmetric) {
8463:         A->structurally_symmetric_set = PETSC_TRUE;
8464:         A->structurally_symmetric     = PETSC_TRUE;
8465:       }
8466:     }
8467:   } else if (A->symmetric) {
8468:     *flg = PETSC_TRUE;
8469:   } else if (!tol) {
8470:     *flg = PETSC_FALSE;
8471:   } else {
8472:     if (!A->ops->issymmetric) {
8473:       MatType mattype;
8474:       MatGetType(A,&mattype);
8475:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8476:     }
8477:     (*A->ops->issymmetric)(A,tol,flg);
8478:   }
8479:   return(0);
8480: }

8482: /*@
8483:    MatIsHermitian - Test whether a matrix is Hermitian

8485:    Collective on Mat

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

8491:    Output Parameters:
8492: .  flg - the result

8494:    Level: intermediate

8496:    Concepts: matrix^symmetry

8498: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8499:           MatIsSymmetricKnown(), MatIsSymmetric()
8500: @*/
8501: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8502: {


8509:   if (!A->hermitian_set) {
8510:     if (!A->ops->ishermitian) {
8511:       MatType mattype;
8512:       MatGetType(A,&mattype);
8513:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8514:     }
8515:     (*A->ops->ishermitian)(A,tol,flg);
8516:     if (!tol) {
8517:       A->hermitian_set = PETSC_TRUE;
8518:       A->hermitian     = *flg;
8519:       if (A->hermitian) {
8520:         A->structurally_symmetric_set = PETSC_TRUE;
8521:         A->structurally_symmetric     = PETSC_TRUE;
8522:       }
8523:     }
8524:   } else if (A->hermitian) {
8525:     *flg = PETSC_TRUE;
8526:   } else if (!tol) {
8527:     *flg = PETSC_FALSE;
8528:   } else {
8529:     if (!A->ops->ishermitian) {
8530:       MatType mattype;
8531:       MatGetType(A,&mattype);
8532:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8533:     }
8534:     (*A->ops->ishermitian)(A,tol,flg);
8535:   }
8536:   return(0);
8537: }

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

8542:    Not Collective

8544:    Input Parameter:
8545: .  A - the matrix to check

8547:    Output Parameters:
8548: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8549: -  flg - the result

8551:    Level: advanced

8553:    Concepts: matrix^symmetry

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

8558: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8559: @*/
8560: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8561: {
8566:   if (A->symmetric_set) {
8567:     *set = PETSC_TRUE;
8568:     *flg = A->symmetric;
8569:   } else {
8570:     *set = PETSC_FALSE;
8571:   }
8572:   return(0);
8573: }

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

8578:    Not Collective

8580:    Input Parameter:
8581: .  A - the matrix to check

8583:    Output Parameters:
8584: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8585: -  flg - the result

8587:    Level: advanced

8589:    Concepts: matrix^symmetry

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

8594: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8595: @*/
8596: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8597: {
8602:   if (A->hermitian_set) {
8603:     *set = PETSC_TRUE;
8604:     *flg = A->hermitian;
8605:   } else {
8606:     *set = PETSC_FALSE;
8607:   }
8608:   return(0);
8609: }

8611: /*@
8612:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8614:    Collective on Mat

8616:    Input Parameter:
8617: .  A - the matrix to test

8619:    Output Parameters:
8620: .  flg - the result

8622:    Level: intermediate

8624:    Concepts: matrix^symmetry

8626: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8627: @*/
8628: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8629: {

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

8639:     A->structurally_symmetric_set = PETSC_TRUE;
8640:   }
8641:   *flg = A->structurally_symmetric;
8642:   return(0);
8643: }

8645: /*@
8646:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8647:        to be communicated to other processors during the MatAssemblyBegin/End() process

8649:     Not collective

8651:    Input Parameter:
8652: .   vec - the vector

8654:    Output Parameters:
8655: +   nstash   - the size of the stash
8656: .   reallocs - the number of additional mallocs incurred.
8657: .   bnstash   - the size of the block stash
8658: -   breallocs - the number of additional mallocs incurred.in the block stash

8660:    Level: advanced

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

8664: @*/
8665: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8666: {

8670:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8671:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8672:   return(0);
8673: }

8675: /*@C
8676:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8677:      parallel layout

8679:    Collective on Mat

8681:    Input Parameter:
8682: .  mat - the matrix

8684:    Output Parameter:
8685: +   right - (optional) vector that the matrix can be multiplied against
8686: -   left - (optional) vector that the matrix vector product can be stored in

8688:    Notes:
8689:     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().

8691:   Notes:
8692:     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed

8694:   Level: advanced

8696: .seealso: MatCreate(), VecDestroy()
8697: @*/
8698: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8699: {

8705:   if (mat->ops->getvecs) {
8706:     (*mat->ops->getvecs)(mat,right,left);
8707:   } else {
8708:     PetscInt rbs,cbs;
8709:     MatGetBlockSizes(mat,&rbs,&cbs);
8710:     if (right) {
8711:       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8712:       VecCreate(PetscObjectComm((PetscObject)mat),right);
8713:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8714:       VecSetBlockSize(*right,cbs);
8715:       VecSetType(*right,VECSTANDARD);
8716:       PetscLayoutReference(mat->cmap,&(*right)->map);
8717:     }
8718:     if (left) {
8719:       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8720:       VecCreate(PetscObjectComm((PetscObject)mat),left);
8721:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8722:       VecSetBlockSize(*left,rbs);
8723:       VecSetType(*left,VECSTANDARD);
8724:       PetscLayoutReference(mat->rmap,&(*left)->map);
8725:     }
8726:   }
8727:   return(0);
8728: }

8730: /*@C
8731:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8732:      with default values.

8734:    Not Collective

8736:    Input Parameters:
8737: .    info - the MatFactorInfo data structure


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

8744:    Level: developer

8746: .seealso: MatFactorInfo

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

8751: @*/

8753: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8754: {

8758:   PetscMemzero(info,sizeof(MatFactorInfo));
8759:   return(0);
8760: }

8762: /*@
8763:    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed

8765:    Collective on Mat

8767:    Input Parameters:
8768: +  mat - the factored matrix
8769: -  is - the index set defining the Schur indices (0-based)

8771:    Notes:
8772:     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.

8774:    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.

8776:    Level: developer

8778:    Concepts:

8780: .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8781:           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()

8783: @*/
8784: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8785: {
8786:   PetscErrorCode ierr,(*f)(Mat,IS);

8794:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8795:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8796:   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");
8797:   if (mat->schur) {
8798:     MatDestroy(&mat->schur);
8799:   }
8800:   (*f)(mat,is);
8801:   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8802:   MatFactorSetUpInPlaceSchur_Private(mat);
8803:   return(0);
8804: }

8806: /*@
8807:   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step

8809:    Logically Collective on Mat

8811:    Input Parameters:
8812: +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8813: .  S - location where to return the Schur complement, can be NULL
8814: -  status - the status of the Schur complement matrix, can be NULL

8816:    Notes:
8817:    You must call MatFactorSetSchurIS() before calling this routine.

8819:    The routine provides a copy of the Schur matrix stored within the solver data structures.
8820:    The caller must destroy the object when it is no longer needed.
8821:    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.

8823:    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)

8825:    Developer Notes:
8826:     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
8827:    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.

8829:    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.

8831:    Level: advanced

8833:    References:

8835: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8836: @*/
8837: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8838: {

8845:   if (S) {
8846:     PetscErrorCode (*f)(Mat,Mat*);

8848:     PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);
8849:     if (f) {
8850:       (*f)(F,S);
8851:     } else {
8852:       MatDuplicate(F->schur,MAT_COPY_VALUES,S);
8853:     }
8854:   }
8855:   if (status) *status = F->schur_status;
8856:   return(0);
8857: }

8859: /*@
8860:   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix

8862:    Logically Collective on Mat

8864:    Input Parameters:
8865: +  F - the factored matrix obtained by calling MatGetFactor()
8866: .  *S - location where to return the Schur complement, can be NULL
8867: -  status - the status of the Schur complement matrix, can be NULL

8869:    Notes:
8870:    You must call MatFactorSetSchurIS() before calling this routine.

8872:    Schur complement mode is currently implemented for sequential matrices.
8873:    The routine returns a the Schur Complement stored within the data strutures of the solver.
8874:    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8875:    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.

8877:    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix

8879:    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.

8881:    Level: advanced

8883:    References:

8885: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8886: @*/
8887: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8888: {
8893:   if (S) *S = F->schur;
8894:   if (status) *status = F->schur_status;
8895:   return(0);
8896: }

8898: /*@
8899:   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement

8901:    Logically Collective on Mat

8903:    Input Parameters:
8904: +  F - the factored matrix obtained by calling MatGetFactor()
8905: .  *S - location where the Schur complement is stored
8906: -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)

8908:    Notes:

8910:    Level: advanced

8912:    References:

8914: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8915: @*/
8916: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8917: {

8922:   if (S) {
8924:     *S = NULL;
8925:   }
8926:   F->schur_status = status;
8927:   MatFactorUpdateSchurStatus_Private(F);
8928:   return(0);
8929: }

8931: /*@
8932:   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step

8934:    Logically Collective on Mat

8936:    Input Parameters:
8937: +  F - the factored matrix obtained by calling MatGetFactor()
8938: .  rhs - location where the right hand side of the Schur complement system is stored
8939: -  sol - location where the solution of the Schur complement system has to be returned

8941:    Notes:
8942:    The sizes of the vectors should match the size of the Schur complement

8944:    Must be called after MatFactorSetSchurIS()

8946:    Level: advanced

8948:    References:

8950: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8951: @*/
8952: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8953: {

8965:   MatFactorFactorizeSchurComplement(F);
8966:   switch (F->schur_status) {
8967:   case MAT_FACTOR_SCHUR_FACTORED:
8968:     MatSolveTranspose(F->schur,rhs,sol);
8969:     break;
8970:   case MAT_FACTOR_SCHUR_INVERTED:
8971:     MatMultTranspose(F->schur,rhs,sol);
8972:     break;
8973:   default:
8974:     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
8975:     break;
8976:   }
8977:   return(0);
8978: }

8980: /*@
8981:   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step

8983:    Logically Collective on Mat

8985:    Input Parameters:
8986: +  F - the factored matrix obtained by calling MatGetFactor()
8987: .  rhs - location where the right hand side of the Schur complement system is stored
8988: -  sol - location where the solution of the Schur complement system has to be returned

8990:    Notes:
8991:    The sizes of the vectors should match the size of the Schur complement

8993:    Must be called after MatFactorSetSchurIS()

8995:    Level: advanced

8997:    References:

8999: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9000: @*/
9001: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9002: {

9014:   MatFactorFactorizeSchurComplement(F);
9015:   switch (F->schur_status) {
9016:   case MAT_FACTOR_SCHUR_FACTORED:
9017:     MatSolve(F->schur,rhs,sol);
9018:     break;
9019:   case MAT_FACTOR_SCHUR_INVERTED:
9020:     MatMult(F->schur,rhs,sol);
9021:     break;
9022:   default:
9023:     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9024:     break;
9025:   }
9026:   return(0);
9027: }

9029: /*@
9030:   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step

9032:    Logically Collective on Mat

9034:    Input Parameters:
9035: +  F - the factored matrix obtained by calling MatGetFactor()

9037:    Notes:
9038:     Must be called after MatFactorSetSchurIS().

9040:    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.

9042:    Level: advanced

9044:    References:

9046: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9047: @*/
9048: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9049: {

9055:   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) return(0);
9056:   MatFactorFactorizeSchurComplement(F);
9057:   MatFactorInvertSchurComplement_Private(F);
9058:   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9059:   return(0);
9060: }

9062: /*@
9063:   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step

9065:    Logically Collective on Mat

9067:    Input Parameters:
9068: +  F - the factored matrix obtained by calling MatGetFactor()

9070:    Notes:
9071:     Must be called after MatFactorSetSchurIS().

9073:    Level: advanced

9075:    References:

9077: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9078: @*/
9079: PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9080: {

9086:   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) return(0);
9087:   MatFactorFactorizeSchurComplement_Private(F);
9088:   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9089:   return(0);
9090: }

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

9095:    Neighbor-wise Collective on Mat

9097:    Input Parameters:
9098: +  A - the matrix
9099: .  P - the projection matrix
9100: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9101: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9102:           if the result is a dense matrix this is irrelevent

9104:    Output Parameters:
9105: .  C - the product matrix

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

9110:    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9111:    which inherit from AIJ.

9113:    Level: intermediate

9115: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9116: @*/
9117: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9118: {
9120:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9121:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9122:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9123:   PetscBool      sametype;

9128:   MatCheckPreallocated(A,1);
9129:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9130:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9131:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9134:   MatCheckPreallocated(P,2);
9135:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9136:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9138:   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);
9139:   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);
9140:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9141:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9143:   if (scall == MAT_REUSE_MATRIX) {

9147:     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9148:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9149:     PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9150:     (*(*C)->ops->ptapnumeric)(A,P,*C);
9151:     PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9152:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9153:     return(0);
9154:   }

9156:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9157:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

9159:   fA = A->ops->ptap;
9160:   fP = P->ops->ptap;
9161:   PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);
9162:   if (fP == fA && sametype) {
9163:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9164:     ptap = fA;
9165:   } else {
9166:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9167:     char ptapname[256];
9168:     PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));
9169:     PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));
9170:     PetscStrlcat(ptapname,"_",sizeof(ptapname));
9171:     PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));
9172:     PetscStrlcat(ptapname,"_C",sizeof(ptapname)); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9173:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9174:     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);
9175:   }

9177:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9178:   (*ptap)(A,P,scall,fill,C);
9179:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9180:   return(0);
9181: }

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

9186:    Neighbor-wise Collective on Mat

9188:    Input Parameters:
9189: +  A - the matrix
9190: -  P - the projection matrix

9192:    Output Parameters:
9193: .  C - the product matrix

9195:    Notes:
9196:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9197:    the user using MatDeatroy().

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

9202:    Level: intermediate

9204: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9205: @*/
9206: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9207: {

9213:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9214:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9217:   MatCheckPreallocated(P,2);
9218:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9219:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9222:   MatCheckPreallocated(C,3);
9223:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9224:   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);
9225:   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);
9226:   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);
9227:   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);
9228:   MatCheckPreallocated(A,1);

9230:   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9231:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9232:   (*C->ops->ptapnumeric)(A,P,C);
9233:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9234:   return(0);
9235: }

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

9240:    Neighbor-wise Collective on Mat

9242:    Input Parameters:
9243: +  A - the matrix
9244: -  P - the projection matrix

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

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

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

9256:    Level: intermediate

9258: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9259: @*/
9260: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9261: {

9267:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9268:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9269:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9272:   MatCheckPreallocated(P,2);
9273:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9274:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9277:   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);
9278:   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);
9279:   MatCheckPreallocated(A,1);

9281:   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9282:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9283:   (*A->ops->ptapsymbolic)(A,P,fill,C);
9284:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

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

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

9293:    Neighbor-wise Collective on Mat

9295:    Input Parameters:
9296: +  A - the matrix
9297: .  R - the projection matrix
9298: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9299: -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9300:           if the result is a dense matrix this is irrelevent

9302:    Output Parameters:
9303: .  C - the product matrix

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

9308:    This routine is currently only implemented for pairs of AIJ matrices and classes
9309:    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9310:    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9311:    We recommend using MatPtAP().

9313:    Level: intermediate

9315: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9316: @*/
9317: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9318: {

9324:   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9325:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9326:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9329:   MatCheckPreallocated(R,2);
9330:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9331:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9333:   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);

9335:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9336:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9337:   MatCheckPreallocated(A,1);

9339:   if (!A->ops->rart) {
9340:     Mat Rt;
9341:     MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);
9342:     MatMatMatMult(R,A,Rt,scall,fill,C);
9343:     MatDestroy(&Rt);
9344:     return(0);
9345:   }
9346:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
9347:   (*A->ops->rart)(A,R,scall,fill,C);
9348:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
9349:   return(0);
9350: }

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

9355:    Neighbor-wise Collective on Mat

9357:    Input Parameters:
9358: +  A - the matrix
9359: -  R - the projection matrix

9361:    Output Parameters:
9362: .  C - the product matrix

9364:    Notes:
9365:    C must have been created by calling MatRARtSymbolic and must be destroyed by
9366:    the user using MatDestroy().

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

9371:    Level: intermediate

9373: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9374: @*/
9375: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9376: {

9382:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9383:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9386:   MatCheckPreallocated(R,2);
9387:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9388:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9391:   MatCheckPreallocated(C,3);
9392:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9393:   if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
9394:   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9395:   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);
9396:   if (R->rmap->N!=C->cmap->N)