Actual source code: matrix.c
petsc-3.8.4 2018-03-24
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_CUSPCopyToGPU, 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 Vec
47: Input Parameters:
48: + x - the vector
49: - rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50: it will create one internally.
52: Output Parameter:
53: . x - the vector
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: This routine does not work for factorizations done with external packages.
112: This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
114: This can be called on non-factored matrices that come from, for example, matrices used in SOR.
116: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
117: @*/
118: PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
119: {
122: *pivot = mat->factorerror_zeropivot_value;
123: *row = mat->factorerror_zeropivot_row;
124: return(0);
125: }
127: /*@
128: MatFactorGetError - gets the error code from a factorization
130: Logically Collective on Mat
132: Input Parameters:
133: . mat - the factored matrix
135: Output Parameter:
136: . err - the error code
138: Level: advanced
140: Notes: This can be called on non-factored matrices that come from, for example, matrices used in SOR.
142: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
143: @*/
144: PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
145: {
148: *err = mat->factorerrortype;
149: return(0);
150: }
152: /*@
153: MatFactorClearError - clears the error code in a factorization
155: Logically Collective on Mat
157: Input Parameter:
158: . mat - the factored matrix
160: Level: developer
162: Notes: This can be called on non-factored matrices that come from, for example, matrices used in SOR.
164: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
165: @*/
166: PetscErrorCode MatFactorClearError(Mat mat)
167: {
170: mat->factorerrortype = MAT_FACTOR_NOERROR;
171: mat->factorerror_zeropivot_value = 0.0;
172: mat->factorerror_zeropivot_row = 0;
173: return(0);
174: }
176: static PetscErrorCode MatFindNonzeroRows_Basic(Mat mat,IS *keptrows)
177: {
178: PetscErrorCode ierr;
179: Vec r,l;
180: const PetscScalar *al;
181: PetscInt i,nz,gnz,N,n;
184: MatGetSize(mat,&N,NULL);
185: MatGetLocalSize(mat,&n,NULL);
186: MatCreateVecs(mat,&r,&l);
187: VecSet(l,0.0);
188: VecSetRandom(r,NULL);
189: MatMult(mat,r,l);
190: VecGetArrayRead(l,&al);
191: for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++;
192: MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));
193: if (gnz != N) {
194: PetscInt *nzr;
195: PetscMalloc1(nz,&nzr);
196: if (nz) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
197: ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,keptrows);
198: } else *keptrows = NULL;
199: VecRestoreArrayRead(l,&al);
200: VecDestroy(&l);
201: VecDestroy(&r);
202: return(0);
203: }
205: /*@
206: MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
208: Input Parameter:
209: . A - the matrix
211: Output Parameter:
212: . keptrows - the rows that are not completely zero
214: Notes: keptrows is set to NULL if all rows are nonzero.
216: Level: intermediate
218: @*/
219: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
220: {
227: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
228: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
229: if (!mat->ops->findnonzerorows) {
230: MatFindNonzeroRows_Basic(mat,keptrows);
231: } else {
232: (*mat->ops->findnonzerorows)(mat,keptrows);
233: }
234: return(0);
235: }
237: /*@
238: MatFindZeroRows - Locate all rows that are completely zero in the matrix
240: Input Parameter:
241: . A - the matrix
243: Output Parameter:
244: . zerorows - the rows that are completely zero
246: Notes: zerorows is set to NULL if no rows are zero.
248: Level: intermediate
250: @*/
251: PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
252: {
254: IS keptrows;
255: PetscInt m, n;
260: MatFindNonzeroRows(mat, &keptrows);
261: /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
262: In keeping with this convention, we set zerorows to NULL if there are no zero
263: rows. */
264: if (keptrows == NULL) {
265: *zerorows = NULL;
266: } else {
267: MatGetOwnershipRange(mat,&m,&n);
268: ISComplement(keptrows,m,n,zerorows);
269: ISDestroy(&keptrows);
270: }
271: return(0);
272: }
274: /*@
275: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
277: Not Collective
279: Input Parameters:
280: . A - the matrix
282: Output Parameters:
283: . a - the diagonal part (which is a SEQUENTIAL matrix)
285: Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
286: Use caution, as the reference count on the returned matrix is not incremented and it is used as
287: part of the containing MPI Mat's normal operation.
289: Level: advanced
291: @*/
292: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
293: {
300: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
301: if (!A->ops->getdiagonalblock) {
302: PetscMPIInt size;
303: MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
304: if (size == 1) {
305: *a = A;
306: return(0);
307: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
308: }
309: (*A->ops->getdiagonalblock)(A,a);
310: return(0);
311: }
313: /*@
314: MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
316: Collective on Mat
318: Input Parameters:
319: . mat - the matrix
321: Output Parameter:
322: . trace - the sum of the diagonal entries
324: Level: advanced
326: @*/
327: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
328: {
330: Vec diag;
333: MatCreateVecs(mat,&diag,NULL);
334: MatGetDiagonal(mat,diag);
335: VecSum(diag,trace);
336: VecDestroy(&diag);
337: return(0);
338: }
340: /*@
341: MatRealPart - Zeros out the imaginary part of the matrix
343: Logically Collective on Mat
345: Input Parameters:
346: . mat - the matrix
348: Level: advanced
351: .seealso: MatImaginaryPart()
352: @*/
353: PetscErrorCode MatRealPart(Mat mat)
354: {
360: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
361: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
362: if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
363: MatCheckPreallocated(mat,1);
364: (*mat->ops->realpart)(mat);
365: #if defined(PETSC_HAVE_CUSP)
366: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
367: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
368: }
369: #elif defined(PETSC_HAVE_VIENNACL)
370: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
371: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
372: }
373: #elif defined(PETSC_HAVE_VECCUDA)
374: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
375: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
376: }
377: #endif
378: return(0);
379: }
381: /*@C
382: MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
384: Collective on Mat
386: Input Parameter:
387: . mat - the matrix
389: Output Parameters:
390: + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
391: - ghosts - the global indices of the ghost points
393: Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
395: Level: advanced
397: @*/
398: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
399: {
405: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
406: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
407: if (!mat->ops->getghosts) {
408: if (nghosts) *nghosts = 0;
409: if (ghosts) *ghosts = 0;
410: } else {
411: (*mat->ops->getghosts)(mat,nghosts,ghosts);
412: }
413: return(0);
414: }
417: /*@
418: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
420: Logically Collective on Mat
422: Input Parameters:
423: . mat - the matrix
425: Level: advanced
428: .seealso: MatRealPart()
429: @*/
430: PetscErrorCode MatImaginaryPart(Mat mat)
431: {
437: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
438: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
439: if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
440: MatCheckPreallocated(mat,1);
441: (*mat->ops->imaginarypart)(mat);
442: #if defined(PETSC_HAVE_CUSP)
443: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
444: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
445: }
446: #elif defined(PETSC_HAVE_VIENNACL)
447: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
448: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
449: }
450: #elif defined(PETSC_HAVE_VECCUDA)
451: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
452: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
453: }
454: #endif
455: return(0);
456: }
458: /*@
459: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
461: Not Collective
463: Input Parameter:
464: . mat - the matrix
466: Output Parameters:
467: + missing - is any diagonal missing
468: - dd - first diagonal entry that is missing (optional) on this process
470: Level: advanced
473: .seealso: MatRealPart()
474: @*/
475: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
476: {
482: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
483: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
484: if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
485: (*mat->ops->missingdiagonal)(mat,missing,dd);
486: return(0);
487: }
489: /*@C
490: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
491: for each row that you get to ensure that your application does
492: not bleed memory.
494: Not Collective
496: Input Parameters:
497: + mat - the matrix
498: - row - the row to get
500: Output Parameters:
501: + ncols - if not NULL, the number of nonzeros in the row
502: . cols - if not NULL, the column numbers
503: - vals - if not NULL, the values
505: Notes:
506: This routine is provided for people who need to have direct access
507: to the structure of a matrix. We hope that we provide enough
508: high-level matrix routines that few users will need it.
510: MatGetRow() always returns 0-based column indices, regardless of
511: whether the internal representation is 0-based (default) or 1-based.
513: For better efficiency, set cols and/or vals to NULL if you do
514: not wish to extract these quantities.
516: The user can only examine the values extracted with MatGetRow();
517: the values cannot be altered. To change the matrix entries, one
518: must use MatSetValues().
520: You can only have one call to MatGetRow() outstanding for a particular
521: matrix at a time, per processor. MatGetRow() can only obtain rows
522: associated with the given processor, it cannot get rows from the
523: other processors; for that we suggest using MatCreateSubMatrices(), then
524: MatGetRow() on the submatrix. The row index passed to MatGetRows()
525: is in the global number of rows.
527: Fortran Notes:
528: The calling sequence from Fortran is
529: .vb
530: MatGetRow(matrix,row,ncols,cols,values,ierr)
531: Mat matrix (input)
532: integer row (input)
533: integer ncols (output)
534: integer cols(maxcols) (output)
535: double precision (or double complex) values(maxcols) output
536: .ve
537: where maxcols >= maximum nonzeros in any row of the matrix.
540: Caution:
541: Do not try to change the contents of the output arrays (cols and vals).
542: In some cases, this may corrupt the matrix.
544: Level: advanced
546: Concepts: matrices^row access
548: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
549: @*/
550: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
551: {
553: PetscInt incols;
558: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
559: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
560: if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
561: MatCheckPreallocated(mat,1);
562: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
563: (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
564: if (ncols) *ncols = incols;
565: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
566: return(0);
567: }
569: /*@
570: MatConjugate - replaces the matrix values with their complex conjugates
572: Logically Collective on Mat
574: Input Parameters:
575: . mat - the matrix
577: Level: advanced
579: .seealso: VecConjugate()
580: @*/
581: PetscErrorCode MatConjugate(Mat mat)
582: {
583: #if defined(PETSC_USE_COMPLEX)
588: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
589: 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");
590: (*mat->ops->conjugate)(mat);
591: #if defined(PETSC_HAVE_CUSP)
592: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
593: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
594: }
595: #elif defined(PETSC_HAVE_VIENNACL)
596: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
597: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
598: }
599: #elif defined(PETSC_HAVE_VECCUDA)
600: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
601: mat->valid_GPU_matrix = PETSC_CUDA_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: On the fortran side, the user should pass in a string 'prefix' of
797: sufficient length to hold the prefix.
799: Level: advanced
801: .keywords: Mat, get, options, prefix, database
803: .seealso: MatAppendOptionsPrefix()
804: @*/
805: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
806: {
811: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
812: return(0);
813: }
815: /*@
816: MatSetUp - Sets up the internal matrix data structures for the later use.
818: Collective on Mat
820: Input Parameters:
821: . A - the Mat context
823: Notes:
824: If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
826: If a suitable preallocation routine is used, this function does not need to be called.
828: See the Performance chapter of the PETSc users manual for how to preallocate matrices
830: Level: beginner
832: .keywords: Mat, setup
834: .seealso: MatCreate(), MatDestroy()
835: @*/
836: PetscErrorCode MatSetUp(Mat A)
837: {
838: PetscMPIInt size;
843: if (!((PetscObject)A)->type_name) {
844: MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
845: if (size == 1) {
846: MatSetType(A, MATSEQAIJ);
847: } else {
848: MatSetType(A, MATMPIAIJ);
849: }
850: }
851: if (!A->preallocated && A->ops->setup) {
852: PetscInfo(A,"Warning not preallocating matrix storage\n");
853: (*A->ops->setup)(A);
854: }
855: PetscLayoutSetUp(A->rmap);
856: PetscLayoutSetUp(A->cmap);
857: A->preallocated = PETSC_TRUE;
858: return(0);
859: }
861: #if defined(PETSC_HAVE_SAWS)
862: #include <petscviewersaws.h>
863: #endif
864: /*@C
865: MatView - Visualizes a matrix object.
867: Collective on Mat
869: Input Parameters:
870: + mat - the matrix
871: - viewer - visualization context
873: Notes:
874: The available visualization contexts include
875: + PETSC_VIEWER_STDOUT_SELF - for sequential matrices
876: . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
877: . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
878: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
880: The user can open alternative visualization contexts with
881: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
882: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
883: specified file; corresponding input uses MatLoad()
884: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
885: an X window display
886: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
887: Currently only the sequential dense and AIJ
888: matrix types support the Socket viewer.
890: The user can call PetscViewerPushFormat() to specify the output
891: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
892: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
893: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
894: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
895: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
896: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
897: format common among all matrix types
898: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
899: format (which is in many cases the same as the default)
900: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
901: size and structure (not the matrix entries)
902: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
903: the matrix structure
905: Options Database Keys:
906: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
907: . -mat_view ::ascii_info_detail - Prints more detailed info
908: . -mat_view - Prints matrix in ASCII format
909: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
910: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
911: . -display <name> - Sets display name (default is host)
912: . -draw_pause <sec> - Sets number of seconds to pause after display
913: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 12 Using MATLAB with PETSc for details)
914: . -viewer_socket_machine <machine> -
915: . -viewer_socket_port <port> -
916: . -mat_view binary - save matrix to file in binary format
917: - -viewer_binary_filename <name> -
918: Level: beginner
920: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
921: viewer is used.
923: See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
924: viewer is used.
926: One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
927: And then use the following mouse functions:
928: left mouse: zoom in
929: middle mouse: zoom out
930: right mouse: continue with the simulation
932: Concepts: matrices^viewing
933: Concepts: matrices^plotting
934: Concepts: matrices^printing
936: .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
937: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
938: @*/
939: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
940: {
941: PetscErrorCode ierr;
942: PetscInt rows,cols,rbs,cbs;
943: PetscBool iascii,ibinary;
944: PetscViewerFormat format;
945: PetscMPIInt size;
946: #if defined(PETSC_HAVE_SAWS)
947: PetscBool issaws;
948: #endif
953: if (!viewer) {
954: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
955: }
958: MatCheckPreallocated(mat,1);
959: PetscViewerGetFormat(viewer,&format);
960: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
961: if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) return(0);
962: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
963: if (ibinary) {
964: PetscBool mpiio;
965: PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
966: if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
967: }
969: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
970: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
971: if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
972: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
973: }
975: #if defined(PETSC_HAVE_SAWS)
976: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
977: #endif
978: if (iascii) {
979: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
980: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
981: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
982: PetscViewerASCIIPushTab(viewer);
983: MatGetSize(mat,&rows,&cols);
984: MatGetBlockSizes(mat,&rbs,&cbs);
985: if (rbs != 1 || cbs != 1) {
986: if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
987: else {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
988: } else {
989: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
990: }
991: if (mat->factortype) {
992: const MatSolverPackage solver;
993: MatFactorGetSolverPackage(mat,&solver);
994: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
995: }
996: if (mat->ops->getinfo) {
997: MatInfo info;
998: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
999: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
1000: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
1001: }
1002: if (mat->nullsp) {PetscViewerASCIIPrintf(viewer," has attached null space\n");}
1003: if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer," has attached near null space\n");}
1004: }
1005: #if defined(PETSC_HAVE_SAWS)
1006: } else if (issaws) {
1007: PetscMPIInt rank;
1009: PetscObjectName((PetscObject)mat);
1010: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
1011: if (!((PetscObject)mat)->amsmem && !rank) {
1012: PetscObjectViewSAWs((PetscObject)mat,viewer);
1013: }
1014: #endif
1015: }
1016: if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1017: PetscViewerASCIIPushTab(viewer);
1018: (*mat->ops->viewnative)(mat,viewer);
1019: PetscViewerASCIIPopTab(viewer);
1020: } else if (mat->ops->view) {
1021: PetscViewerASCIIPushTab(viewer);
1022: (*mat->ops->view)(mat,viewer);
1023: PetscViewerASCIIPopTab(viewer);
1024: }
1025: if (iascii) {
1026: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1027: PetscViewerGetFormat(viewer,&format);
1028: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1029: PetscViewerASCIIPopTab(viewer);
1030: }
1031: }
1032: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
1033: return(0);
1034: }
1036: #if defined(PETSC_USE_DEBUG)
1037: #include <../src/sys/totalview/tv_data_display.h>
1038: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1039: {
1040: TV_add_row("Local rows", "int", &mat->rmap->n);
1041: TV_add_row("Local columns", "int", &mat->cmap->n);
1042: TV_add_row("Global rows", "int", &mat->rmap->N);
1043: TV_add_row("Global columns", "int", &mat->cmap->N);
1044: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1045: return TV_format_OK;
1046: }
1047: #endif
1049: /*@C
1050: MatLoad - Loads a matrix that has been stored in binary format
1051: with MatView(). The matrix format is determined from the options database.
1052: Generates a parallel MPI matrix if the communicator has more than one
1053: processor. The default matrix type is AIJ.
1055: Collective on PetscViewer
1057: Input Parameters:
1058: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1059: or some related function before a call to MatLoad()
1060: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
1062: Options Database Keys:
1063: Used with block matrix formats (MATSEQBAIJ, ...) to specify
1064: block size
1065: . -matload_block_size <bs>
1067: Level: beginner
1069: Notes:
1070: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1071: Mat before calling this routine if you wish to set it from the options database.
1073: MatLoad() automatically loads into the options database any options
1074: given in the file filename.info where filename is the name of the file
1075: that was passed to the PetscViewerBinaryOpen(). The options in the info
1076: file will be ignored if you use the -viewer_binary_skip_info option.
1078: If the type or size of newmat is not set before a call to MatLoad, PETSc
1079: sets the default matrix type AIJ and sets the local and global sizes.
1080: If type and/or size is already set, then the same are used.
1082: In parallel, each processor can load a subset of rows (or the
1083: entire matrix). This routine is especially useful when a large
1084: matrix is stored on disk and only part of it is desired on each
1085: processor. For example, a parallel solver may access only some of
1086: the rows from each processor. The algorithm used here reads
1087: relatively small blocks of data rather than reading the entire
1088: matrix and then subsetting it.
1090: Notes for advanced users:
1091: Most users should not need to know the details of the binary storage
1092: format, since MatLoad() and MatView() completely hide these details.
1093: But for anyone who's interested, the standard binary matrix storage
1094: format is
1096: $ int MAT_FILE_CLASSID
1097: $ int number of rows
1098: $ int number of columns
1099: $ int total number of nonzeros
1100: $ int *number nonzeros in each row
1101: $ int *column indices of all nonzeros (starting index is zero)
1102: $ PetscScalar *values of all nonzeros
1104: PETSc automatically does the byte swapping for
1105: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
1106: linux, Windows and the paragon; thus if you write your own binary
1107: read/write routines you have to swap the bytes; see PetscBinaryRead()
1108: and PetscBinaryWrite() to see how this may be done.
1110: .keywords: matrix, load, binary, input
1112: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
1114: @*/
1115: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1116: {
1118: PetscBool isbinary,flg;
1123: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
1124: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1126: if (!((PetscObject)newmat)->type_name) {
1127: MatSetType(newmat,MATAIJ);
1128: }
1130: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1131: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1132: (*newmat->ops->load)(newmat,viewer);
1133: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
1135: flg = PETSC_FALSE;
1136: PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1137: if (flg) {
1138: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1139: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1140: }
1141: flg = PETSC_FALSE;
1142: PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1143: if (flg) {
1144: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1145: }
1146: return(0);
1147: }
1149: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1150: {
1152: Mat_Redundant *redund = *redundant;
1153: PetscInt i;
1156: if (redund){
1157: if (redund->matseq) { /* via MatCreateSubMatrices() */
1158: ISDestroy(&redund->isrow);
1159: ISDestroy(&redund->iscol);
1160: MatDestroySubMatrices(1,&redund->matseq);
1161: } else {
1162: PetscFree2(redund->send_rank,redund->recv_rank);
1163: PetscFree(redund->sbuf_j);
1164: PetscFree(redund->sbuf_a);
1165: for (i=0; i<redund->nrecvs; i++) {
1166: PetscFree(redund->rbuf_j[i]);
1167: PetscFree(redund->rbuf_a[i]);
1168: }
1169: PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1170: }
1172: if (redund->subcomm) {
1173: PetscCommDestroy(&redund->subcomm);
1174: }
1175: PetscFree(redund);
1176: }
1177: return(0);
1178: }
1180: /*@
1181: MatDestroy - Frees space taken by a matrix.
1183: Collective on Mat
1185: Input Parameter:
1186: . A - the matrix
1188: Level: beginner
1190: @*/
1191: PetscErrorCode MatDestroy(Mat *A)
1192: {
1196: if (!*A) return(0);
1198: if (--((PetscObject)(*A))->refct > 0) {*A = NULL; return(0);}
1200: /* if memory was published with SAWs then destroy it */
1201: PetscObjectSAWsViewOff((PetscObject)*A);
1202: if ((*A)->ops->destroy) {
1203: (*(*A)->ops->destroy)(*A);
1204: }
1206: PetscFree((*A)->solvertype);
1207: MatDestroy_Redundant(&(*A)->redundant);
1208: MatNullSpaceDestroy(&(*A)->nullsp);
1209: MatNullSpaceDestroy(&(*A)->transnullsp);
1210: MatNullSpaceDestroy(&(*A)->nearnullsp);
1211: MatDestroy(&(*A)->schur);
1212: PetscLayoutDestroy(&(*A)->rmap);
1213: PetscLayoutDestroy(&(*A)->cmap);
1214: PetscHeaderDestroy(A);
1215: return(0);
1216: }
1218: /*@C
1219: MatSetValues - Inserts or adds a block of values into a matrix.
1220: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1221: MUST be called after all calls to MatSetValues() have been completed.
1223: Not Collective
1225: Input Parameters:
1226: + mat - the matrix
1227: . v - a logically two-dimensional array of values
1228: . m, idxm - the number of rows and their global indices
1229: . n, idxn - the number of columns and their global indices
1230: - addv - either ADD_VALUES or INSERT_VALUES, where
1231: ADD_VALUES adds values to any existing entries, and
1232: INSERT_VALUES replaces existing entries with new values
1234: Notes:
1235: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1236: MatSetUp() before using this routine
1238: By default the values, v, are row-oriented. See MatSetOption() for other options.
1240: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1241: options cannot be mixed without intervening calls to the assembly
1242: routines.
1244: MatSetValues() uses 0-based row and column numbers in Fortran
1245: as well as in C.
1247: Negative indices may be passed in idxm and idxn, these rows and columns are
1248: simply ignored. This allows easily inserting element stiffness matrices
1249: with homogeneous Dirchlet boundary conditions that you don't want represented
1250: in the matrix.
1252: Efficiency Alert:
1253: The routine MatSetValuesBlocked() may offer much better efficiency
1254: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1256: Level: beginner
1258: Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
1259: because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1261: Concepts: matrices^putting entries in
1263: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1264: InsertMode, INSERT_VALUES, ADD_VALUES
1265: @*/
1266: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1267: {
1269: #if defined(PETSC_USE_DEBUG)
1270: PetscInt i,j;
1271: #endif
1276: if (!m || !n) return(0); /* no values to insert */
1280: MatCheckPreallocated(mat,1);
1281: if (mat->insertmode == NOT_SET_VALUES) {
1282: mat->insertmode = addv;
1283: }
1284: #if defined(PETSC_USE_DEBUG)
1285: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1286: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1287: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1289: for (i=0; i<m; i++) {
1290: for (j=0; j<n; j++) {
1291: if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1292: #if defined(PETSC_USE_COMPLEX)
1293: 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]);
1294: #else
1295: SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1296: #endif
1297: }
1298: }
1299: #endif
1301: if (mat->assembled) {
1302: mat->was_assembled = PETSC_TRUE;
1303: mat->assembled = PETSC_FALSE;
1304: }
1305: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1306: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1307: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1308: #if defined(PETSC_HAVE_CUSP)
1309: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1310: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1311: }
1312: #elif defined(PETSC_HAVE_VIENNACL)
1313: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1314: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1315: }
1316: #elif defined(PETSC_HAVE_VECCUDA)
1317: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1318: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1319: }
1320: #endif
1321: return(0);
1322: }
1325: /*@
1326: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1327: values into a matrix
1329: Not Collective
1331: Input Parameters:
1332: + mat - the matrix
1333: . row - the (block) row to set
1334: - v - a logically two-dimensional array of values
1336: Notes:
1337: By the values, v, are column-oriented (for the block version) and sorted
1339: All the nonzeros in the row must be provided
1341: The matrix must have previously had its column indices set
1343: The row must belong to this process
1345: Level: intermediate
1347: Concepts: matrices^putting entries in
1349: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1350: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1351: @*/
1352: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1353: {
1355: PetscInt globalrow;
1361: ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1362: MatSetValuesRow(mat,globalrow,v);
1363: #if defined(PETSC_HAVE_CUSP)
1364: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1365: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1366: }
1367: #elif defined(PETSC_HAVE_VIENNACL)
1368: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1369: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1370: }
1371: #elif defined(PETSC_HAVE_VECCUDA)
1372: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1373: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1374: }
1375: #endif
1376: return(0);
1377: }
1379: /*@
1380: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1381: values into a matrix
1383: Not Collective
1385: Input Parameters:
1386: + mat - the matrix
1387: . row - the (block) row to set
1388: - 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
1390: Notes:
1391: The values, v, are column-oriented for the block version.
1393: All the nonzeros in the row must be provided
1395: THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1397: The row must belong to this process
1399: Level: advanced
1401: Concepts: matrices^putting entries in
1403: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1404: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1405: @*/
1406: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1407: {
1413: MatCheckPreallocated(mat,1);
1415: #if defined(PETSC_USE_DEBUG)
1416: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1417: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1418: #endif
1419: mat->insertmode = INSERT_VALUES;
1421: if (mat->assembled) {
1422: mat->was_assembled = PETSC_TRUE;
1423: mat->assembled = PETSC_FALSE;
1424: }
1425: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1426: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1427: (*mat->ops->setvaluesrow)(mat,row,v);
1428: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1429: #if defined(PETSC_HAVE_CUSP)
1430: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1431: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1432: }
1433: #elif defined(PETSC_HAVE_VIENNACL)
1434: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1435: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1436: }
1437: #elif defined(PETSC_HAVE_VECCUDA)
1438: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1439: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1440: }
1441: #endif
1442: return(0);
1443: }
1445: /*@
1446: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1447: Using structured grid indexing
1449: Not Collective
1451: Input Parameters:
1452: + mat - the matrix
1453: . m - number of rows being entered
1454: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1455: . n - number of columns being entered
1456: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1457: . v - a logically two-dimensional array of values
1458: - addv - either ADD_VALUES or INSERT_VALUES, where
1459: ADD_VALUES adds values to any existing entries, and
1460: INSERT_VALUES replaces existing entries with new values
1462: Notes:
1463: By default the values, v, are row-oriented. See MatSetOption() for other options.
1465: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1466: options cannot be mixed without intervening calls to the assembly
1467: routines.
1469: The grid coordinates are across the entire grid, not just the local portion
1471: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1472: as well as in C.
1474: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1476: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1477: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1479: The columns and rows in the stencil passed in MUST be contained within the
1480: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1481: if you create a DMDA with an overlap of one grid level and on a particular process its first
1482: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1483: first i index you can use in your column and row indices in MatSetStencil() is 5.
1485: In Fortran idxm and idxn should be declared as
1486: $ MatStencil idxm(4,m),idxn(4,n)
1487: and the values inserted using
1488: $ idxm(MatStencil_i,1) = i
1489: $ idxm(MatStencil_j,1) = j
1490: $ idxm(MatStencil_k,1) = k
1491: $ idxm(MatStencil_c,1) = c
1492: etc
1494: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1495: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1496: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1497: DM_BOUNDARY_PERIODIC boundary type.
1499: 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
1500: a single value per point) you can skip filling those indices.
1502: Inspired by the structured grid interface to the HYPRE package
1503: (http://www.llnl.gov/CASC/hypre)
1505: Efficiency Alert:
1506: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1507: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1509: Level: beginner
1511: Concepts: matrices^putting entries in
1513: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1514: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1515: @*/
1516: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1517: {
1519: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1520: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1521: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1524: if (!m || !n) return(0); /* no values to insert */
1531: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1532: jdxm = buf; jdxn = buf+m;
1533: } else {
1534: PetscMalloc2(m,&bufm,n,&bufn);
1535: jdxm = bufm; jdxn = bufn;
1536: }
1537: for (i=0; i<m; i++) {
1538: for (j=0; j<3-sdim; j++) dxm++;
1539: tmp = *dxm++ - starts[0];
1540: for (j=0; j<dim-1; j++) {
1541: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1542: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1543: }
1544: if (mat->stencil.noc) dxm++;
1545: jdxm[i] = tmp;
1546: }
1547: for (i=0; i<n; i++) {
1548: for (j=0; j<3-sdim; j++) dxn++;
1549: tmp = *dxn++ - starts[0];
1550: for (j=0; j<dim-1; j++) {
1551: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1552: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1553: }
1554: if (mat->stencil.noc) dxn++;
1555: jdxn[i] = tmp;
1556: }
1557: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1558: PetscFree2(bufm,bufn);
1559: return(0);
1560: }
1562: /*@
1563: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1564: Using structured grid indexing
1566: Not Collective
1568: Input Parameters:
1569: + mat - the matrix
1570: . m - number of rows being entered
1571: . idxm - grid coordinates for matrix rows being entered
1572: . n - number of columns being entered
1573: . idxn - grid coordinates for matrix columns being entered
1574: . v - a logically two-dimensional array of values
1575: - addv - either ADD_VALUES or INSERT_VALUES, where
1576: ADD_VALUES adds values to any existing entries, and
1577: INSERT_VALUES replaces existing entries with new values
1579: Notes:
1580: By default the values, v, are row-oriented and unsorted.
1581: See MatSetOption() for other options.
1583: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1584: options cannot be mixed without intervening calls to the assembly
1585: routines.
1587: The grid coordinates are across the entire grid, not just the local portion
1589: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1590: as well as in C.
1592: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1594: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1595: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1597: The columns and rows in the stencil passed in MUST be contained within the
1598: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1599: if you create a DMDA with an overlap of one grid level and on a particular process its first
1600: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1601: first i index you can use in your column and row indices in MatSetStencil() is 5.
1603: In Fortran idxm and idxn should be declared as
1604: $ MatStencil idxm(4,m),idxn(4,n)
1605: and the values inserted using
1606: $ idxm(MatStencil_i,1) = i
1607: $ idxm(MatStencil_j,1) = j
1608: $ idxm(MatStencil_k,1) = k
1609: etc
1611: Negative indices may be passed in idxm and idxn, these rows and columns are
1612: simply ignored. This allows easily inserting element stiffness matrices
1613: with homogeneous Dirchlet boundary conditions that you don't want represented
1614: in the matrix.
1616: Inspired by the structured grid interface to the HYPRE package
1617: (http://www.llnl.gov/CASC/hypre)
1619: Level: beginner
1621: Concepts: matrices^putting entries in
1623: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1624: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1625: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1626: @*/
1627: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1628: {
1630: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1631: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1632: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1635: if (!m || !n) return(0); /* no values to insert */
1642: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1643: jdxm = buf; jdxn = buf+m;
1644: } else {
1645: PetscMalloc2(m,&bufm,n,&bufn);
1646: jdxm = bufm; jdxn = bufn;
1647: }
1648: for (i=0; i<m; i++) {
1649: for (j=0; j<3-sdim; j++) dxm++;
1650: tmp = *dxm++ - starts[0];
1651: for (j=0; j<sdim-1; j++) {
1652: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1653: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1654: }
1655: dxm++;
1656: jdxm[i] = tmp;
1657: }
1658: for (i=0; i<n; i++) {
1659: for (j=0; j<3-sdim; j++) dxn++;
1660: tmp = *dxn++ - starts[0];
1661: for (j=0; j<sdim-1; j++) {
1662: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1663: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1664: }
1665: dxn++;
1666: jdxn[i] = tmp;
1667: }
1668: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1669: PetscFree2(bufm,bufn);
1670: #if defined(PETSC_HAVE_CUSP)
1671: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1672: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1673: }
1674: #elif defined(PETSC_HAVE_VIENNACL)
1675: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1676: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1677: }
1678: #elif defined(PETSC_HAVE_VECCUDA)
1679: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1680: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1681: }
1682: #endif
1683: return(0);
1684: }
1686: /*@
1687: MatSetStencil - Sets the grid information for setting values into a matrix via
1688: MatSetValuesStencil()
1690: Not Collective
1692: Input Parameters:
1693: + mat - the matrix
1694: . dim - dimension of the grid 1, 2, or 3
1695: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1696: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1697: - dof - number of degrees of freedom per node
1700: Inspired by the structured grid interface to the HYPRE package
1701: (www.llnl.gov/CASC/hyper)
1703: For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1704: user.
1706: Level: beginner
1708: Concepts: matrices^putting entries in
1710: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1711: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1712: @*/
1713: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1714: {
1715: PetscInt i;
1722: mat->stencil.dim = dim + (dof > 1);
1723: for (i=0; i<dim; i++) {
1724: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1725: mat->stencil.starts[i] = starts[dim-i-1];
1726: }
1727: mat->stencil.dims[dim] = dof;
1728: mat->stencil.starts[dim] = 0;
1729: mat->stencil.noc = (PetscBool)(dof == 1);
1730: return(0);
1731: }
1733: /*@C
1734: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1736: Not Collective
1738: Input Parameters:
1739: + mat - the matrix
1740: . v - a logically two-dimensional array of values
1741: . m, idxm - the number of block rows and their global block indices
1742: . n, idxn - the number of block columns and their global block indices
1743: - addv - either ADD_VALUES or INSERT_VALUES, where
1744: ADD_VALUES adds values to any existing entries, and
1745: INSERT_VALUES replaces existing entries with new values
1747: Notes:
1748: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1749: MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1751: The m and n count the NUMBER of blocks in the row direction and column direction,
1752: NOT the total number of rows/columns; for example, if the block size is 2 and
1753: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1754: The values in idxm would be 1 2; that is the first index for each block divided by
1755: the block size.
1757: Note that you must call MatSetBlockSize() when constructing this matrix (before
1758: preallocating it).
1760: By default the values, v, are row-oriented, so the layout of
1761: v is the same as for MatSetValues(). See MatSetOption() for other options.
1763: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1764: options cannot be mixed without intervening calls to the assembly
1765: routines.
1767: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1768: as well as in C.
1770: Negative indices may be passed in idxm and idxn, these rows and columns are
1771: simply ignored. This allows easily inserting element stiffness matrices
1772: with homogeneous Dirchlet boundary conditions that you don't want represented
1773: in the matrix.
1775: Each time an entry is set within a sparse matrix via MatSetValues(),
1776: internal searching must be done to determine where to place the
1777: data in the matrix storage space. By instead inserting blocks of
1778: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1779: reduced.
1781: Example:
1782: $ Suppose m=n=2 and block size(bs) = 2 The array is
1783: $
1784: $ 1 2 | 3 4
1785: $ 5 6 | 7 8
1786: $ - - - | - - -
1787: $ 9 10 | 11 12
1788: $ 13 14 | 15 16
1789: $
1790: $ v[] should be passed in like
1791: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1792: $
1793: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1794: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1796: Level: intermediate
1798: Concepts: matrices^putting entries in blocked
1800: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1801: @*/
1802: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1803: {
1809: if (!m || !n) return(0); /* no values to insert */
1813: MatCheckPreallocated(mat,1);
1814: if (mat->insertmode == NOT_SET_VALUES) {
1815: mat->insertmode = addv;
1816: }
1817: #if defined(PETSC_USE_DEBUG)
1818: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1819: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1820: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1821: #endif
1823: if (mat->assembled) {
1824: mat->was_assembled = PETSC_TRUE;
1825: mat->assembled = PETSC_FALSE;
1826: }
1827: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1828: if (mat->ops->setvaluesblocked) {
1829: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1830: } else {
1831: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1832: PetscInt i,j,bs,cbs;
1833: MatGetBlockSizes(mat,&bs,&cbs);
1834: if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1835: iidxm = buf; iidxn = buf + m*bs;
1836: } else {
1837: PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1838: iidxm = bufr; iidxn = bufc;
1839: }
1840: for (i=0; i<m; i++) {
1841: for (j=0; j<bs; j++) {
1842: iidxm[i*bs+j] = bs*idxm[i] + j;
1843: }
1844: }
1845: for (i=0; i<n; i++) {
1846: for (j=0; j<cbs; j++) {
1847: iidxn[i*cbs+j] = cbs*idxn[i] + j;
1848: }
1849: }
1850: MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1851: PetscFree2(bufr,bufc);
1852: }
1853: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1854: #if defined(PETSC_HAVE_CUSP)
1855: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1856: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1857: }
1858: #elif defined(PETSC_HAVE_VIENNACL)
1859: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1860: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1861: }
1862: #elif defined(PETSC_HAVE_VECCUDA)
1863: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1864: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1865: }
1866: #endif
1867: return(0);
1868: }
1870: /*@
1871: MatGetValues - Gets a block of values from a matrix.
1873: Not Collective; currently only returns a local block
1875: Input Parameters:
1876: + mat - the matrix
1877: . v - a logically two-dimensional array for storing the values
1878: . m, idxm - the number of rows and their global indices
1879: - n, idxn - the number of columns and their global indices
1881: Notes:
1882: The user must allocate space (m*n PetscScalars) for the values, v.
1883: The values, v, are then returned in a row-oriented format,
1884: analogous to that used by default in MatSetValues().
1886: MatGetValues() uses 0-based row and column numbers in
1887: Fortran as well as in C.
1889: MatGetValues() requires that the matrix has been assembled
1890: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1891: MatSetValues() and MatGetValues() CANNOT be made in succession
1892: without intermediate matrix assembly.
1894: Negative row or column indices will be ignored and those locations in v[] will be
1895: left unchanged.
1897: Level: advanced
1899: Concepts: matrices^accessing values
1901: .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1902: @*/
1903: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1904: {
1910: if (!m || !n) return(0);
1914: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1915: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1916: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1917: MatCheckPreallocated(mat,1);
1919: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1920: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1921: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1922: return(0);
1923: }
1925: /*@
1926: MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1927: the same size. Currently, this can only be called once and creates the given matrix.
1929: Not Collective
1931: Input Parameters:
1932: + mat - the matrix
1933: . nb - the number of blocks
1934: . bs - the number of rows (and columns) in each block
1935: . rows - a concatenation of the rows for each block
1936: - v - a concatenation of logically two-dimensional arrays of values
1938: Notes:
1939: In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1941: Level: advanced
1943: Concepts: matrices^putting entries in
1945: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1946: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1947: @*/
1948: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1949: {
1957: #if defined(PETSC_USE_DEBUG)
1958: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1959: #endif
1961: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1962: if (mat->ops->setvaluesbatch) {
1963: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1964: } else {
1965: PetscInt b;
1966: for (b = 0; b < nb; ++b) {
1967: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1968: }
1969: }
1970: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1971: return(0);
1972: }
1974: /*@
1975: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1976: the routine MatSetValuesLocal() to allow users to insert matrix entries
1977: using a local (per-processor) numbering.
1979: Not Collective
1981: Input Parameters:
1982: + x - the matrix
1983: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS()
1984: - cmapping - column mapping
1986: Level: intermediate
1988: Concepts: matrices^local to global mapping
1989: Concepts: local to global mapping^for matrices
1991: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1992: @*/
1993: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1994: {
2003: if (x->ops->setlocaltoglobalmapping) {
2004: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
2005: } else {
2006: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
2007: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
2008: }
2009: return(0);
2010: }
2013: /*@
2014: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2016: Not Collective
2018: Input Parameters:
2019: . A - the matrix
2021: Output Parameters:
2022: + rmapping - row mapping
2023: - cmapping - column mapping
2025: Level: advanced
2027: Concepts: matrices^local to global mapping
2028: Concepts: local to global mapping^for matrices
2030: .seealso: MatSetValuesLocal()
2031: @*/
2032: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2033: {
2039: if (rmapping) *rmapping = A->rmap->mapping;
2040: if (cmapping) *cmapping = A->cmap->mapping;
2041: return(0);
2042: }
2044: /*@
2045: MatGetLayouts - Gets the PetscLayout objects for rows and columns
2047: Not Collective
2049: Input Parameters:
2050: . A - the matrix
2052: Output Parameters:
2053: + rmap - row layout
2054: - cmap - column layout
2056: Level: advanced
2058: .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping()
2059: @*/
2060: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2061: {
2067: if (rmap) *rmap = A->rmap;
2068: if (cmap) *cmap = A->cmap;
2069: return(0);
2070: }
2072: /*@C
2073: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2074: using a local ordering of the nodes.
2076: Not Collective
2078: Input Parameters:
2079: + mat - the matrix
2080: . nrow, irow - number of rows and their local indices
2081: . ncol, icol - number of columns and their local indices
2082: . y - a logically two-dimensional array of values
2083: - addv - either INSERT_VALUES or ADD_VALUES, where
2084: ADD_VALUES adds values to any existing entries, and
2085: INSERT_VALUES replaces existing entries with new values
2087: Notes:
2088: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2089: MatSetUp() before using this routine
2091: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2093: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2094: options cannot be mixed without intervening calls to the assembly
2095: routines.
2097: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2098: MUST be called after all calls to MatSetValuesLocal() have been completed.
2100: Level: intermediate
2102: Concepts: matrices^putting entries in with local numbering
2104: Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
2105: because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2107: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2108: MatSetValueLocal()
2109: @*/
2110: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2111: {
2117: MatCheckPreallocated(mat,1);
2118: if (!nrow || !ncol) return(0); /* no values to insert */
2122: if (mat->insertmode == NOT_SET_VALUES) {
2123: mat->insertmode = addv;
2124: }
2125: #if defined(PETSC_USE_DEBUG)
2126: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2127: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2128: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2129: #endif
2131: if (mat->assembled) {
2132: mat->was_assembled = PETSC_TRUE;
2133: mat->assembled = PETSC_FALSE;
2134: }
2135: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2136: if (mat->ops->setvalueslocal) {
2137: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
2138: } else {
2139: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2140: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2141: irowm = buf; icolm = buf+nrow;
2142: } else {
2143: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2144: irowm = bufr; icolm = bufc;
2145: }
2146: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
2147: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
2148: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
2149: PetscFree2(bufr,bufc);
2150: }
2151: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2152: #if defined(PETSC_HAVE_CUSP)
2153: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2154: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2155: }
2156: #elif defined(PETSC_HAVE_VIENNACL)
2157: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2158: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2159: }
2160: #elif defined(PETSC_HAVE_VECCUDA)
2161: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2162: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2163: }
2164: #endif
2165: return(0);
2166: }
2168: /*@C
2169: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2170: using a local ordering of the nodes a block at a time.
2172: Not Collective
2174: Input Parameters:
2175: + x - the matrix
2176: . nrow, irow - number of rows and their local indices
2177: . ncol, icol - number of columns and their local indices
2178: . y - a logically two-dimensional array of values
2179: - addv - either INSERT_VALUES or ADD_VALUES, where
2180: ADD_VALUES adds values to any existing entries, and
2181: INSERT_VALUES replaces existing entries with new values
2183: Notes:
2184: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2185: MatSetUp() before using this routine
2187: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2188: before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2190: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2191: options cannot be mixed without intervening calls to the assembly
2192: routines.
2194: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2195: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2197: Level: intermediate
2199: Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
2200: because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2202: Concepts: matrices^putting blocked values in with local numbering
2204: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2205: MatSetValuesLocal(), MatSetValuesBlocked()
2206: @*/
2207: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2208: {
2214: MatCheckPreallocated(mat,1);
2215: if (!nrow || !ncol) return(0); /* no values to insert */
2219: if (mat->insertmode == NOT_SET_VALUES) {
2220: mat->insertmode = addv;
2221: }
2222: #if defined(PETSC_USE_DEBUG)
2223: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2224: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2225: 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);
2226: #endif
2228: if (mat->assembled) {
2229: mat->was_assembled = PETSC_TRUE;
2230: mat->assembled = PETSC_FALSE;
2231: }
2232: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2233: if (mat->ops->setvaluesblockedlocal) {
2234: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2235: } else {
2236: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2237: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2238: irowm = buf; icolm = buf + nrow;
2239: } else {
2240: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2241: irowm = bufr; icolm = bufc;
2242: }
2243: ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2244: ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2245: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2246: PetscFree2(bufr,bufc);
2247: }
2248: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2249: #if defined(PETSC_HAVE_CUSP)
2250: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2251: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2252: }
2253: #elif defined(PETSC_HAVE_VIENNACL)
2254: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2255: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2256: }
2257: #elif defined(PETSC_HAVE_VECCUDA)
2258: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2259: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2260: }
2261: #endif
2262: return(0);
2263: }
2265: /*@
2266: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2268: Collective on Mat and Vec
2270: Input Parameters:
2271: + mat - the matrix
2272: - x - the vector to be multiplied
2274: Output Parameters:
2275: . y - the result
2277: Notes:
2278: The vectors x and y cannot be the same. I.e., one cannot
2279: call MatMult(A,y,y).
2281: Level: developer
2283: Concepts: matrix-vector product
2285: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2286: @*/
2287: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2288: {
2297: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2298: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2299: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2300: MatCheckPreallocated(mat,1);
2302: if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2303: (*mat->ops->multdiagonalblock)(mat,x,y);
2304: PetscObjectStateIncrease((PetscObject)y);
2305: return(0);
2306: }
2308: /* --------------------------------------------------------*/
2309: /*@
2310: MatMult - Computes the matrix-vector product, y = Ax.
2312: Neighbor-wise Collective on Mat and Vec
2314: Input Parameters:
2315: + mat - the matrix
2316: - x - the vector to be multiplied
2318: Output Parameters:
2319: . y - the result
2321: Notes:
2322: The vectors x and y cannot be the same. I.e., one cannot
2323: call MatMult(A,y,y).
2325: Level: beginner
2327: Concepts: matrix-vector product
2329: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2330: @*/
2331: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2332: {
2340: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2341: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2342: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2343: #if !defined(PETSC_HAVE_CONSTRAINTS)
2344: 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);
2345: 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);
2346: 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);
2347: #endif
2348: VecLocked(y,3);
2349: if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2350: MatCheckPreallocated(mat,1);
2352: VecLockPush(x);
2353: if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2354: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2355: (*mat->ops->mult)(mat,x,y);
2356: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2357: if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2358: VecLockPop(x);
2359: return(0);
2360: }
2362: /*@
2363: MatMultTranspose - Computes matrix transpose times a vector.
2365: Neighbor-wise Collective on Mat and Vec
2367: Input Parameters:
2368: + mat - the matrix
2369: - x - the vector to be multilplied
2371: Output Parameters:
2372: . y - the result
2374: Notes:
2375: The vectors x and y cannot be the same. I.e., one cannot
2376: call MatMultTranspose(A,y,y).
2378: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2379: use MatMultHermitianTranspose()
2381: Level: beginner
2383: Concepts: matrix vector product^transpose
2385: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2386: @*/
2387: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2388: {
2397: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2398: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2399: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2400: #if !defined(PETSC_HAVE_CONSTRAINTS)
2401: 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);
2402: 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);
2403: #endif
2404: if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2405: MatCheckPreallocated(mat,1);
2407: if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2408: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2409: VecLockPush(x);
2410: (*mat->ops->multtranspose)(mat,x,y);
2411: VecLockPop(x);
2412: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2413: PetscObjectStateIncrease((PetscObject)y);
2414: if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2415: return(0);
2416: }
2418: /*@
2419: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2421: Neighbor-wise Collective on Mat and Vec
2423: Input Parameters:
2424: + mat - the matrix
2425: - x - the vector to be multilplied
2427: Output Parameters:
2428: . y - the result
2430: Notes:
2431: The vectors x and y cannot be the same. I.e., one cannot
2432: call MatMultHermitianTranspose(A,y,y).
2434: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2436: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2438: Level: beginner
2440: Concepts: matrix vector product^transpose
2442: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2443: @*/
2444: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2445: {
2447: Vec w;
2455: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2456: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2457: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2458: #if !defined(PETSC_HAVE_CONSTRAINTS)
2459: 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);
2460: 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);
2461: #endif
2462: MatCheckPreallocated(mat,1);
2464: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2465: if (mat->ops->multhermitiantranspose) {
2466: VecLockPush(x);
2467: (*mat->ops->multhermitiantranspose)(mat,x,y);
2468: VecLockPop(x);
2469: } else {
2470: VecDuplicate(x,&w);
2471: VecCopy(x,w);
2472: VecConjugate(w);
2473: MatMultTranspose(mat,w,y);
2474: VecDestroy(&w);
2475: VecConjugate(y);
2476: }
2477: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2478: PetscObjectStateIncrease((PetscObject)y);
2479: return(0);
2480: }
2482: /*@
2483: MatMultAdd - Computes v3 = v2 + A * v1.
2485: Neighbor-wise Collective on Mat and Vec
2487: Input Parameters:
2488: + mat - the matrix
2489: - v1, v2 - the vectors
2491: Output Parameters:
2492: . v3 - the result
2494: Notes:
2495: The vectors v1 and v3 cannot be the same. I.e., one cannot
2496: call MatMultAdd(A,v1,v2,v1).
2498: Level: beginner
2500: Concepts: matrix vector product^addition
2502: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2503: @*/
2504: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2505: {
2515: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2516: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2517: 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);
2518: /* 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);
2519: 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); */
2520: 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);
2521: 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);
2522: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2523: MatCheckPreallocated(mat,1);
2525: if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2526: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2527: VecLockPush(v1);
2528: (*mat->ops->multadd)(mat,v1,v2,v3);
2529: VecLockPop(v1);
2530: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2531: PetscObjectStateIncrease((PetscObject)v3);
2532: return(0);
2533: }
2535: /*@
2536: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2538: Neighbor-wise Collective on Mat and Vec
2540: Input Parameters:
2541: + mat - the matrix
2542: - v1, v2 - the vectors
2544: Output Parameters:
2545: . v3 - the result
2547: Notes:
2548: The vectors v1 and v3 cannot be the same. I.e., one cannot
2549: call MatMultTransposeAdd(A,v1,v2,v1).
2551: Level: beginner
2553: Concepts: matrix vector product^transpose and addition
2555: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2556: @*/
2557: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2558: {
2568: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2569: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2570: if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2571: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2572: 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);
2573: 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);
2574: 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);
2575: MatCheckPreallocated(mat,1);
2577: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2578: VecLockPush(v1);
2579: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2580: VecLockPop(v1);
2581: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2582: PetscObjectStateIncrease((PetscObject)v3);
2583: return(0);
2584: }
2586: /*@
2587: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2589: Neighbor-wise Collective on Mat and Vec
2591: Input Parameters:
2592: + mat - the matrix
2593: - v1, v2 - the vectors
2595: Output Parameters:
2596: . v3 - the result
2598: Notes:
2599: The vectors v1 and v3 cannot be the same. I.e., one cannot
2600: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2602: Level: beginner
2604: Concepts: matrix vector product^transpose and addition
2606: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2607: @*/
2608: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2609: {
2619: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2620: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2621: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2622: 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);
2623: 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);
2624: 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);
2625: MatCheckPreallocated(mat,1);
2627: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2628: VecLockPush(v1);
2629: if (mat->ops->multhermitiantransposeadd) {
2630: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2631: } else {
2632: Vec w,z;
2633: VecDuplicate(v1,&w);
2634: VecCopy(v1,w);
2635: VecConjugate(w);
2636: VecDuplicate(v3,&z);
2637: MatMultTranspose(mat,w,z);
2638: VecDestroy(&w);
2639: VecConjugate(z);
2640: VecWAXPY(v3,1.0,v2,z);
2641: VecDestroy(&z);
2642: }
2643: VecLockPop(v1);
2644: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2645: PetscObjectStateIncrease((PetscObject)v3);
2646: return(0);
2647: }
2649: /*@
2650: MatMultConstrained - The inner multiplication routine for a
2651: constrained matrix P^T A P.
2653: Neighbor-wise Collective on Mat and Vec
2655: Input Parameters:
2656: + mat - the matrix
2657: - x - the vector to be multilplied
2659: Output Parameters:
2660: . y - the result
2662: Notes:
2663: The vectors x and y cannot be the same. I.e., one cannot
2664: call MatMult(A,y,y).
2666: Level: beginner
2668: .keywords: matrix, multiply, matrix-vector product, constraint
2669: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2670: @*/
2671: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2672: {
2679: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2680: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2681: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2682: 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);
2683: 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);
2684: 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);
2686: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2687: VecLockPush(x);
2688: (*mat->ops->multconstrained)(mat,x,y);
2689: VecLockPop(x);
2690: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2691: PetscObjectStateIncrease((PetscObject)y);
2692: return(0);
2693: }
2695: /*@
2696: MatMultTransposeConstrained - The inner multiplication routine for a
2697: constrained matrix P^T A^T P.
2699: Neighbor-wise Collective on Mat and Vec
2701: Input Parameters:
2702: + mat - the matrix
2703: - x - the vector to be multilplied
2705: Output Parameters:
2706: . y - the result
2708: Notes:
2709: The vectors x and y cannot be the same. I.e., one cannot
2710: call MatMult(A,y,y).
2712: Level: beginner
2714: .keywords: matrix, multiply, matrix-vector product, constraint
2715: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2716: @*/
2717: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2718: {
2725: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2726: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2727: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2728: 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);
2729: 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);
2731: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2732: (*mat->ops->multtransposeconstrained)(mat,x,y);
2733: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2734: PetscObjectStateIncrease((PetscObject)y);
2735: return(0);
2736: }
2738: /*@C
2739: MatGetFactorType - gets the type of factorization it is
2741: Note Collective
2742: as the flag
2744: Input Parameters:
2745: . mat - the matrix
2747: Output Parameters:
2748: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2750: Level: intermediate
2752: .seealso: MatFactorType, MatGetFactor()
2753: @*/
2754: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2755: {
2759: *t = mat->factortype;
2760: return(0);
2761: }
2763: /* ------------------------------------------------------------*/
2764: /*@C
2765: MatGetInfo - Returns information about matrix storage (number of
2766: nonzeros, memory, etc.).
2768: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2770: Input Parameters:
2771: . mat - the matrix
2773: Output Parameters:
2774: + flag - flag indicating the type of parameters to be returned
2775: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2776: MAT_GLOBAL_SUM - sum over all processors)
2777: - info - matrix information context
2779: Notes:
2780: The MatInfo context contains a variety of matrix data, including
2781: number of nonzeros allocated and used, number of mallocs during
2782: matrix assembly, etc. Additional information for factored matrices
2783: is provided (such as the fill ratio, number of mallocs during
2784: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2785: when using the runtime options
2786: $ -info -mat_view ::ascii_info
2788: Example for C/C++ Users:
2789: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2790: data within the MatInfo context. For example,
2791: .vb
2792: MatInfo info;
2793: Mat A;
2794: double mal, nz_a, nz_u;
2796: MatGetInfo(A,MAT_LOCAL,&info);
2797: mal = info.mallocs;
2798: nz_a = info.nz_allocated;
2799: .ve
2801: Example for Fortran Users:
2802: Fortran users should declare info as a double precision
2803: array of dimension MAT_INFO_SIZE, and then extract the parameters
2804: of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2805: a complete list of parameter names.
2806: .vb
2807: double precision info(MAT_INFO_SIZE)
2808: double precision mal, nz_a
2809: Mat A
2810: integer ierr
2812: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2813: mal = info(MAT_INFO_MALLOCS)
2814: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2815: .ve
2817: Level: intermediate
2819: Concepts: matrices^getting information on
2821: Developer Note: fortran interface is not autogenerated as the f90
2822: interface defintion cannot be generated correctly [due to MatInfo]
2824: .seealso: MatStashGetInfo()
2826: @*/
2827: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2828: {
2835: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2836: MatCheckPreallocated(mat,1);
2837: (*mat->ops->getinfo)(mat,flag,info);
2838: return(0);
2839: }
2841: /*
2842: This is used by external packages where it is not easy to get the info from the actual
2843: matrix factorization.
2844: */
2845: PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2846: {
2850: PetscMemzero(info,sizeof(MatInfo));
2851: return(0);
2852: }
2854: /* ----------------------------------------------------------*/
2856: /*@C
2857: MatLUFactor - Performs in-place LU factorization of matrix.
2859: Collective on Mat
2861: Input Parameters:
2862: + mat - the matrix
2863: . row - row permutation
2864: . col - column permutation
2865: - info - options for factorization, includes
2866: $ fill - expected fill as ratio of original fill.
2867: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2868: $ Run with the option -info to determine an optimal value to use
2870: Notes:
2871: Most users should employ the simplified KSP interface for linear solvers
2872: instead of working directly with matrix algebra routines such as this.
2873: See, e.g., KSPCreate().
2875: This changes the state of the matrix to a factored matrix; it cannot be used
2876: for example with MatSetValues() unless one first calls MatSetUnfactored().
2878: Level: developer
2880: Concepts: matrices^LU factorization
2882: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2883: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2885: Developer Note: fortran interface is not autogenerated as the f90
2886: interface defintion cannot be generated correctly [due to MatFactorInfo]
2888: @*/
2889: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2890: {
2892: MatFactorInfo tinfo;
2900: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2901: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2902: if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2903: MatCheckPreallocated(mat,1);
2904: if (!info) {
2905: MatFactorInfoInitialize(&tinfo);
2906: info = &tinfo;
2907: }
2909: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2910: (*mat->ops->lufactor)(mat,row,col,info);
2911: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2912: PetscObjectStateIncrease((PetscObject)mat);
2913: return(0);
2914: }
2916: /*@C
2917: MatILUFactor - Performs in-place ILU factorization of matrix.
2919: Collective on Mat
2921: Input Parameters:
2922: + mat - the matrix
2923: . row - row permutation
2924: . col - column permutation
2925: - info - structure containing
2926: $ levels - number of levels of fill.
2927: $ expected fill - as ratio of original fill.
2928: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2929: missing diagonal entries)
2931: Notes:
2932: Probably really in-place only when level of fill is zero, otherwise allocates
2933: new space to store factored matrix and deletes previous memory.
2935: Most users should employ the simplified KSP interface for linear solvers
2936: instead of working directly with matrix algebra routines such as this.
2937: See, e.g., KSPCreate().
2939: Level: developer
2941: Concepts: matrices^ILU factorization
2943: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2945: Developer Note: fortran interface is not autogenerated as the f90
2946: interface defintion cannot be generated correctly [due to MatFactorInfo]
2948: @*/
2949: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2950: {
2959: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2960: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2961: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2962: if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2963: MatCheckPreallocated(mat,1);
2965: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2966: (*mat->ops->ilufactor)(mat,row,col,info);
2967: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2968: PetscObjectStateIncrease((PetscObject)mat);
2969: return(0);
2970: }
2972: /*@C
2973: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2974: Call this routine before calling MatLUFactorNumeric().
2976: Collective on Mat
2978: Input Parameters:
2979: + fact - the factor matrix obtained with MatGetFactor()
2980: . mat - the matrix
2981: . row, col - row and column permutations
2982: - info - options for factorization, includes
2983: $ fill - expected fill as ratio of original fill.
2984: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2985: $ Run with the option -info to determine an optimal value to use
2988: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2990: Most users should employ the simplified KSP interface for linear solvers
2991: instead of working directly with matrix algebra routines such as this.
2992: See, e.g., KSPCreate().
2994: Level: developer
2996: Concepts: matrices^LU symbolic factorization
2998: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3000: Developer Note: fortran interface is not autogenerated as the f90
3001: interface defintion cannot be generated correctly [due to MatFactorInfo]
3003: @*/
3004: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3005: {
3015: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3016: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3017: if (!(fact)->ops->lufactorsymbolic) {
3018: const MatSolverPackage spackage;
3019: MatFactorGetSolverPackage(fact,&spackage);
3020: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3021: }
3022: MatCheckPreallocated(mat,2);
3024: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
3025: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
3026: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
3027: PetscObjectStateIncrease((PetscObject)fact);
3028: return(0);
3029: }
3031: /*@C
3032: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3033: Call this routine after first calling MatLUFactorSymbolic().
3035: Collective on Mat
3037: Input Parameters:
3038: + fact - the factor matrix obtained with MatGetFactor()
3039: . mat - the matrix
3040: - info - options for factorization
3042: Notes:
3043: See MatLUFactor() for in-place factorization. See
3044: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3046: Most users should employ the simplified KSP interface for linear solvers
3047: instead of working directly with matrix algebra routines such as this.
3048: See, e.g., KSPCreate().
3050: Level: developer
3052: Concepts: matrices^LU numeric factorization
3054: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3056: Developer Note: fortran interface is not autogenerated as the f90
3057: interface defintion cannot be generated correctly [due to MatFactorInfo]
3059: @*/
3060: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3061: {
3069: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3070: 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);
3072: if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3073: MatCheckPreallocated(mat,2);
3074: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
3075: (fact->ops->lufactornumeric)(fact,mat,info);
3076: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
3077: MatViewFromOptions(fact,NULL,"-mat_factor_view");
3078: PetscObjectStateIncrease((PetscObject)fact);
3079: return(0);
3080: }
3082: /*@C
3083: MatCholeskyFactor - Performs in-place Cholesky factorization of a
3084: symmetric matrix.
3086: Collective on Mat
3088: Input Parameters:
3089: + mat - the matrix
3090: . perm - row and column permutations
3091: - f - expected fill as ratio of original fill
3093: Notes:
3094: See MatLUFactor() for the nonsymmetric case. See also
3095: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3097: Most users should employ the simplified KSP interface for linear solvers
3098: instead of working directly with matrix algebra routines such as this.
3099: See, e.g., KSPCreate().
3101: Level: developer
3103: Concepts: matrices^Cholesky factorization
3105: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3106: MatGetOrdering()
3108: Developer Note: fortran interface is not autogenerated as the f90
3109: interface defintion cannot be generated correctly [due to MatFactorInfo]
3111: @*/
3112: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3113: {
3121: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3122: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3123: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3124: 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);
3125: MatCheckPreallocated(mat,1);
3127: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3128: (*mat->ops->choleskyfactor)(mat,perm,info);
3129: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3130: PetscObjectStateIncrease((PetscObject)mat);
3131: return(0);
3132: }
3134: /*@C
3135: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3136: of a symmetric matrix.
3138: Collective on Mat
3140: Input Parameters:
3141: + fact - the factor matrix obtained with MatGetFactor()
3142: . mat - the matrix
3143: . perm - row and column permutations
3144: - info - options for factorization, includes
3145: $ fill - expected fill as ratio of original fill.
3146: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3147: $ Run with the option -info to determine an optimal value to use
3149: Notes:
3150: See MatLUFactorSymbolic() for the nonsymmetric case. See also
3151: MatCholeskyFactor() and MatCholeskyFactorNumeric().
3153: Most users should employ the simplified KSP interface for linear solvers
3154: instead of working directly with matrix algebra routines such as this.
3155: See, e.g., KSPCreate().
3157: Level: developer
3159: Concepts: matrices^Cholesky symbolic factorization
3161: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3162: MatGetOrdering()
3164: Developer Note: fortran interface is not autogenerated as the f90
3165: interface defintion cannot be generated correctly [due to MatFactorInfo]
3167: @*/
3168: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3169: {
3178: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3179: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3180: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3181: if (!(fact)->ops->choleskyfactorsymbolic) {
3182: const MatSolverPackage spackage;
3183: MatFactorGetSolverPackage(fact,&spackage);
3184: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3185: }
3186: MatCheckPreallocated(mat,2);
3188: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3189: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3190: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3191: PetscObjectStateIncrease((PetscObject)fact);
3192: return(0);
3193: }
3195: /*@C
3196: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3197: of a symmetric matrix. Call this routine after first calling
3198: MatCholeskyFactorSymbolic().
3200: Collective on Mat
3202: Input Parameters:
3203: + fact - the factor matrix obtained with MatGetFactor()
3204: . mat - the initial matrix
3205: . info - options for factorization
3206: - fact - the symbolic factor of mat
3209: Notes:
3210: Most users should employ the simplified KSP interface for linear solvers
3211: instead of working directly with matrix algebra routines such as this.
3212: See, e.g., KSPCreate().
3214: Level: developer
3216: Concepts: matrices^Cholesky numeric factorization
3218: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3220: Developer Note: fortran interface is not autogenerated as the f90
3221: interface defintion cannot be generated correctly [due to MatFactorInfo]
3223: @*/
3224: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3225: {
3233: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3234: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3235: 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);
3236: MatCheckPreallocated(mat,2);
3238: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3239: (fact->ops->choleskyfactornumeric)(fact,mat,info);
3240: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3241: MatViewFromOptions(fact,NULL,"-mat_factor_view");
3242: PetscObjectStateIncrease((PetscObject)fact);
3243: return(0);
3244: }
3246: /* ----------------------------------------------------------------*/
3247: /*@
3248: MatSolve - Solves A x = b, given a factored matrix.
3250: Neighbor-wise Collective on Mat and Vec
3252: Input Parameters:
3253: + mat - the factored matrix
3254: - b - the right-hand-side vector
3256: Output Parameter:
3257: . x - the result vector
3259: Notes:
3260: The vectors b and x cannot be the same. I.e., one cannot
3261: call MatSolve(A,x,x).
3263: Notes:
3264: Most users should employ the simplified KSP interface for linear solvers
3265: instead of working directly with matrix algebra routines such as this.
3266: See, e.g., KSPCreate().
3268: Level: developer
3270: Concepts: matrices^triangular solves
3272: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3273: @*/
3274: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3275: {
3285: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3286: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3287: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3288: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3289: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3290: if (!mat->rmap->N && !mat->cmap->N) return(0);
3291: if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3292: MatCheckPreallocated(mat,1);
3294: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3295: if (mat->factorerrortype) {
3296: PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3297: VecSetInf(x);
3298: } else {
3299: (*mat->ops->solve)(mat,b,x);
3300: }
3301: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3302: PetscObjectStateIncrease((PetscObject)x);
3303: return(0);
3304: }
3306: static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3307: {
3309: Vec b,x;
3310: PetscInt m,N,i;
3311: PetscScalar *bb,*xx;
3312: PetscBool flg;
3315: PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3316: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3317: PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3318: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3320: MatDenseGetArray(B,&bb);
3321: MatDenseGetArray(X,&xx);
3322: MatGetLocalSize(B,&m,NULL); /* number local rows */
3323: MatGetSize(B,NULL,&N); /* total columns in dense matrix */
3324: MatCreateVecs(A,&x,&b);
3325: for (i=0; i<N; i++) {
3326: VecPlaceArray(b,bb + i*m);
3327: VecPlaceArray(x,xx + i*m);
3328: if (trans) {
3329: MatSolveTranspose(A,b,x);
3330: } else {
3331: MatSolve(A,b,x);
3332: }
3333: VecResetArray(x);
3334: VecResetArray(b);
3335: }
3336: VecDestroy(&b);
3337: VecDestroy(&x);
3338: MatDenseRestoreArray(B,&bb);
3339: MatDenseRestoreArray(X,&xx);
3340: return(0);
3341: }
3343: /*@
3344: MatMatSolve - Solves A X = B, given a factored matrix.
3346: Neighbor-wise Collective on Mat
3348: Input Parameters:
3349: + A - the factored matrix
3350: - B - the right-hand-side matrix (dense matrix)
3352: Output Parameter:
3353: . X - the result matrix (dense matrix)
3355: Notes:
3356: The matrices b and x cannot be the same. I.e., one cannot
3357: call MatMatSolve(A,x,x).
3359: Notes:
3360: Most users should usually employ the simplified KSP interface for linear solvers
3361: instead of working directly with matrix algebra routines such as this.
3362: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3363: at a time.
3365: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3366: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3368: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3370: Level: developer
3372: Concepts: matrices^triangular solves
3374: .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3375: @*/
3376: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3377: {
3387: if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3388: if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3389: 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);
3390: 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);
3391: 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);
3392: 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");
3393: if (!A->rmap->N && !A->cmap->N) return(0);
3394: MatCheckPreallocated(A,1);
3396: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3397: if (!A->ops->matsolve) {
3398: PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3399: MatMatSolve_Basic(A,B,X,PETSC_FALSE);
3400: } else {
3401: (*A->ops->matsolve)(A,B,X);
3402: }
3403: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3404: PetscObjectStateIncrease((PetscObject)X);
3405: return(0);
3406: }
3408: /*@
3409: MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3411: Neighbor-wise Collective on Mat
3413: Input Parameters:
3414: + A - the factored matrix
3415: - B - the right-hand-side matrix (dense matrix)
3417: Output Parameter:
3418: . X - the result matrix (dense matrix)
3420: Notes:
3421: The matrices b and x cannot be the same. I.e., one cannot
3422: call MatMatSolveTranspose(A,x,x).
3424: Notes:
3425: Most users should usually employ the simplified KSP interface for linear solvers
3426: instead of working directly with matrix algebra routines such as this.
3427: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3428: at a time.
3430: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3431: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3433: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3435: Level: developer
3437: Concepts: matrices^triangular solves
3439: .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3440: @*/
3441: PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3442: {
3452: if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3453: if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3454: 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);
3455: 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);
3456: 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);
3457: 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");
3458: if (!A->rmap->N && !A->cmap->N) return(0);
3459: MatCheckPreallocated(A,1);
3461: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3462: if (!A->ops->matsolvetranspose) {
3463: PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);
3464: MatMatSolve_Basic(A,B,X,PETSC_TRUE);
3465: } else {
3466: (*A->ops->matsolvetranspose)(A,B,X);
3467: }
3468: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3469: PetscObjectStateIncrease((PetscObject)X);
3470: return(0);
3471: }
3473: /*@
3474: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3475: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3477: Neighbor-wise Collective on Mat and Vec
3479: Input Parameters:
3480: + mat - the factored matrix
3481: - b - the right-hand-side vector
3483: Output Parameter:
3484: . x - the result vector
3486: Notes:
3487: MatSolve() should be used for most applications, as it performs
3488: a forward solve followed by a backward solve.
3490: The vectors b and x cannot be the same, i.e., one cannot
3491: call MatForwardSolve(A,x,x).
3493: For matrix in seqsbaij format with block size larger than 1,
3494: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3495: MatForwardSolve() solves U^T*D y = b, and
3496: MatBackwardSolve() solves U x = y.
3497: Thus they do not provide a symmetric preconditioner.
3499: Most users should employ the simplified KSP interface for linear solvers
3500: instead of working directly with matrix algebra routines such as this.
3501: See, e.g., KSPCreate().
3503: Level: developer
3505: Concepts: matrices^forward solves
3507: .seealso: MatSolve(), MatBackwardSolve()
3508: @*/
3509: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3510: {
3520: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3521: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3522: if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3523: 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);
3524: 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);
3525: 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);
3526: MatCheckPreallocated(mat,1);
3527: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3528: (*mat->ops->forwardsolve)(mat,b,x);
3529: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3530: PetscObjectStateIncrease((PetscObject)x);
3531: return(0);
3532: }
3534: /*@
3535: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3536: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3538: Neighbor-wise Collective on Mat and Vec
3540: Input Parameters:
3541: + mat - the factored matrix
3542: - b - the right-hand-side vector
3544: Output Parameter:
3545: . x - the result vector
3547: Notes:
3548: MatSolve() should be used for most applications, as it performs
3549: a forward solve followed by a backward solve.
3551: The vectors b and x cannot be the same. I.e., one cannot
3552: call MatBackwardSolve(A,x,x).
3554: For matrix in seqsbaij format with block size larger than 1,
3555: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3556: MatForwardSolve() solves U^T*D y = b, and
3557: MatBackwardSolve() solves U x = y.
3558: Thus they do not provide a symmetric preconditioner.
3560: Most users should employ the simplified KSP interface for linear solvers
3561: instead of working directly with matrix algebra routines such as this.
3562: See, e.g., KSPCreate().
3564: Level: developer
3566: Concepts: matrices^backward solves
3568: .seealso: MatSolve(), MatForwardSolve()
3569: @*/
3570: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3571: {
3581: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3582: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3583: if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3584: 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);
3585: 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);
3586: 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);
3587: MatCheckPreallocated(mat,1);
3589: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3590: (*mat->ops->backwardsolve)(mat,b,x);
3591: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3592: PetscObjectStateIncrease((PetscObject)x);
3593: return(0);
3594: }
3596: /*@
3597: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3599: Neighbor-wise Collective on Mat and Vec
3601: Input Parameters:
3602: + mat - the factored matrix
3603: . b - the right-hand-side vector
3604: - y - the vector to be added to
3606: Output Parameter:
3607: . x - the result vector
3609: Notes:
3610: The vectors b and x cannot be the same. I.e., one cannot
3611: call MatSolveAdd(A,x,y,x).
3613: Most users should employ the simplified KSP interface for linear solvers
3614: instead of working directly with matrix algebra routines such as this.
3615: See, e.g., KSPCreate().
3617: Level: developer
3619: Concepts: matrices^triangular solves
3621: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3622: @*/
3623: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3624: {
3625: PetscScalar one = 1.0;
3626: Vec tmp;
3638: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3639: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3640: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3641: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3642: if (mat->rmap->N != 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);
3643: 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);
3644: 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);
3645: MatCheckPreallocated(mat,1);
3647: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3648: if (mat->ops->solveadd) {
3649: (*mat->ops->solveadd)(mat,b,y,x);
3650: } else {
3651: /* do the solve then the add manually */
3652: if (x != y) {
3653: MatSolve(mat,b,x);
3654: VecAXPY(x,one,y);
3655: } else {
3656: VecDuplicate(x,&tmp);
3657: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3658: VecCopy(x,tmp);
3659: MatSolve(mat,b,x);
3660: VecAXPY(x,one,tmp);
3661: VecDestroy(&tmp);
3662: }
3663: }
3664: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3665: PetscObjectStateIncrease((PetscObject)x);
3666: return(0);
3667: }
3669: /*@
3670: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3672: Neighbor-wise Collective on Mat and Vec
3674: Input Parameters:
3675: + mat - the factored matrix
3676: - b - the right-hand-side vector
3678: Output Parameter:
3679: . x - the result vector
3681: Notes:
3682: The vectors b and x cannot be the same. I.e., one cannot
3683: call MatSolveTranspose(A,x,x).
3685: Most users should employ the simplified KSP interface for linear solvers
3686: instead of working directly with matrix algebra routines such as this.
3687: See, e.g., KSPCreate().
3689: Level: developer
3691: Concepts: matrices^triangular solves
3693: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3694: @*/
3695: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3696: {
3706: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3707: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3708: if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3709: 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);
3710: 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);
3711: MatCheckPreallocated(mat,1);
3712: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3713: if (mat->factorerrortype) {
3714: PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3715: VecSetInf(x);
3716: } else {
3717: (*mat->ops->solvetranspose)(mat,b,x);
3718: }
3719: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3720: PetscObjectStateIncrease((PetscObject)x);
3721: return(0);
3722: }
3724: /*@
3725: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3726: factored matrix.
3728: Neighbor-wise Collective on Mat and Vec
3730: Input Parameters:
3731: + mat - the factored matrix
3732: . b - the right-hand-side vector
3733: - y - the vector to be added to
3735: Output Parameter:
3736: . x - the result vector
3738: Notes:
3739: The vectors b and x cannot be the same. I.e., one cannot
3740: call MatSolveTransposeAdd(A,x,y,x).
3742: Most users should employ the simplified KSP interface for linear solvers
3743: instead of working directly with matrix algebra routines such as this.
3744: See, e.g., KSPCreate().
3746: Level: developer
3748: Concepts: matrices^triangular solves
3750: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3751: @*/
3752: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3753: {
3754: PetscScalar one = 1.0;
3756: Vec tmp;
3767: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3768: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3769: 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);
3770: 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);
3771: 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);
3772: 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);
3773: MatCheckPreallocated(mat,1);
3775: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3776: if (mat->ops->solvetransposeadd) {
3777: if (mat->factorerrortype) {
3778: PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3779: VecSetInf(x);
3780: } else {
3781: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3782: }
3783: } else {
3784: /* do the solve then the add manually */
3785: if (x != y) {
3786: MatSolveTranspose(mat,b,x);
3787: VecAXPY(x,one,y);
3788: } else {
3789: VecDuplicate(x,&tmp);
3790: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3791: VecCopy(x,tmp);
3792: MatSolveTranspose(mat,b,x);
3793: VecAXPY(x,one,tmp);
3794: VecDestroy(&tmp);
3795: }
3796: }
3797: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3798: PetscObjectStateIncrease((PetscObject)x);
3799: return(0);
3800: }
3801: /* ----------------------------------------------------------------*/
3803: /*@
3804: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3806: Neighbor-wise Collective on Mat and Vec
3808: Input Parameters:
3809: + mat - the matrix
3810: . b - the right hand side
3811: . omega - the relaxation factor
3812: . flag - flag indicating the type of SOR (see below)
3813: . shift - diagonal shift
3814: . its - the number of iterations
3815: - lits - the number of local iterations
3817: Output Parameters:
3818: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3820: SOR Flags:
3821: . SOR_FORWARD_SWEEP - forward SOR
3822: . SOR_BACKWARD_SWEEP - backward SOR
3823: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3824: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3825: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3826: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3827: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3828: upper/lower triangular part of matrix to
3829: vector (with omega)
3830: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3832: Notes:
3833: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3834: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3835: on each processor.
3837: Application programmers will not generally use MatSOR() directly,
3838: but instead will employ the KSP/PC interface.
3840: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3842: Notes for Advanced Users:
3843: The flags are implemented as bitwise inclusive or operations.
3844: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3845: to specify a zero initial guess for SSOR.
3847: Most users should employ the simplified KSP interface for linear solvers
3848: instead of working directly with matrix algebra routines such as this.
3849: See, e.g., KSPCreate().
3851: Vectors x and b CANNOT be the same
3853: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3855: Level: developer
3857: Concepts: matrices^relaxation
3858: Concepts: matrices^SOR
3859: Concepts: matrices^Gauss-Seidel
3861: @*/
3862: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3863: {
3873: if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3874: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3875: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3876: 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);
3877: 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);
3878: 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);
3879: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3880: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3881: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3883: MatCheckPreallocated(mat,1);
3884: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3885: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3886: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3887: PetscObjectStateIncrease((PetscObject)x);
3888: return(0);
3889: }
3891: /*
3892: Default matrix copy routine.
3893: */
3894: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3895: {
3896: PetscErrorCode ierr;
3897: PetscInt i,rstart = 0,rend = 0,nz;
3898: const PetscInt *cwork;
3899: const PetscScalar *vwork;
3902: if (B->assembled) {
3903: MatZeroEntries(B);
3904: }
3905: MatGetOwnershipRange(A,&rstart,&rend);
3906: for (i=rstart; i<rend; i++) {
3907: MatGetRow(A,i,&nz,&cwork,&vwork);
3908: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3909: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3910: }
3911: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3912: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3913: return(0);
3914: }
3916: /*@
3917: MatCopy - Copys a matrix to another matrix.
3919: Collective on Mat
3921: Input Parameters:
3922: + A - the matrix
3923: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3925: Output Parameter:
3926: . B - where the copy is put
3928: Notes:
3929: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3930: same nonzero pattern or the routine will crash.
3932: MatCopy() copies the matrix entries of a matrix to another existing
3933: matrix (after first zeroing the second matrix). A related routine is
3934: MatConvert(), which first creates a new matrix and then copies the data.
3936: Level: intermediate
3938: Concepts: matrices^copying
3940: .seealso: MatConvert(), MatDuplicate()
3942: @*/
3943: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3944: {
3946: PetscInt i;
3954: MatCheckPreallocated(B,2);
3955: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3956: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3957: 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);
3958: MatCheckPreallocated(A,1);
3959: if (A == B) return(0);
3961: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3962: if (A->ops->copy) {
3963: (*A->ops->copy)(A,B,str);
3964: } else { /* generic conversion */
3965: MatCopy_Basic(A,B,str);
3966: }
3968: B->stencil.dim = A->stencil.dim;
3969: B->stencil.noc = A->stencil.noc;
3970: for (i=0; i<=A->stencil.dim; i++) {
3971: B->stencil.dims[i] = A->stencil.dims[i];
3972: B->stencil.starts[i] = A->stencil.starts[i];
3973: }
3975: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3976: PetscObjectStateIncrease((PetscObject)B);
3977: return(0);
3978: }
3980: /*@C
3981: MatConvert - Converts a matrix to another matrix, either of the same
3982: or different type.
3984: Collective on Mat
3986: Input Parameters:
3987: + mat - the matrix
3988: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3989: same type as the original matrix.
3990: - reuse - denotes if the destination matrix is to be created or reused.
3991: 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
3992: 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).
3994: Output Parameter:
3995: . M - pointer to place new matrix
3997: Notes:
3998: MatConvert() first creates a new matrix and then copies the data from
3999: the first matrix. A related routine is MatCopy(), which copies the matrix
4000: entries of one matrix to another already existing matrix context.
4002: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4003: the MPI communicator of the generated matrix is always the same as the communicator
4004: of the input matrix.
4006: Level: intermediate
4008: Concepts: matrices^converting between storage formats
4010: .seealso: MatCopy(), MatDuplicate()
4011: @*/
4012: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4013: {
4015: PetscBool sametype,issame,flg;
4016: char convname[256],mtype[256];
4017: Mat B;
4023: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4024: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4025: MatCheckPreallocated(mat,1);
4026: MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);
4028: PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
4029: if (flg) {
4030: newtype = mtype;
4031: }
4032: PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
4033: PetscStrcmp(newtype,"same",&issame);
4034: if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4035: 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");
4037: if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) return(0);
4039: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4040: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
4041: } else {
4042: PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4043: const char *prefix[3] = {"seq","mpi",""};
4044: PetscInt i;
4045: /*
4046: Order of precedence:
4047: 1) See if a specialized converter is known to the current matrix.
4048: 2) See if a specialized converter is known to the desired matrix class.
4049: 3) See if a good general converter is registered for the desired class
4050: (as of 6/27/03 only MATMPIADJ falls into this category).
4051: 4) See if a good general converter is known for the current matrix.
4052: 5) Use a really basic converter.
4053: */
4055: /* 1) See if a specialized converter is known to the current matrix and the desired class */
4056: for (i=0; i<3; i++) {
4057: PetscStrcpy(convname,"MatConvert_");
4058: PetscStrcat(convname,((PetscObject)mat)->type_name);
4059: PetscStrcat(convname,"_");
4060: PetscStrcat(convname,prefix[i]);
4061: PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
4062: PetscStrcat(convname,"_C");
4063: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4064: if (conv) goto foundconv;
4065: }
4067: /* 2) See if a specialized converter is known to the desired matrix class. */
4068: MatCreate(PetscObjectComm((PetscObject)mat),&B);
4069: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
4070: MatSetType(B,newtype);
4071: for (i=0; i<3; i++) {
4072: PetscStrcpy(convname,"MatConvert_");
4073: PetscStrcat(convname,((PetscObject)mat)->type_name);
4074: PetscStrcat(convname,"_");
4075: PetscStrcat(convname,prefix[i]);
4076: PetscStrcat(convname,newtype);
4077: PetscStrcat(convname,"_C");
4078: PetscObjectQueryFunction((PetscObject)B,convname,&conv);
4079: if (conv) {
4080: MatDestroy(&B);
4081: goto foundconv;
4082: }
4083: }
4085: /* 3) See if a good general converter is registered for the desired class */
4086: conv = B->ops->convertfrom;
4087: MatDestroy(&B);
4088: if (conv) goto foundconv;
4090: /* 4) See if a good general converter is known for the current matrix */
4091: if (mat->ops->convert) {
4092: conv = mat->ops->convert;
4093: }
4094: if (conv) goto foundconv;
4096: /* 5) Use a really basic converter. */
4097: conv = MatConvert_Basic;
4099: foundconv:
4100: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4101: (*conv)(mat,newtype,reuse,M);
4102: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4103: }
4104: PetscObjectStateIncrease((PetscObject)*M);
4106: /* Copy Mat options */
4107: if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
4108: if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
4109: return(0);
4110: }
4112: /*@C
4113: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
4115: Not Collective
4117: Input Parameter:
4118: . mat - the matrix, must be a factored matrix
4120: Output Parameter:
4121: . type - the string name of the package (do not free this string)
4123: Notes:
4124: In Fortran you pass in a empty string and the package name will be copied into it.
4125: (Make sure the string is long enough)
4127: Level: intermediate
4129: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4130: @*/
4131: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4132: {
4133: PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
4138: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4139: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
4140: if (!conv) {
4141: *type = MATSOLVERPETSC;
4142: } else {
4143: (*conv)(mat,type);
4144: }
4145: return(0);
4146: }
4148: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4149: struct _MatSolverPackageForSpecifcType {
4150: MatType mtype;
4151: PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*);
4152: MatSolverPackageForSpecifcType next;
4153: };
4155: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4156: struct _MatSolverPackageHolder {
4157: char *name;
4158: MatSolverPackageForSpecifcType handlers;
4159: MatSolverPackageHolder next;
4160: };
4162: static MatSolverPackageHolder MatSolverPackageHolders = NULL;
4164: /*@C
4165: MatSolvePackageRegister - Registers a MatSolverPackage that works for a particular matrix type
4167: Input Parameters:
4168: + package - name of the package, for example petsc or superlu
4169: . mtype - the matrix type that works with this package
4170: . ftype - the type of factorization supported by the package
4171: - getfactor - routine that will create the factored matrix ready to be used
4173: Level: intermediate
4175: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4176: @*/
4177: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4178: {
4179: PetscErrorCode ierr;
4180: MatSolverPackageHolder next = MatSolverPackageHolders,prev;
4181: PetscBool flg;
4182: MatSolverPackageForSpecifcType inext,iprev = NULL;
4185: if (!next) {
4186: PetscNew(&MatSolverPackageHolders);
4187: PetscStrallocpy(package,&MatSolverPackageHolders->name);
4188: PetscNew(&MatSolverPackageHolders->handlers);
4189: PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4190: MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4191: return(0);
4192: }
4193: while (next) {
4194: PetscStrcasecmp(package,next->name,&flg);
4195: if (flg) {
4196: if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverPackageHolder is missing handlers");
4197: inext = next->handlers;
4198: while (inext) {
4199: PetscStrcasecmp(mtype,inext->mtype,&flg);
4200: if (flg) {
4201: inext->getfactor[(int)ftype-1] = getfactor;
4202: return(0);
4203: }
4204: iprev = inext;
4205: inext = inext->next;
4206: }
4207: PetscNew(&iprev->next);
4208: PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4209: iprev->next->getfactor[(int)ftype-1] = getfactor;
4210: return(0);
4211: }
4212: prev = next;
4213: next = next->next;
4214: }
4215: PetscNew(&prev->next);
4216: PetscStrallocpy(package,&prev->next->name);
4217: PetscNew(&prev->next->handlers);
4218: PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4219: prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4220: return(0);
4221: }
4223: /*@C
4224: MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4226: Input Parameters:
4227: + package - name of the package, for example petsc or superlu
4228: . ftype - the type of factorization supported by the package
4229: - mtype - the matrix type that works with this package
4231: Output Parameters:
4232: + foundpackage - PETSC_TRUE if the package was registered
4233: . foundmtype - PETSC_TRUE if the package supports the requested mtype
4234: - getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4236: Level: intermediate
4238: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4239: @*/
4240: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4241: {
4242: PetscErrorCode ierr;
4243: MatSolverPackageHolder next = MatSolverPackageHolders;
4244: PetscBool flg;
4245: MatSolverPackageForSpecifcType inext;
4248: if (foundpackage) *foundpackage = PETSC_FALSE;
4249: if (foundmtype) *foundmtype = PETSC_FALSE;
4250: if (getfactor) *getfactor = NULL;
4252: if (package) {
4253: while (next) {
4254: PetscStrcasecmp(package,next->name,&flg);
4255: if (flg) {
4256: if (foundpackage) *foundpackage = PETSC_TRUE;
4257: inext = next->handlers;
4258: while (inext) {
4259: PetscStrbeginswith(mtype,inext->mtype,&flg);
4260: if (flg) {
4261: if (foundmtype) *foundmtype = PETSC_TRUE;
4262: if (getfactor) *getfactor = inext->getfactor[(int)ftype-1];
4263: return(0);
4264: }
4265: inext = inext->next;
4266: }
4267: }
4268: next = next->next;
4269: }
4270: } else {
4271: while (next) {
4272: inext = next->handlers;
4273: while (inext) {
4274: PetscStrbeginswith(mtype,inext->mtype,&flg);
4275: if (flg && inext->getfactor[(int)ftype-1]) {
4276: if (foundpackage) *foundpackage = PETSC_TRUE;
4277: if (foundmtype) *foundmtype = PETSC_TRUE;
4278: if (getfactor) *getfactor = inext->getfactor[(int)ftype-1];
4279: return(0);
4280: }
4281: inext = inext->next;
4282: }
4283: next = next->next;
4284: }
4285: }
4286: return(0);
4287: }
4289: PetscErrorCode MatSolverPackageDestroy(void)
4290: {
4291: PetscErrorCode ierr;
4292: MatSolverPackageHolder next = MatSolverPackageHolders,prev;
4293: MatSolverPackageForSpecifcType inext,iprev;
4296: while (next) {
4297: PetscFree(next->name);
4298: inext = next->handlers;
4299: while (inext) {
4300: PetscFree(inext->mtype);
4301: iprev = inext;
4302: inext = inext->next;
4303: PetscFree(iprev);
4304: }
4305: prev = next;
4306: next = next->next;
4307: PetscFree(prev);
4308: }
4309: MatSolverPackageHolders = NULL;
4310: return(0);
4311: }
4313: /*@C
4314: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4316: Collective on Mat
4318: Input Parameters:
4319: + mat - the matrix
4320: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4321: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4323: Output Parameters:
4324: . f - the factor matrix used with MatXXFactorSymbolic() calls
4326: Notes:
4327: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4328: such as pastix, superlu, mumps etc.
4330: PETSc must have been ./configure to use the external solver, using the option --download-package
4332: Level: intermediate
4334: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4335: @*/
4336: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4337: {
4338: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4339: PetscBool foundpackage,foundmtype;
4345: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4346: MatCheckPreallocated(mat,1);
4348: MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4349: if (!foundpackage) {
4350: if (type) {
4351: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4352: } else {
4353: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4354: }
4355: }
4357: if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4358: if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support factorization type %s for matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);
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, const MatSolverPackage 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: MatSolverPackageGet(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: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4427: .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4428: @*/
4429: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4430: {
4432: Mat B;
4433: PetscInt i;
4434: DM dm;
4440: if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4441: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4442: MatCheckPreallocated(mat,1);
4444: *M = 0;
4445: if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4446: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4447: (*mat->ops->duplicate)(mat,op,M);
4448: B = *M;
4450: B->stencil.dim = mat->stencil.dim;
4451: B->stencil.noc = mat->stencil.noc;
4452: for (i=0; i<=mat->stencil.dim; i++) {
4453: B->stencil.dims[i] = mat->stencil.dims[i];
4454: B->stencil.starts[i] = mat->stencil.starts[i];
4455: }
4457: B->nooffproczerorows = mat->nooffproczerorows;
4458: B->nooffprocentries = mat->nooffprocentries;
4460: PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4461: if (dm) {
4462: PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4463: }
4464: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4465: PetscObjectStateIncrease((PetscObject)B);
4466: return(0);
4467: }
4469: /*@
4470: MatGetDiagonal - Gets the diagonal of a matrix.
4472: Logically Collective on Mat and Vec
4474: Input Parameters:
4475: + mat - the matrix
4476: - v - the vector for storing the diagonal
4478: Output Parameter:
4479: . v - the diagonal of the matrix
4481: Level: intermediate
4483: Note:
4484: Currently only correct in parallel for square matrices.
4486: Concepts: matrices^accessing diagonals
4488: .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4489: @*/
4490: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4491: {
4498: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4499: if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4500: MatCheckPreallocated(mat,1);
4502: (*mat->ops->getdiagonal)(mat,v);
4503: PetscObjectStateIncrease((PetscObject)v);
4504: return(0);
4505: }
4507: /*@C
4508: MatGetRowMin - Gets the minimum value (of the real part) of each
4509: row of the matrix
4511: Logically Collective on Mat and Vec
4513: Input Parameters:
4514: . mat - the matrix
4516: Output Parameter:
4517: + v - the vector for storing the maximums
4518: - idx - the indices of the column found for each row (optional)
4520: Level: intermediate
4522: Notes: The result of this call are the same as if one converted the matrix to dense format
4523: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4525: This code is only implemented for a couple of matrix formats.
4527: Concepts: matrices^getting row maximums
4529: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4530: MatGetRowMax()
4531: @*/
4532: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4533: {
4540: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4541: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4542: MatCheckPreallocated(mat,1);
4544: (*mat->ops->getrowmin)(mat,v,idx);
4545: PetscObjectStateIncrease((PetscObject)v);
4546: return(0);
4547: }
4549: /*@C
4550: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4551: row of the matrix
4553: Logically Collective on Mat and Vec
4555: Input Parameters:
4556: . mat - the matrix
4558: Output Parameter:
4559: + v - the vector for storing the minimums
4560: - idx - the indices of the column found for each row (or NULL if not needed)
4562: Level: intermediate
4564: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4565: row is 0 (the first column).
4567: This code is only implemented for a couple of matrix formats.
4569: Concepts: matrices^getting row maximums
4571: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4572: @*/
4573: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4574: {
4581: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4582: if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4583: MatCheckPreallocated(mat,1);
4584: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4586: (*mat->ops->getrowminabs)(mat,v,idx);
4587: PetscObjectStateIncrease((PetscObject)v);
4588: return(0);
4589: }
4591: /*@C
4592: MatGetRowMax - Gets the maximum value (of the real part) of each
4593: row of the matrix
4595: Logically Collective on Mat and Vec
4597: Input Parameters:
4598: . mat - the matrix
4600: Output Parameter:
4601: + v - the vector for storing the maximums
4602: - idx - the indices of the column found for each row (optional)
4604: Level: intermediate
4606: Notes: The result of this call are the same as if one converted the matrix to dense format
4607: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4609: This code is only implemented for a couple of matrix formats.
4611: Concepts: matrices^getting row maximums
4613: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4614: @*/
4615: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4616: {
4623: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4624: if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4625: MatCheckPreallocated(mat,1);
4627: (*mat->ops->getrowmax)(mat,v,idx);
4628: PetscObjectStateIncrease((PetscObject)v);
4629: return(0);
4630: }
4632: /*@C
4633: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4634: row of the matrix
4636: Logically Collective on Mat and Vec
4638: Input Parameters:
4639: . mat - the matrix
4641: Output Parameter:
4642: + v - the vector for storing the maximums
4643: - idx - the indices of the column found for each row (or NULL if not needed)
4645: Level: intermediate
4647: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4648: row is 0 (the first column).
4650: This code is only implemented for a couple of matrix formats.
4652: Concepts: matrices^getting row maximums
4654: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4655: @*/
4656: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4657: {
4664: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4665: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4666: MatCheckPreallocated(mat,1);
4667: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4669: (*mat->ops->getrowmaxabs)(mat,v,idx);
4670: PetscObjectStateIncrease((PetscObject)v);
4671: return(0);
4672: }
4674: /*@
4675: MatGetRowSum - Gets the sum of each row of the matrix
4677: Logically or Neighborhood Collective on Mat and Vec
4679: Input Parameters:
4680: . mat - the matrix
4682: Output Parameter:
4683: . v - the vector for storing the sum of rows
4685: Level: intermediate
4687: Notes: This code is slow since it is not currently specialized for different formats
4689: Concepts: matrices^getting row sums
4691: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4692: @*/
4693: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4694: {
4695: Vec ones;
4702: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4703: MatCheckPreallocated(mat,1);
4704: MatCreateVecs(mat,&ones,NULL);
4705: VecSet(ones,1.);
4706: MatMult(mat,ones,v);
4707: VecDestroy(&ones);
4708: return(0);
4709: }
4711: /*@
4712: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4714: Collective on Mat
4716: Input Parameter:
4717: + mat - the matrix to transpose
4718: - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4720: Output Parameters:
4721: . B - the transpose
4723: Notes:
4724: If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4726: MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4728: Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4730: Level: intermediate
4732: Concepts: matrices^transposing
4734: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4735: @*/
4736: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4737: {
4743: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4744: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4745: if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4746: if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4747: if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4748: MatCheckPreallocated(mat,1);
4750: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4751: (*mat->ops->transpose)(mat,reuse,B);
4752: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4753: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4754: return(0);
4755: }
4757: /*@
4758: MatIsTranspose - Test whether a matrix is another one's transpose,
4759: or its own, in which case it tests symmetry.
4761: Collective on Mat
4763: Input Parameter:
4764: + A - the matrix to test
4765: - B - the matrix to test against, this can equal the first parameter
4767: Output Parameters:
4768: . flg - the result
4770: Notes:
4771: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4772: has a running time of the order of the number of nonzeros; the parallel
4773: test involves parallel copies of the block-offdiagonal parts of the matrix.
4775: Level: intermediate
4777: Concepts: matrices^transposing, matrix^symmetry
4779: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4780: @*/
4781: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4782: {
4783: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4789: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4790: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4791: *flg = PETSC_FALSE;
4792: if (f && g) {
4793: if (f == g) {
4794: (*f)(A,B,tol,flg);
4795: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4796: } else {
4797: MatType mattype;
4798: if (!f) {
4799: MatGetType(A,&mattype);
4800: } else {
4801: MatGetType(B,&mattype);
4802: }
4803: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4804: }
4805: return(0);
4806: }
4808: /*@
4809: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4811: Collective on Mat
4813: Input Parameter:
4814: + mat - the matrix to transpose and complex conjugate
4815: - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4817: Output Parameters:
4818: . B - the Hermitian
4820: Level: intermediate
4822: Concepts: matrices^transposing, complex conjugatex
4824: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4825: @*/
4826: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4827: {
4831: MatTranspose(mat,reuse,B);
4832: #if defined(PETSC_USE_COMPLEX)
4833: MatConjugate(*B);
4834: #endif
4835: return(0);
4836: }
4838: /*@
4839: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4841: Collective on Mat
4843: Input Parameter:
4844: + A - the matrix to test
4845: - B - the matrix to test against, this can equal the first parameter
4847: Output Parameters:
4848: . flg - the result
4850: Notes:
4851: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4852: has a running time of the order of the number of nonzeros; the parallel
4853: test involves parallel copies of the block-offdiagonal parts of the matrix.
4855: Level: intermediate
4857: Concepts: matrices^transposing, matrix^symmetry
4859: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4860: @*/
4861: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4862: {
4863: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4869: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4870: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4871: if (f && g) {
4872: if (f==g) {
4873: (*f)(A,B,tol,flg);
4874: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4875: }
4876: return(0);
4877: }
4879: /*@
4880: MatPermute - Creates a new matrix with rows and columns permuted from the
4881: original.
4883: Collective on Mat
4885: Input Parameters:
4886: + mat - the matrix to permute
4887: . row - row permutation, each processor supplies only the permutation for its rows
4888: - col - column permutation, each processor supplies only the permutation for its columns
4890: Output Parameters:
4891: . B - the permuted matrix
4893: Level: advanced
4895: Note:
4896: The index sets map from row/col of permuted matrix to row/col of original matrix.
4897: The index sets should be on the same communicator as Mat and have the same local sizes.
4899: Concepts: matrices^permuting
4901: .seealso: MatGetOrdering(), ISAllGather()
4903: @*/
4904: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4905: {
4914: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4915: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4916: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4917: MatCheckPreallocated(mat,1);
4919: (*mat->ops->permute)(mat,row,col,B);
4920: PetscObjectStateIncrease((PetscObject)*B);
4921: return(0);
4922: }
4924: /*@
4925: MatEqual - Compares two matrices.
4927: Collective on Mat
4929: Input Parameters:
4930: + A - the first matrix
4931: - B - the second matrix
4933: Output Parameter:
4934: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4936: Level: intermediate
4938: Concepts: matrices^equality between
4939: @*/
4940: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4941: {
4951: MatCheckPreallocated(B,2);
4952: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4953: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4954: 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);
4955: if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4956: if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4957: 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);
4958: MatCheckPreallocated(A,1);
4960: (*A->ops->equal)(A,B,flg);
4961: return(0);
4962: }
4964: /*@C
4965: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4966: matrices that are stored as vectors. Either of the two scaling
4967: matrices can be NULL.
4969: Collective on Mat
4971: Input Parameters:
4972: + mat - the matrix to be scaled
4973: . l - the left scaling vector (or NULL)
4974: - r - the right scaling vector (or NULL)
4976: Notes:
4977: MatDiagonalScale() computes A = LAR, where
4978: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4979: The L scales the rows of the matrix, the R scales the columns of the matrix.
4981: Level: intermediate
4983: Concepts: matrices^diagonal scaling
4984: Concepts: diagonal scaling of matrices
4986: .seealso: MatScale()
4987: @*/
4988: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4989: {
4995: if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4998: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4999: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5000: MatCheckPreallocated(mat,1);
5002: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5003: (*mat->ops->diagonalscale)(mat,l,r);
5004: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5005: PetscObjectStateIncrease((PetscObject)mat);
5006: #if defined(PETSC_HAVE_CUSP)
5007: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5008: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5009: }
5010: #elif defined(PETSC_HAVE_VIENNACL)
5011: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5012: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5013: }
5014: #elif defined(PETSC_HAVE_VECCUDA)
5015: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5016: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5017: }
5018: #endif
5019: return(0);
5020: }
5022: /*@
5023: MatScale - Scales all elements of a matrix by a given number.
5025: Logically Collective on Mat
5027: Input Parameters:
5028: + mat - the matrix to be scaled
5029: - a - the scaling value
5031: Output Parameter:
5032: . mat - the scaled matrix
5034: Level: intermediate
5036: Concepts: matrices^scaling all entries
5038: .seealso: MatDiagonalScale()
5039: @*/
5040: PetscErrorCode MatScale(Mat mat,PetscScalar a)
5041: {
5047: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5048: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5049: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5051: MatCheckPreallocated(mat,1);
5053: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5054: if (a != (PetscScalar)1.0) {
5055: (*mat->ops->scale)(mat,a);
5056: PetscObjectStateIncrease((PetscObject)mat);
5057: #if defined(PETSC_HAVE_CUSP)
5058: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5059: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5060: }
5061: #elif defined(PETSC_HAVE_VIENNACL)
5062: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5063: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5064: }
5065: #elif defined(PETSC_HAVE_VECCUDA)
5066: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5067: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5068: }
5069: #endif
5070: }
5071: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5072: return(0);
5073: }
5075: /*@
5076: MatNorm - Calculates various norms of a matrix.
5078: Collective on Mat
5080: Input Parameters:
5081: + mat - the matrix
5082: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5084: Output Parameters:
5085: . nrm - the resulting norm
5087: Level: intermediate
5089: Concepts: matrices^norm
5090: Concepts: norm^of matrix
5091: @*/
5092: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5093: {
5101: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5102: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5103: if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5104: MatCheckPreallocated(mat,1);
5106: (*mat->ops->norm)(mat,type,nrm);
5107: return(0);
5108: }
5110: /*
5111: This variable is used to prevent counting of MatAssemblyBegin() that
5112: are called from within a MatAssemblyEnd().
5113: */
5114: static PetscInt MatAssemblyEnd_InUse = 0;
5115: /*@
5116: MatAssemblyBegin - Begins assembling the matrix. This routine should
5117: be called after completing all calls to MatSetValues().
5119: Collective on Mat
5121: Input Parameters:
5122: + mat - the matrix
5123: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5125: Notes:
5126: MatSetValues() generally caches the values. The matrix is ready to
5127: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5128: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5129: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5130: using the matrix.
5132: ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5133: 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
5134: a global collective operation requring all processes that share the matrix.
5136: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5137: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5138: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5140: Level: beginner
5142: Concepts: matrices^assembling
5144: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5145: @*/
5146: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5147: {
5153: MatCheckPreallocated(mat,1);
5154: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5155: if (mat->assembled) {
5156: mat->was_assembled = PETSC_TRUE;
5157: mat->assembled = PETSC_FALSE;
5158: }
5159: if (!MatAssemblyEnd_InUse) {
5160: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5161: if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5162: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5163: } else if (mat->ops->assemblybegin) {
5164: (*mat->ops->assemblybegin)(mat,type);
5165: }
5166: return(0);
5167: }
5169: /*@
5170: MatAssembled - Indicates if a matrix has been assembled and is ready for
5171: use; for example, in matrix-vector product.
5173: Not Collective
5175: Input Parameter:
5176: . mat - the matrix
5178: Output Parameter:
5179: . assembled - PETSC_TRUE or PETSC_FALSE
5181: Level: advanced
5183: Concepts: matrices^assembled?
5185: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5186: @*/
5187: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
5188: {
5193: *assembled = mat->assembled;
5194: return(0);
5195: }
5197: /*@
5198: MatAssemblyEnd - Completes assembling the matrix. This routine should
5199: be called after MatAssemblyBegin().
5201: Collective on Mat
5203: Input Parameters:
5204: + mat - the matrix
5205: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5207: Options Database Keys:
5208: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5209: . -mat_view ::ascii_info_detail - Prints more detailed info
5210: . -mat_view - Prints matrix in ASCII format
5211: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
5212: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5213: . -display <name> - Sets display name (default is host)
5214: . -draw_pause <sec> - Sets number of seconds to pause after display
5215: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 12 Using MATLAB with PETSc )
5216: . -viewer_socket_machine <machine> - Machine to use for socket
5217: . -viewer_socket_port <port> - Port number to use for socket
5218: - -mat_view binary:filename[:append] - Save matrix to file in binary format
5220: Notes:
5221: MatSetValues() generally caches the values. The matrix is ready to
5222: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5223: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5224: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5225: using the matrix.
5227: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5228: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5229: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5231: Level: beginner
5233: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5234: @*/
5235: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5236: {
5237: PetscErrorCode ierr;
5238: static PetscInt inassm = 0;
5239: PetscBool flg = PETSC_FALSE;
5245: inassm++;
5246: MatAssemblyEnd_InUse++;
5247: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5248: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5249: if (mat->ops->assemblyend) {
5250: (*mat->ops->assemblyend)(mat,type);
5251: }
5252: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5253: } else if (mat->ops->assemblyend) {
5254: (*mat->ops->assemblyend)(mat,type);
5255: }
5257: /* Flush assembly is not a true assembly */
5258: if (type != MAT_FLUSH_ASSEMBLY) {
5259: mat->assembled = PETSC_TRUE; mat->num_ass++;
5260: }
5261: mat->insertmode = NOT_SET_VALUES;
5262: MatAssemblyEnd_InUse--;
5263: PetscObjectStateIncrease((PetscObject)mat);
5264: if (!mat->symmetric_eternal) {
5265: mat->symmetric_set = PETSC_FALSE;
5266: mat->hermitian_set = PETSC_FALSE;
5267: mat->structurally_symmetric_set = PETSC_FALSE;
5268: }
5269: #if defined(PETSC_HAVE_CUSP)
5270: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5271: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5272: }
5273: #elif defined(PETSC_HAVE_VIENNACL)
5274: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5275: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5276: }
5277: #elif defined(PETSC_HAVE_VECCUDA)
5278: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5279: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5280: }
5281: #endif
5282: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5283: MatViewFromOptions(mat,NULL,"-mat_view");
5285: if (mat->checksymmetryonassembly) {
5286: MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5287: if (flg) {
5288: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5289: } else {
5290: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5291: }
5292: }
5293: if (mat->nullsp && mat->checknullspaceonassembly) {
5294: MatNullSpaceTest(mat->nullsp,mat,NULL);
5295: }
5296: }
5297: inassm--;
5298: return(0);
5299: }
5301: /*@
5302: MatSetOption - Sets a parameter option for a matrix. Some options
5303: may be specific to certain storage formats. Some options
5304: determine how values will be inserted (or added). Sorted,
5305: row-oriented input will generally assemble the fastest. The default
5306: is row-oriented.
5308: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5310: Input Parameters:
5311: + mat - the matrix
5312: . option - the option, one of those listed below (and possibly others),
5313: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5315: Options Describing Matrix Structure:
5316: + MAT_SPD - symmetric positive definite
5317: . MAT_SYMMETRIC - symmetric in terms of both structure and value
5318: . MAT_HERMITIAN - transpose is the complex conjugation
5319: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5320: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5321: you set to be kept with all future use of the matrix
5322: including after MatAssemblyBegin/End() which could
5323: potentially change the symmetry structure, i.e. you
5324: KNOW the matrix will ALWAYS have the property you set.
5327: Options For Use with MatSetValues():
5328: Insert a logically dense subblock, which can be
5329: . MAT_ROW_ORIENTED - row-oriented (default)
5331: Note these options reflect the data you pass in with MatSetValues(); it has
5332: nothing to do with how the data is stored internally in the matrix
5333: data structure.
5335: When (re)assembling a matrix, we can restrict the input for
5336: efficiency/debugging purposes. These options include:
5337: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5338: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5339: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5340: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5341: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5342: . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5343: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5344: performance for very large process counts.
5345: - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5346: of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5347: functions, instead sending only neighbor messages.
5349: Notes:
5350: Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5352: Some options are relevant only for particular matrix types and
5353: are thus ignored by others. Other options are not supported by
5354: certain matrix types and will generate an error message if set.
5356: If using a Fortran 77 module to compute a matrix, one may need to
5357: use the column-oriented option (or convert to the row-oriented
5358: format).
5360: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5361: that would generate a new entry in the nonzero structure is instead
5362: ignored. Thus, if memory has not alredy been allocated for this particular
5363: data, then the insertion is ignored. For dense matrices, in which
5364: the entire array is allocated, no entries are ever ignored.
5365: Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5367: MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5368: that would generate a new entry in the nonzero structure instead produces
5369: 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
5371: MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5372: that would generate a new entry that has not been preallocated will
5373: instead produce an error. (Currently supported for AIJ and BAIJ formats
5374: only.) This is a useful flag when debugging matrix memory preallocation.
5375: If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5377: MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5378: other processors should be dropped, rather than stashed.
5379: This is useful if you know that the "owning" processor is also
5380: always generating the correct matrix entries, so that PETSc need
5381: not transfer duplicate entries generated on another processor.
5383: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5384: searches during matrix assembly. When this flag is set, the hash table
5385: is created during the first Matrix Assembly. This hash table is
5386: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5387: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5388: should be used with MAT_USE_HASH_TABLE flag. This option is currently
5389: supported by MATMPIBAIJ format only.
5391: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5392: are kept in the nonzero structure
5394: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5395: a zero location in the matrix
5397: MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5399: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5400: zero row routines and thus improves performance for very large process counts.
5402: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5403: part of the matrix (since they should match the upper triangular part).
5405: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5407: Level: intermediate
5409: Concepts: matrices^setting options
5411: .seealso: MatOption, Mat
5413: @*/
5414: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5415: {
5421: if (op > 0) {
5424: }
5426: 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);
5427: 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()");
5429: switch (op) {
5430: case MAT_NO_OFF_PROC_ENTRIES:
5431: mat->nooffprocentries = flg;
5432: return(0);
5433: break;
5434: case MAT_SUBSET_OFF_PROC_ENTRIES:
5435: mat->subsetoffprocentries = flg;
5436: return(0);
5437: case MAT_NO_OFF_PROC_ZERO_ROWS:
5438: mat->nooffproczerorows = flg;
5439: return(0);
5440: break;
5441: case MAT_SPD:
5442: mat->spd_set = PETSC_TRUE;
5443: mat->spd = flg;
5444: if (flg) {
5445: mat->symmetric = PETSC_TRUE;
5446: mat->structurally_symmetric = PETSC_TRUE;
5447: mat->symmetric_set = PETSC_TRUE;
5448: mat->structurally_symmetric_set = PETSC_TRUE;
5449: }
5450: break;
5451: case MAT_SYMMETRIC:
5452: mat->symmetric = flg;
5453: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5454: mat->symmetric_set = PETSC_TRUE;
5455: mat->structurally_symmetric_set = flg;
5456: #if !defined(PETSC_USE_COMPLEX)
5457: mat->hermitian = flg;
5458: mat->hermitian_set = PETSC_TRUE;
5459: #endif
5460: break;
5461: case MAT_HERMITIAN:
5462: mat->hermitian = flg;
5463: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5464: mat->hermitian_set = PETSC_TRUE;
5465: mat->structurally_symmetric_set = flg;
5466: #if !defined(PETSC_USE_COMPLEX)
5467: mat->symmetric = flg;
5468: mat->symmetric_set = PETSC_TRUE;
5469: #endif
5470: break;
5471: case MAT_STRUCTURALLY_SYMMETRIC:
5472: mat->structurally_symmetric = flg;
5473: mat->structurally_symmetric_set = PETSC_TRUE;
5474: break;
5475: case MAT_SYMMETRY_ETERNAL:
5476: mat->symmetric_eternal = flg;
5477: break;
5478: case MAT_STRUCTURE_ONLY:
5479: mat->structure_only = flg;
5480: break;
5481: default:
5482: break;
5483: }
5484: if (mat->ops->setoption) {
5485: (*mat->ops->setoption)(mat,op,flg);
5486: }
5487: return(0);
5488: }
5490: /*@
5491: MatGetOption - Gets a parameter option that has been set for a matrix.
5493: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5495: Input Parameters:
5496: + mat - the matrix
5497: - option - the option, this only responds to certain options, check the code for which ones
5499: Output Parameter:
5500: . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5502: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5504: Level: intermediate
5506: Concepts: matrices^setting options
5508: .seealso: MatOption, MatSetOption()
5510: @*/
5511: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5512: {
5517: 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);
5518: 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()");
5520: switch (op) {
5521: case MAT_NO_OFF_PROC_ENTRIES:
5522: *flg = mat->nooffprocentries;
5523: break;
5524: case MAT_NO_OFF_PROC_ZERO_ROWS:
5525: *flg = mat->nooffproczerorows;
5526: break;
5527: case MAT_SYMMETRIC:
5528: *flg = mat->symmetric;
5529: break;
5530: case MAT_HERMITIAN:
5531: *flg = mat->hermitian;
5532: break;
5533: case MAT_STRUCTURALLY_SYMMETRIC:
5534: *flg = mat->structurally_symmetric;
5535: break;
5536: case MAT_SYMMETRY_ETERNAL:
5537: *flg = mat->symmetric_eternal;
5538: break;
5539: case MAT_SPD:
5540: *flg = mat->spd;
5541: break;
5542: default:
5543: break;
5544: }
5545: return(0);
5546: }
5548: /*@
5549: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5550: this routine retains the old nonzero structure.
5552: Logically Collective on Mat
5554: Input Parameters:
5555: . mat - the matrix
5557: Level: intermediate
5559: Notes: If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase.
5560: See the Performance chapter of the users manual for information on preallocating matrices.
5562: Concepts: matrices^zeroing
5564: .seealso: MatZeroRows()
5565: @*/
5566: PetscErrorCode MatZeroEntries(Mat mat)
5567: {
5573: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5574: 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");
5575: if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5576: MatCheckPreallocated(mat,1);
5578: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5579: (*mat->ops->zeroentries)(mat);
5580: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5581: PetscObjectStateIncrease((PetscObject)mat);
5582: #if defined(PETSC_HAVE_CUSP)
5583: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5584: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5585: }
5586: #elif defined(PETSC_HAVE_VIENNACL)
5587: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5588: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5589: }
5590: #elif defined(PETSC_HAVE_VECCUDA)
5591: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5592: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5593: }
5594: #endif
5595: return(0);
5596: }
5598: /*@C
5599: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5600: of a set of rows and columns of a matrix.
5602: Collective on Mat
5604: Input Parameters:
5605: + mat - the matrix
5606: . numRows - the number of rows to remove
5607: . rows - the global row indices
5608: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5609: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5610: - b - optional vector of right hand side, that will be adjusted by provided solution
5612: Notes:
5613: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5615: The user can set a value in the diagonal entry (or for the AIJ and
5616: row formats can optionally remove the main diagonal entry from the
5617: nonzero structure as well, by passing 0.0 as the final argument).
5619: For the parallel case, all processes that share the matrix (i.e.,
5620: those in the communicator used for matrix creation) MUST call this
5621: routine, regardless of whether any rows being zeroed are owned by
5622: them.
5624: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5625: list only rows local to itself).
5627: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5629: Level: intermediate
5631: Concepts: matrices^zeroing rows
5633: .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5634: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5635: @*/
5636: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5637: {
5644: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5645: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5646: if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5647: MatCheckPreallocated(mat,1);
5649: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5650: MatViewFromOptions(mat,NULL,"-mat_view");
5651: PetscObjectStateIncrease((PetscObject)mat);
5652: #if defined(PETSC_HAVE_CUSP)
5653: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5654: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5655: }
5656: #elif defined(PETSC_HAVE_VIENNACL)
5657: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5658: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5659: }
5660: #elif defined(PETSC_HAVE_VECCUDA)
5661: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5662: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5663: }
5664: #endif
5665: return(0);
5666: }
5668: /*@C
5669: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5670: of a set of rows and columns of a matrix.
5672: Collective on Mat
5674: Input Parameters:
5675: + mat - the matrix
5676: . is - the rows to zero
5677: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5678: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5679: - b - optional vector of right hand side, that will be adjusted by provided solution
5681: Notes:
5682: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5684: The user can set a value in the diagonal entry (or for the AIJ and
5685: row formats can optionally remove the main diagonal entry from the
5686: nonzero structure as well, by passing 0.0 as the final argument).
5688: For the parallel case, all processes that share the matrix (i.e.,
5689: those in the communicator used for matrix creation) MUST call this
5690: routine, regardless of whether any rows being zeroed are owned by
5691: them.
5693: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5694: list only rows local to itself).
5696: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5698: Level: intermediate
5700: Concepts: matrices^zeroing rows
5702: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5703: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5704: @*/
5705: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5706: {
5708: PetscInt numRows;
5709: const PetscInt *rows;
5716: ISGetLocalSize(is,&numRows);
5717: ISGetIndices(is,&rows);
5718: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5719: ISRestoreIndices(is,&rows);
5720: return(0);
5721: }
5723: /*@C
5724: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5725: of a set of rows of a matrix.
5727: Collective on Mat
5729: Input Parameters:
5730: + mat - the matrix
5731: . numRows - the number of rows to remove
5732: . rows - the global row indices
5733: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5734: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5735: - b - optional vector of right hand side, that will be adjusted by provided solution
5737: Notes:
5738: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5739: but does not release memory. For the dense and block diagonal
5740: formats this does not alter the nonzero structure.
5742: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5743: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5744: merely zeroed.
5746: The user can set a value in the diagonal entry (or for the AIJ and
5747: row formats can optionally remove the main diagonal entry from the
5748: nonzero structure as well, by passing 0.0 as the final argument).
5750: For the parallel case, all processes that share the matrix (i.e.,
5751: those in the communicator used for matrix creation) MUST call this
5752: routine, regardless of whether any rows being zeroed are owned by
5753: them.
5755: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5756: list only rows local to itself).
5758: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5759: owns that are to be zeroed. This saves a global synchronization in the implementation.
5761: Level: intermediate
5763: Concepts: matrices^zeroing rows
5765: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5766: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5767: @*/
5768: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5769: {
5776: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5777: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5778: if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5779: MatCheckPreallocated(mat,1);
5781: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5782: MatViewFromOptions(mat,NULL,"-mat_view");
5783: PetscObjectStateIncrease((PetscObject)mat);
5784: #if defined(PETSC_HAVE_CUSP)
5785: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5786: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5787: }
5788: #elif defined(PETSC_HAVE_VIENNACL)
5789: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5790: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5791: }
5792: #elif defined(PETSC_HAVE_VECCUDA)
5793: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5794: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5795: }
5796: #endif
5797: return(0);
5798: }
5800: /*@C
5801: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5802: of a set of rows of a matrix.
5804: Collective on Mat
5806: Input Parameters:
5807: + mat - the matrix
5808: . is - index set of rows to remove
5809: . diag - value put in all diagonals of eliminated rows
5810: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5811: - b - optional vector of right hand side, that will be adjusted by provided solution
5813: Notes:
5814: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5815: but does not release memory. For the dense and block diagonal
5816: formats this does not alter the nonzero structure.
5818: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5819: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5820: merely zeroed.
5822: The user can set a value in the diagonal entry (or for the AIJ and
5823: row formats can optionally remove the main diagonal entry from the
5824: nonzero structure as well, by passing 0.0 as the final argument).
5826: For the parallel case, all processes that share the matrix (i.e.,
5827: those in the communicator used for matrix creation) MUST call this
5828: routine, regardless of whether any rows being zeroed are owned by
5829: them.
5831: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5832: list only rows local to itself).
5834: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5835: owns that are to be zeroed. This saves a global synchronization in the implementation.
5837: Level: intermediate
5839: Concepts: matrices^zeroing rows
5841: .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5842: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5843: @*/
5844: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5845: {
5846: PetscInt numRows;
5847: const PetscInt *rows;
5854: ISGetLocalSize(is,&numRows);
5855: ISGetIndices(is,&rows);
5856: MatZeroRows(mat,numRows,rows,diag,x,b);
5857: ISRestoreIndices(is,&rows);
5858: return(0);
5859: }
5861: /*@C
5862: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5863: of a set of rows of a matrix. These rows must be local to the process.
5865: Collective on Mat
5867: Input Parameters:
5868: + mat - the matrix
5869: . numRows - the number of rows to remove
5870: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5871: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5872: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5873: - b - optional vector of right hand side, that will be adjusted by provided solution
5875: Notes:
5876: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5877: but does not release memory. For the dense and block diagonal
5878: formats this does not alter the nonzero structure.
5880: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5881: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5882: merely zeroed.
5884: The user can set a value in the diagonal entry (or for the AIJ and
5885: row formats can optionally remove the main diagonal entry from the
5886: nonzero structure as well, by passing 0.0 as the final argument).
5888: For the parallel case, all processes that share the matrix (i.e.,
5889: those in the communicator used for matrix creation) MUST call this
5890: routine, regardless of whether any rows being zeroed are owned by
5891: them.
5893: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5894: list only rows local to itself).
5896: The grid coordinates are across the entire grid, not just the local portion
5898: In Fortran idxm and idxn should be declared as
5899: $ MatStencil idxm(4,m)
5900: and the values inserted using
5901: $ idxm(MatStencil_i,1) = i
5902: $ idxm(MatStencil_j,1) = j
5903: $ idxm(MatStencil_k,1) = k
5904: $ idxm(MatStencil_c,1) = c
5905: etc
5907: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5908: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5909: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5910: DM_BOUNDARY_PERIODIC boundary type.
5912: 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
5913: a single value per point) you can skip filling those indices.
5915: Level: intermediate
5917: Concepts: matrices^zeroing rows
5919: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5920: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5921: @*/
5922: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5923: {
5924: PetscInt dim = mat->stencil.dim;
5925: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5926: PetscInt *dims = mat->stencil.dims+1;
5927: PetscInt *starts = mat->stencil.starts;
5928: PetscInt *dxm = (PetscInt*) rows;
5929: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5937: PetscMalloc1(numRows, &jdxm);
5938: for (i = 0; i < numRows; ++i) {
5939: /* Skip unused dimensions (they are ordered k, j, i, c) */
5940: for (j = 0; j < 3-sdim; ++j) dxm++;
5941: /* Local index in X dir */
5942: tmp = *dxm++ - starts[0];
5943: /* Loop over remaining dimensions */
5944: for (j = 0; j < dim-1; ++j) {
5945: /* If nonlocal, set index to be negative */
5946: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5947: /* Update local index */
5948: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5949: }
5950: /* Skip component slot if necessary */
5951: if (mat->stencil.noc) dxm++;
5952: /* Local row number */
5953: if (tmp >= 0) {
5954: jdxm[numNewRows++] = tmp;
5955: }
5956: }
5957: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5958: PetscFree(jdxm);
5959: return(0);
5960: }
5962: /*@C
5963: MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5964: of a set of rows and columns of a matrix.
5966: Collective on Mat
5968: Input Parameters:
5969: + mat - the matrix
5970: . numRows - the number of rows/columns to remove
5971: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5972: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5973: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5974: - b - optional vector of right hand side, that will be adjusted by provided solution
5976: Notes:
5977: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5978: but does not release memory. For the dense and block diagonal
5979: formats this does not alter the nonzero structure.
5981: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5982: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5983: merely zeroed.
5985: The user can set a value in the diagonal entry (or for the AIJ and
5986: row formats can optionally remove the main diagonal entry from the
5987: nonzero structure as well, by passing 0.0 as the final argument).
5989: For the parallel case, all processes that share the matrix (i.e.,
5990: those in the communicator used for matrix creation) MUST call this
5991: routine, regardless of whether any rows being zeroed are owned by
5992: them.
5994: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5995: list only rows local to itself, but the row/column numbers are given in local numbering).
5997: The grid coordinates are across the entire grid, not just the local portion
5999: In Fortran idxm and idxn should be declared as
6000: $ MatStencil idxm(4,m)
6001: and the values inserted using
6002: $ idxm(MatStencil_i,1) = i
6003: $ idxm(MatStencil_j,1) = j
6004: $ idxm(MatStencil_k,1) = k
6005: $ idxm(MatStencil_c,1) = c
6006: etc
6008: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6009: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6010: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6011: DM_BOUNDARY_PERIODIC boundary type.
6013: 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
6014: a single value per point) you can skip filling those indices.
6016: Level: intermediate
6018: Concepts: matrices^zeroing rows
6020: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6021: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6022: @*/
6023: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6024: {
6025: PetscInt dim = mat->stencil.dim;
6026: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
6027: PetscInt *dims = mat->stencil.dims+1;
6028: PetscInt *starts = mat->stencil.starts;
6029: PetscInt *dxm = (PetscInt*) rows;
6030: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
6038: PetscMalloc1(numRows, &jdxm);
6039: for (i = 0; i < numRows; ++i) {
6040: /* Skip unused dimensions (they are ordered k, j, i, c) */
6041: for (j = 0; j < 3-sdim; ++j) dxm++;
6042: /* Local index in X dir */
6043: tmp = *dxm++ - starts[0];
6044: /* Loop over remaining dimensions */
6045: for (j = 0; j < dim-1; ++j) {
6046: /* If nonlocal, set index to be negative */
6047: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6048: /* Update local index */
6049: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6050: }
6051: /* Skip component slot if necessary */
6052: if (mat->stencil.noc) dxm++;
6053: /* Local row number */
6054: if (tmp >= 0) {
6055: jdxm[numNewRows++] = tmp;
6056: }
6057: }
6058: MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
6059: PetscFree(jdxm);
6060: return(0);
6061: }
6063: /*@C
6064: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6065: of a set of rows of a matrix; using local numbering of rows.
6067: Collective on Mat
6069: Input Parameters:
6070: + mat - the matrix
6071: . numRows - the number of rows to remove
6072: . rows - the global row indices
6073: . diag - value put in all diagonals of eliminated rows
6074: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6075: - b - optional vector of right hand side, that will be adjusted by provided solution
6077: Notes:
6078: Before calling MatZeroRowsLocal(), the user must first set the
6079: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6081: For the AIJ matrix formats this removes the old nonzero structure,
6082: but does not release memory. For the dense and block diagonal
6083: formats this does not alter the nonzero structure.
6085: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6086: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6087: merely zeroed.
6089: The user can set a value in the diagonal entry (or for the AIJ and
6090: row formats can optionally remove the main diagonal entry from the
6091: nonzero structure as well, by passing 0.0 as the final argument).
6093: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6094: owns that are to be zeroed. This saves a global synchronization in the implementation.
6096: Level: intermediate
6098: Concepts: matrices^zeroing
6100: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6101: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6102: @*/
6103: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6104: {
6111: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6112: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6113: MatCheckPreallocated(mat,1);
6115: if (mat->ops->zerorowslocal) {
6116: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6117: } else {
6118: IS is, newis;
6119: const PetscInt *newRows;
6121: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6122: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6123: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6124: ISGetIndices(newis,&newRows);
6125: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6126: ISRestoreIndices(newis,&newRows);
6127: ISDestroy(&newis);
6128: ISDestroy(&is);
6129: }
6130: PetscObjectStateIncrease((PetscObject)mat);
6131: #if defined(PETSC_HAVE_CUSP)
6132: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6133: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6134: }
6135: #elif defined(PETSC_HAVE_VIENNACL)
6136: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6137: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6138: }
6139: #elif defined(PETSC_HAVE_VECCUDA)
6140: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6141: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6142: }
6143: #endif
6144: return(0);
6145: }
6147: /*@C
6148: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6149: of a set of rows of a matrix; using local numbering of rows.
6151: Collective on Mat
6153: Input Parameters:
6154: + mat - the matrix
6155: . is - index set of rows to remove
6156: . diag - value put in all diagonals of eliminated rows
6157: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6158: - b - optional vector of right hand side, that will be adjusted by provided solution
6160: Notes:
6161: Before calling MatZeroRowsLocalIS(), the user must first set the
6162: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6164: For the AIJ matrix formats this removes the old nonzero structure,
6165: but does not release memory. For the dense and block diagonal
6166: formats this does not alter the nonzero structure.
6168: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6169: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6170: merely zeroed.
6172: The user can set a value in the diagonal entry (or for the AIJ and
6173: row formats can optionally remove the main diagonal entry from the
6174: nonzero structure as well, by passing 0.0 as the final argument).
6176: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6177: owns that are to be zeroed. This saves a global synchronization in the implementation.
6179: Level: intermediate
6181: Concepts: matrices^zeroing
6183: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6184: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6185: @*/
6186: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6187: {
6189: PetscInt numRows;
6190: const PetscInt *rows;
6196: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6197: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6198: MatCheckPreallocated(mat,1);
6200: ISGetLocalSize(is,&numRows);
6201: ISGetIndices(is,&rows);
6202: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6203: ISRestoreIndices(is,&rows);
6204: return(0);
6205: }
6207: /*@C
6208: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6209: of a set of rows and columns of a matrix; using local numbering of rows.
6211: Collective on Mat
6213: Input Parameters:
6214: + mat - the matrix
6215: . numRows - the number of rows to remove
6216: . rows - the global row indices
6217: . diag - value put in all diagonals of eliminated rows
6218: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6219: - b - optional vector of right hand side, that will be adjusted by provided solution
6221: Notes:
6222: Before calling MatZeroRowsColumnsLocal(), the user must first set the
6223: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6225: The user can set a value in the diagonal entry (or for the AIJ and
6226: row formats can optionally remove the main diagonal entry from the
6227: nonzero structure as well, by passing 0.0 as the final argument).
6229: Level: intermediate
6231: Concepts: matrices^zeroing
6233: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6234: MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6235: @*/
6236: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6237: {
6239: IS is, newis;
6240: const PetscInt *newRows;
6246: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6247: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6248: MatCheckPreallocated(mat,1);
6250: if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6251: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6252: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6253: ISGetIndices(newis,&newRows);
6254: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6255: ISRestoreIndices(newis,&newRows);
6256: ISDestroy(&newis);
6257: ISDestroy(&is);
6258: PetscObjectStateIncrease((PetscObject)mat);
6259: #if defined(PETSC_HAVE_CUSP)
6260: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6261: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6262: }
6263: #elif defined(PETSC_HAVE_VIENNACL)
6264: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6265: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6266: }
6267: #elif defined(PETSC_HAVE_VECCUDA)
6268: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6269: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6270: }
6271: #endif
6272: return(0);
6273: }
6275: /*@C
6276: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6277: of a set of rows and columns of a matrix; using local numbering of rows.
6279: Collective on Mat
6281: Input Parameters:
6282: + mat - the matrix
6283: . is - index set of rows to remove
6284: . diag - value put in all diagonals of eliminated rows
6285: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6286: - b - optional vector of right hand side, that will be adjusted by provided solution
6288: Notes:
6289: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6290: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6292: The user can set a value in the diagonal entry (or for the AIJ and
6293: row formats can optionally remove the main diagonal entry from the
6294: nonzero structure as well, by passing 0.0 as the final argument).
6296: Level: intermediate
6298: Concepts: matrices^zeroing
6300: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6301: MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6302: @*/
6303: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6304: {
6306: PetscInt numRows;
6307: const PetscInt *rows;
6313: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6314: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6315: MatCheckPreallocated(mat,1);
6317: ISGetLocalSize(is,&numRows);
6318: ISGetIndices(is,&rows);
6319: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6320: ISRestoreIndices(is,&rows);
6321: return(0);
6322: }
6324: /*@C
6325: MatGetSize - Returns the numbers of rows and columns in a matrix.
6327: Not Collective
6329: Input Parameter:
6330: . mat - the matrix
6332: Output Parameters:
6333: + m - the number of global rows
6334: - n - the number of global columns
6336: Note: both output parameters can be NULL on input.
6338: Level: beginner
6340: Concepts: matrices^size
6342: .seealso: MatGetLocalSize()
6343: @*/
6344: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6345: {
6348: if (m) *m = mat->rmap->N;
6349: if (n) *n = mat->cmap->N;
6350: return(0);
6351: }
6353: /*@C
6354: MatGetLocalSize - Returns the number of rows and columns in a matrix
6355: stored locally. This information may be implementation dependent, so
6356: use with care.
6358: Not Collective
6360: Input Parameters:
6361: . mat - the matrix
6363: Output Parameters:
6364: + m - the number of local rows
6365: - n - the number of local columns
6367: Note: both output parameters can be NULL on input.
6369: Level: beginner
6371: Concepts: matrices^local size
6373: .seealso: MatGetSize()
6374: @*/
6375: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6376: {
6381: if (m) *m = mat->rmap->n;
6382: if (n) *n = mat->cmap->n;
6383: return(0);
6384: }
6386: /*@
6387: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6388: this processor. (The columns of the "diagonal block")
6390: Not Collective, unless matrix has not been allocated, then collective on Mat
6392: Input Parameters:
6393: . mat - the matrix
6395: Output Parameters:
6396: + m - the global index of the first local column
6397: - n - one more than the global index of the last local column
6399: Notes: both output parameters can be NULL on input.
6401: Level: developer
6403: Concepts: matrices^column ownership
6405: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6407: @*/
6408: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6409: {
6415: MatCheckPreallocated(mat,1);
6416: if (m) *m = mat->cmap->rstart;
6417: if (n) *n = mat->cmap->rend;
6418: return(0);
6419: }
6421: /*@
6422: MatGetOwnershipRange - Returns the range of matrix rows owned by
6423: this processor, assuming that the matrix is laid out with the first
6424: n1 rows on the first processor, the next n2 rows on the second, etc.
6425: For certain parallel layouts this range may not be well defined.
6427: Not Collective
6429: Input Parameters:
6430: . mat - the matrix
6432: Output Parameters:
6433: + m - the global index of the first local row
6434: - n - one more than the global index of the last local row
6436: Note: Both output parameters can be NULL on input.
6437: $ This function requires that the matrix be preallocated. If you have not preallocated, consider using
6438: $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6439: $ and then MPI_Scan() to calculate prefix sums of the local sizes.
6441: Level: beginner
6443: Concepts: matrices^row ownership
6445: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6447: @*/
6448: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6449: {
6455: MatCheckPreallocated(mat,1);
6456: if (m) *m = mat->rmap->rstart;
6457: if (n) *n = mat->rmap->rend;
6458: return(0);
6459: }
6461: /*@C
6462: MatGetOwnershipRanges - Returns the range of matrix rows owned by
6463: each process
6465: Not Collective, unless matrix has not been allocated, then collective on Mat
6467: Input Parameters:
6468: . mat - the matrix
6470: Output Parameters:
6471: . ranges - start of each processors portion plus one more than the total length at the end
6473: Level: beginner
6475: Concepts: matrices^row ownership
6477: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6479: @*/
6480: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6481: {
6487: MatCheckPreallocated(mat,1);
6488: PetscLayoutGetRanges(mat->rmap,ranges);
6489: return(0);
6490: }
6492: /*@C
6493: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6494: this processor. (The columns of the "diagonal blocks" for each process)
6496: Not Collective, unless matrix has not been allocated, then collective on Mat
6498: Input Parameters:
6499: . mat - the matrix
6501: Output Parameters:
6502: . ranges - start of each processors portion plus one more then the total length at the end
6504: Level: beginner
6506: Concepts: matrices^column ownership
6508: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6510: @*/
6511: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6512: {
6518: MatCheckPreallocated(mat,1);
6519: PetscLayoutGetRanges(mat->cmap,ranges);
6520: return(0);
6521: }
6523: /*@C
6524: MatGetOwnershipIS - Get row and column ownership as index sets
6526: Not Collective
6528: Input Arguments:
6529: . A - matrix of type Elemental
6531: Output Arguments:
6532: + rows - rows in which this process owns elements
6533: . cols - columns in which this process owns elements
6535: Level: intermediate
6537: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6538: @*/
6539: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6540: {
6541: PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6544: MatCheckPreallocated(A,1);
6545: PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6546: if (f) {
6547: (*f)(A,rows,cols);
6548: } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6549: if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6550: if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6551: }
6552: return(0);
6553: }
6555: /*@C
6556: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6557: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6558: to complete the factorization.
6560: Collective on Mat
6562: Input Parameters:
6563: + mat - the matrix
6564: . row - row permutation
6565: . column - column permutation
6566: - info - structure containing
6567: $ levels - number of levels of fill.
6568: $ expected fill - as ratio of original fill.
6569: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6570: missing diagonal entries)
6572: Output Parameters:
6573: . fact - new matrix that has been symbolically factored
6575: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6577: Most users should employ the simplified KSP interface for linear solvers
6578: instead of working directly with matrix algebra routines such as this.
6579: See, e.g., KSPCreate().
6581: Level: developer
6583: Concepts: matrices^symbolic LU factorization
6584: Concepts: matrices^factorization
6585: Concepts: LU^symbolic factorization
6587: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6588: MatGetOrdering(), MatFactorInfo
6590: Developer Note: fortran interface is not autogenerated as the f90
6591: interface defintion cannot be generated correctly [due to MatFactorInfo]
6593: @*/
6594: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6595: {
6605: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6606: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6607: if (!(fact)->ops->ilufactorsymbolic) {
6608: const MatSolverPackage spackage;
6609: MatFactorGetSolverPackage(fact,&spackage);
6610: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6611: }
6612: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6613: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6614: MatCheckPreallocated(mat,2);
6616: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6617: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6618: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6619: return(0);
6620: }
6622: /*@C
6623: MatICCFactorSymbolic - Performs symbolic incomplete
6624: Cholesky factorization for a symmetric matrix. Use
6625: MatCholeskyFactorNumeric() to complete the factorization.
6627: Collective on Mat
6629: Input Parameters:
6630: + mat - the matrix
6631: . perm - row and column permutation
6632: - info - structure containing
6633: $ levels - number of levels of fill.
6634: $ expected fill - as ratio of original fill.
6636: Output Parameter:
6637: . fact - the factored matrix
6639: Notes:
6640: Most users should employ the KSP interface for linear solvers
6641: instead of working directly with matrix algebra routines such as this.
6642: See, e.g., KSPCreate().
6644: Level: developer
6646: Concepts: matrices^symbolic incomplete Cholesky factorization
6647: Concepts: matrices^factorization
6648: Concepts: Cholsky^symbolic factorization
6650: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6652: Developer Note: fortran interface is not autogenerated as the f90
6653: interface defintion cannot be generated correctly [due to MatFactorInfo]
6655: @*/
6656: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6657: {
6666: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6667: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6668: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6669: if (!(fact)->ops->iccfactorsymbolic) {
6670: const MatSolverPackage spackage;
6671: MatFactorGetSolverPackage(fact,&spackage);
6672: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6673: }
6674: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6675: MatCheckPreallocated(mat,2);
6677: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6678: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6679: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6680: return(0);
6681: }
6683: /*@C
6684: MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6685: points to an array of valid matrices, they may be reused to store the new
6686: submatrices.
6688: Collective on Mat
6690: Input Parameters:
6691: + mat - the matrix
6692: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6693: . irow, icol - index sets of rows and columns to extract
6694: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6696: Output Parameter:
6697: . submat - the array of submatrices
6699: Notes:
6700: MatCreateSubMatrices() can extract ONLY sequential submatrices
6701: (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6702: to extract a parallel submatrix.
6704: Some matrix types place restrictions on the row and column
6705: indices, such as that they be sorted or that they be equal to each other.
6707: The index sets may not have duplicate entries.
6709: When extracting submatrices from a parallel matrix, each processor can
6710: form a different submatrix by setting the rows and columns of its
6711: individual index sets according to the local submatrix desired.
6713: When finished using the submatrices, the user should destroy
6714: them with MatDestroyMatrices().
6716: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6717: original matrix has not changed from that last call to MatCreateSubMatrices().
6719: This routine creates the matrices in submat; you should NOT create them before
6720: calling it. It also allocates the array of matrix pointers submat.
6722: For BAIJ matrices the index sets must respect the block structure, that is if they
6723: request one row/column in a block, they must request all rows/columns that are in
6724: that block. For example, if the block size is 2 you cannot request just row 0 and
6725: column 0.
6727: Fortran Note:
6728: The Fortran interface is slightly different from that given below; it
6729: requires one to pass in as submat a Mat (integer) array of size at least m.
6731: Level: advanced
6733: Concepts: matrices^accessing submatrices
6734: Concepts: submatrices
6736: .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6737: @*/
6738: PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6739: {
6741: PetscInt i;
6742: PetscBool eq;
6747: if (n) {
6752: }
6754: if (n && scall == MAT_REUSE_MATRIX) {
6757: }
6758: if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6759: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6760: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6761: MatCheckPreallocated(mat,1);
6763: PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6764: (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);
6765: PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6766: for (i=0; i<n; i++) {
6767: (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */
6768: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6769: ISEqual(irow[i],icol[i],&eq);
6770: if (eq) {
6771: if (mat->symmetric) {
6772: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6773: } else if (mat->hermitian) {
6774: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6775: } else if (mat->structurally_symmetric) {
6776: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6777: }
6778: }
6779: }
6780: }
6781: return(0);
6782: }
6784: /*@C
6785: MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6787: Collective on Mat
6789: Input Parameters:
6790: + mat - the matrix
6791: . n - the number of submatrixes to be extracted
6792: . irow, icol - index sets of rows and columns to extract
6793: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6795: Output Parameter:
6796: . submat - the array of submatrices
6798: Level: advanced
6800: Concepts: matrices^accessing submatrices
6801: Concepts: submatrices
6803: .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6804: @*/
6805: PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6806: {
6808: PetscInt i;
6809: PetscBool eq;
6814: if (n) {
6819: }
6821: if (n && scall == MAT_REUSE_MATRIX) {
6824: }
6825: if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6826: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6827: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6828: MatCheckPreallocated(mat,1);
6830: PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6831: (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6832: PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6833: for (i=0; i<n; i++) {
6834: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6835: ISEqual(irow[i],icol[i],&eq);
6836: if (eq) {
6837: if (mat->symmetric) {
6838: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6839: } else if (mat->hermitian) {
6840: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6841: } else if (mat->structurally_symmetric) {
6842: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6843: }
6844: }
6845: }
6846: }
6847: return(0);
6848: }
6850: /*@C
6851: MatDestroyMatrices - Destroys an array of matrices.
6853: Collective on Mat
6855: Input Parameters:
6856: + n - the number of local matrices
6857: - mat - the matrices (note that this is a pointer to the array of matrices)
6859: Level: advanced
6861: Notes: Frees not only the matrices, but also the array that contains the matrices
6862: In Fortran will not free the array.
6864: .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6865: @*/
6866: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6867: {
6869: PetscInt i;
6872: if (!*mat) return(0);
6873: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6876: for (i=0; i<n; i++) {
6877: MatDestroy(&(*mat)[i]);
6878: }
6880: /* memory is allocated even if n = 0 */
6881: PetscFree(*mat);
6882: return(0);
6883: }
6885: /*@C
6886: MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6888: Collective on Mat
6890: Input Parameters:
6891: + n - the number of local matrices
6892: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6893: sequence of MatCreateSubMatrices())
6895: Level: advanced
6897: Notes: Frees not only the matrices, but also the array that contains the matrices
6898: In Fortran will not free the array.
6900: .seealso: MatCreateSubMatrices()
6901: @*/
6902: PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6903: {
6905: Mat mat0;
6908: if (!*mat) return(0);
6909: /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6910: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6913: mat0 = (*mat)[0];
6914: if (mat0 && mat0->ops->destroysubmatrices) {
6915: (mat0->ops->destroysubmatrices)(n,mat);
6916: } else {
6917: MatDestroyMatrices(n,mat);
6918: }
6919: return(0);
6920: }
6922: /*@C
6923: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6925: Collective on Mat
6927: Input Parameters:
6928: . mat - the matrix
6930: Output Parameter:
6931: . matstruct - the sequential matrix with the nonzero structure of mat
6933: Level: intermediate
6935: .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6936: @*/
6937: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6938: {
6946: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6947: MatCheckPreallocated(mat,1);
6949: if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6950: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6951: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6952: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6953: return(0);
6954: }
6956: /*@C
6957: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6959: Collective on Mat
6961: Input Parameters:
6962: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6963: sequence of MatGetSequentialNonzeroStructure())
6965: Level: advanced
6967: Notes: Frees not only the matrices, but also the array that contains the matrices
6969: .seealso: MatGetSeqNonzeroStructure()
6970: @*/
6971: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6972: {
6977: MatDestroy(mat);
6978: return(0);
6979: }
6981: /*@
6982: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6983: 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 MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7005: {
7011: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7012: if (n) {
7015: }
7016: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7017: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7018: MatCheckPreallocated(mat,1);
7020: if (!ov) return(0);
7021: if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7022: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
7023: (*mat->ops->increaseoverlap)(mat,n,is,ov);
7024: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
7025: return(0);
7026: }
7029: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7031: /*@
7032: MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7033: a sub communicator, replaces the index sets by larger ones that represent submatrices with
7034: additional overlap.
7036: Collective on Mat
7038: Input Parameters:
7039: + mat - the matrix
7040: . n - the number of index sets
7041: . is - the array of index sets (these index sets will changed during the call)
7042: - ov - the additional overlap requested
7044: Options Database:
7045: . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7047: Level: developer
7049: Concepts: overlap
7050: Concepts: ASM^computing overlap
7052: .seealso: MatCreateSubMatrices()
7053: @*/
7054: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7055: {
7056: PetscInt i;
7062: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7063: if (n) {
7066: }
7067: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7068: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7069: MatCheckPreallocated(mat,1);
7070: if (!ov) return(0);
7071: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
7072: for(i=0; i<n; i++){
7073: MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
7074: }
7075: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
7076: return(0);
7077: }
7082: /*@
7083: MatGetBlockSize - Returns the matrix block size.
7085: Not Collective
7087: Input Parameter:
7088: . mat - the matrix
7090: Output Parameter:
7091: . bs - block size
7093: Notes:
7094: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7096: If the block size has not been set yet this routine returns 1.
7098: Level: intermediate
7100: Concepts: matrices^block size
7102: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7103: @*/
7104: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7105: {
7109: *bs = PetscAbs(mat->rmap->bs);
7110: return(0);
7111: }
7113: /*@
7114: MatGetBlockSizes - Returns the matrix block row and column sizes.
7116: Not Collective
7118: Input Parameter:
7119: . mat - the matrix
7121: Output Parameter:
7122: . rbs - row block size
7123: . cbs - column block size
7125: Notes:
7126: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7127: If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7129: If a block size has not been set yet this routine returns 1.
7131: Level: intermediate
7133: Concepts: matrices^block size
7135: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7136: @*/
7137: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7138: {
7143: if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7144: if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7145: return(0);
7146: }
7148: /*@
7149: MatSetBlockSize - Sets the matrix block size.
7151: Logically Collective on Mat
7153: Input Parameters:
7154: + mat - the matrix
7155: - bs - block size
7157: Notes:
7158: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7159: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7161: For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7162: is compatible with the matrix local sizes.
7164: Level: intermediate
7166: Concepts: matrices^block size
7168: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7169: @*/
7170: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7171: {
7177: MatSetBlockSizes(mat,bs,bs);
7178: return(0);
7179: }
7181: /*@
7182: MatSetBlockSizes - Sets the matrix block row and column sizes.
7184: Logically Collective on Mat
7186: Input Parameters:
7187: + mat - the matrix
7188: - rbs - row block size
7189: - cbs - column block size
7191: Notes:
7192: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7193: If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7194: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7196: For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7197: are compatible with the matrix local sizes.
7199: The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7201: Level: intermediate
7203: Concepts: matrices^block size
7205: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7206: @*/
7207: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7208: {
7215: if (mat->ops->setblocksizes) {
7216: (*mat->ops->setblocksizes)(mat,rbs,cbs);
7217: }
7218: if (mat->rmap->refcnt) {
7219: ISLocalToGlobalMapping l2g = NULL;
7220: PetscLayout nmap = NULL;
7222: PetscLayoutDuplicate(mat->rmap,&nmap);
7223: if (mat->rmap->mapping) {
7224: ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);
7225: }
7226: PetscLayoutDestroy(&mat->rmap);
7227: mat->rmap = nmap;
7228: mat->rmap->mapping = l2g;
7229: }
7230: if (mat->cmap->refcnt) {
7231: ISLocalToGlobalMapping l2g = NULL;
7232: PetscLayout nmap = NULL;
7234: PetscLayoutDuplicate(mat->cmap,&nmap);
7235: if (mat->cmap->mapping) {
7236: ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);
7237: }
7238: PetscLayoutDestroy(&mat->cmap);
7239: mat->cmap = nmap;
7240: mat->cmap->mapping = l2g;
7241: }
7242: PetscLayoutSetBlockSize(mat->rmap,rbs);
7243: PetscLayoutSetBlockSize(mat->cmap,cbs);
7244: return(0);
7245: }
7247: /*@
7248: MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7250: Logically Collective on Mat
7252: Input Parameters:
7253: + mat - the matrix
7254: . fromRow - matrix from which to copy row block size
7255: - fromCol - matrix from which to copy column block size (can be same as fromRow)
7257: Level: developer
7259: Concepts: matrices^block size
7261: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7262: @*/
7263: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7264: {
7271: if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7272: if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7273: return(0);
7274: }
7276: /*@
7277: MatResidual - Default routine to calculate the residual.
7279: Collective on Mat and Vec
7281: Input Parameters:
7282: + mat - the matrix
7283: . b - the right-hand-side
7284: - x - the approximate solution
7286: Output Parameter:
7287: . r - location to store the residual
7289: Level: developer
7291: .keywords: MG, default, multigrid, residual
7293: .seealso: PCMGSetResidual()
7294: @*/
7295: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7296: {
7305: MatCheckPreallocated(mat,1);
7306: PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7307: if (!mat->ops->residual) {
7308: MatMult(mat,x,r);
7309: VecAYPX(r,-1.0,b);
7310: } else {
7311: (*mat->ops->residual)(mat,b,x,r);
7312: }
7313: PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7314: return(0);
7315: }
7317: /*@C
7318: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7320: Collective on Mat
7322: Input Parameters:
7323: + mat - the matrix
7324: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
7325: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
7326: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7327: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7328: always used.
7330: Output Parameters:
7331: + n - number of rows in the (possibly compressed) matrix
7332: . ia - the row pointers [of length n+1]
7333: . ja - the column indices
7334: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7335: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7337: Level: developer
7339: Notes:
7340: You CANNOT change any of the ia[] or ja[] values.
7342: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7344: Fortran Notes:
7345: In Fortran use
7346: $
7347: $ PetscInt ia(1), ja(1)
7348: $ PetscOffset iia, jja
7349: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7350: $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7352: or
7353: $
7354: $ PetscInt, pointer :: ia(:),ja(:)
7355: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7356: $ ! Access the ith and jth entries via ia(i) and ja(j)
7358: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7359: @*/
7360: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7361: {
7371: MatCheckPreallocated(mat,1);
7372: if (!mat->ops->getrowij) *done = PETSC_FALSE;
7373: else {
7374: *done = PETSC_TRUE;
7375: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7376: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7377: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7378: }
7379: return(0);
7380: }
7382: /*@C
7383: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
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 - number of columns in the (possibly compressed) matrix
7396: . ia - the column pointers
7397: - ja - the row indices
7399: Output Parameters:
7400: . done - PETSC_TRUE or PETSC_FALSE, indicating whether 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 MatRestoreColumnIJ() is invalid.
7407: Level: developer
7409: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7410: @*/
7411: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7412: {
7422: MatCheckPreallocated(mat,1);
7423: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7424: else {
7425: *done = PETSC_TRUE;
7426: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7427: }
7428: return(0);
7429: }
7431: /*@C
7432: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7433: MatGetRowIJ().
7435: Collective on Mat
7437: Input Parameters:
7438: + mat - the matrix
7439: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7440: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7441: symmetrized
7442: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7443: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7444: always used.
7445: . n - size of (possibly compressed) matrix
7446: . ia - the row pointers
7447: - ja - the column indices
7449: Output Parameters:
7450: . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7452: Note:
7453: This routine zeros out n, ia, and ja. This is to prevent accidental
7454: us of the array after it has been restored. If you pass NULL, it will
7455: not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid.
7457: Level: developer
7459: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7460: @*/
7461: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7462: {
7471: MatCheckPreallocated(mat,1);
7473: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7474: else {
7475: *done = PETSC_TRUE;
7476: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7477: if (n) *n = 0;
7478: if (ia) *ia = NULL;
7479: if (ja) *ja = NULL;
7480: }
7481: return(0);
7482: }
7484: /*@C
7485: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7486: MatGetColumnIJ().
7488: Collective on Mat
7490: Input Parameters:
7491: + mat - the matrix
7492: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7493: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7494: symmetrized
7495: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7496: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7497: always used.
7499: Output Parameters:
7500: + n - size of (possibly compressed) matrix
7501: . ia - the column pointers
7502: . ja - the row indices
7503: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7505: Level: developer
7507: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7508: @*/
7509: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7510: {
7519: MatCheckPreallocated(mat,1);
7521: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7522: else {
7523: *done = PETSC_TRUE;
7524: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7525: if (n) *n = 0;
7526: if (ia) *ia = NULL;
7527: if (ja) *ja = NULL;
7528: }
7529: return(0);
7530: }
7532: /*@C
7533: MatColoringPatch -Used inside matrix coloring routines that
7534: use MatGetRowIJ() and/or MatGetColumnIJ().
7536: Collective on Mat
7538: Input Parameters:
7539: + mat - the matrix
7540: . ncolors - max color value
7541: . n - number of entries in colorarray
7542: - colorarray - array indicating color for each column
7544: Output Parameters:
7545: . iscoloring - coloring generated using colorarray information
7547: Level: developer
7549: .seealso: MatGetRowIJ(), MatGetColumnIJ()
7551: @*/
7552: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7553: {
7561: MatCheckPreallocated(mat,1);
7563: if (!mat->ops->coloringpatch) {
7564: ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7565: } else {
7566: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7567: }
7568: return(0);
7569: }
7572: /*@
7573: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7575: Logically Collective on Mat
7577: Input Parameter:
7578: . mat - the factored matrix to be reset
7580: Notes:
7581: This routine should be used only with factored matrices formed by in-place
7582: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7583: format). This option can save memory, for example, when solving nonlinear
7584: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7585: ILU(0) preconditioner.
7587: Note that one can specify in-place ILU(0) factorization by calling
7588: .vb
7589: PCType(pc,PCILU);
7590: PCFactorSeUseInPlace(pc);
7591: .ve
7592: or by using the options -pc_type ilu -pc_factor_in_place
7594: In-place factorization ILU(0) can also be used as a local
7595: solver for the blocks within the block Jacobi or additive Schwarz
7596: methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc
7597: for details on setting local solver options.
7599: Most users should employ the simplified KSP interface for linear solvers
7600: instead of working directly with matrix algebra routines such as this.
7601: See, e.g., KSPCreate().
7603: Level: developer
7605: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7607: Concepts: matrices^unfactored
7609: @*/
7610: PetscErrorCode MatSetUnfactored(Mat mat)
7611: {
7617: MatCheckPreallocated(mat,1);
7618: mat->factortype = MAT_FACTOR_NONE;
7619: if (!mat->ops->setunfactored) return(0);
7620: (*mat->ops->setunfactored)(mat);
7621: return(0);
7622: }
7624: /*MC
7625: MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7627: Synopsis:
7628: MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7630: Not collective
7632: Input Parameter:
7633: . x - matrix
7635: Output Parameters:
7636: + xx_v - the Fortran90 pointer to the array
7637: - ierr - error code
7639: Example of Usage:
7640: .vb
7641: PetscScalar, pointer xx_v(:,:)
7642: ....
7643: call MatDenseGetArrayF90(x,xx_v,ierr)
7644: a = xx_v(3)
7645: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7646: .ve
7648: Level: advanced
7650: .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7652: Concepts: matrices^accessing array
7654: M*/
7656: /*MC
7657: MatDenseRestoreArrayF90 - Restores a matrix array that has been
7658: accessed with MatDenseGetArrayF90().
7660: Synopsis:
7661: MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7663: Not collective
7665: Input Parameters:
7666: + x - matrix
7667: - xx_v - the Fortran90 pointer to the array
7669: Output Parameter:
7670: . ierr - error code
7672: Example of Usage:
7673: .vb
7674: PetscScalar, pointer xx_v(:,:)
7675: ....
7676: call MatDenseGetArrayF90(x,xx_v,ierr)
7677: a = xx_v(3)
7678: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7679: .ve
7681: Level: advanced
7683: .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7685: M*/
7688: /*MC
7689: MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7691: Synopsis:
7692: MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7694: Not collective
7696: Input Parameter:
7697: . x - matrix
7699: Output Parameters:
7700: + xx_v - the Fortran90 pointer to the array
7701: - ierr - error code
7703: Example of Usage:
7704: .vb
7705: PetscScalar, pointer xx_v(:)
7706: ....
7707: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7708: a = xx_v(3)
7709: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7710: .ve
7712: Level: advanced
7714: .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7716: Concepts: matrices^accessing array
7718: M*/
7720: /*MC
7721: MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7722: accessed with MatSeqAIJGetArrayF90().
7724: Synopsis:
7725: MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7727: Not collective
7729: Input Parameters:
7730: + x - matrix
7731: - xx_v - the Fortran90 pointer to the array
7733: Output Parameter:
7734: . ierr - error code
7736: Example of Usage:
7737: .vb
7738: PetscScalar, pointer xx_v(:)
7739: ....
7740: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7741: a = xx_v(3)
7742: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7743: .ve
7745: Level: advanced
7747: .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7749: M*/
7752: /*@
7753: MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7754: as the original matrix.
7756: Collective on Mat
7758: Input Parameters:
7759: + mat - the original matrix
7760: . isrow - parallel IS containing the rows this processor should obtain
7761: . 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.
7762: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7764: Output Parameter:
7765: . newmat - the new submatrix, of the same type as the old
7767: Level: advanced
7769: Notes:
7770: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7772: Some matrix types place restrictions on the row and column indices, such
7773: as that they be sorted or that they be equal to each other.
7775: The index sets may not have duplicate entries.
7777: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7778: the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7779: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7780: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7781: you are finished using it.
7783: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7784: the input matrix.
7786: If iscol is NULL then all columns are obtained (not supported in Fortran).
7788: Example usage:
7789: Consider the following 8x8 matrix with 34 non-zero values, that is
7790: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7791: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7792: as follows:
7794: .vb
7795: 1 2 0 | 0 3 0 | 0 4
7796: Proc0 0 5 6 | 7 0 0 | 8 0
7797: 9 0 10 | 11 0 0 | 12 0
7798: -------------------------------------
7799: 13 0 14 | 15 16 17 | 0 0
7800: Proc1 0 18 0 | 19 20 21 | 0 0
7801: 0 0 0 | 22 23 0 | 24 0
7802: -------------------------------------
7803: Proc2 25 26 27 | 0 0 28 | 29 0
7804: 30 0 0 | 31 32 33 | 0 34
7805: .ve
7807: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7809: .vb
7810: 2 0 | 0 3 0 | 0
7811: Proc0 5 6 | 7 0 0 | 8
7812: -------------------------------
7813: Proc1 18 0 | 19 20 21 | 0
7814: -------------------------------
7815: Proc2 26 27 | 0 0 28 | 29
7816: 0 0 | 31 32 33 | 0
7817: .ve
7820: Concepts: matrices^submatrices
7822: .seealso: MatCreateSubMatrices()
7823: @*/
7824: PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7825: {
7827: PetscMPIInt size;
7828: Mat *local;
7829: IS iscoltmp;
7838: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7839: if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7841: MatCheckPreallocated(mat,1);
7842: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7844: if (!iscol || isrow == iscol) {
7845: PetscBool stride;
7846: PetscMPIInt grabentirematrix = 0,grab;
7847: PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7848: if (stride) {
7849: PetscInt first,step,n,rstart,rend;
7850: ISStrideGetInfo(isrow,&first,&step);
7851: if (step == 1) {
7852: MatGetOwnershipRange(mat,&rstart,&rend);
7853: if (rstart == first) {
7854: ISGetLocalSize(isrow,&n);
7855: if (n == rend-rstart) {
7856: grabentirematrix = 1;
7857: }
7858: }
7859: }
7860: }
7861: MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7862: if (grab) {
7863: PetscInfo(mat,"Getting entire matrix as submatrix\n");
7864: if (cll == MAT_INITIAL_MATRIX) {
7865: *newmat = mat;
7866: PetscObjectReference((PetscObject)mat);
7867: }
7868: return(0);
7869: }
7870: }
7872: if (!iscol) {
7873: ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7874: } else {
7875: iscoltmp = iscol;
7876: }
7878: /* if original matrix is on just one processor then use submatrix generated */
7879: if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7880: MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7881: if (!iscol) {ISDestroy(&iscoltmp);}
7882: return(0);
7883: } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7884: MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7885: *newmat = *local;
7886: PetscFree(local);
7887: if (!iscol) {ISDestroy(&iscoltmp);}
7888: return(0);
7889: } else if (!mat->ops->createsubmatrix) {
7890: /* Create a new matrix type that implements the operation using the full matrix */
7891: PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7892: switch (cll) {
7893: case MAT_INITIAL_MATRIX:
7894: MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);
7895: break;
7896: case MAT_REUSE_MATRIX:
7897: MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);
7898: break;
7899: default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7900: }
7901: PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);
7902: if (!iscol) {ISDestroy(&iscoltmp);}
7903: return(0);
7904: }
7906: if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7907: PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7908: (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7909: PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);
7910: if (!iscol) {ISDestroy(&iscoltmp);}
7911: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7912: return(0);
7913: }
7915: /*@
7916: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7917: used during the assembly process to store values that belong to
7918: other processors.
7920: Not Collective
7922: Input Parameters:
7923: + mat - the matrix
7924: . size - the initial size of the stash.
7925: - bsize - the initial size of the block-stash(if used).
7927: Options Database Keys:
7928: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7929: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7931: Level: intermediate
7933: Notes:
7934: The block-stash is used for values set with MatSetValuesBlocked() while
7935: the stash is used for values set with MatSetValues()
7937: Run with the option -info and look for output of the form
7938: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7939: to determine the appropriate value, MM, to use for size and
7940: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7941: to determine the value, BMM to use for bsize
7943: Concepts: stash^setting matrix size
7944: Concepts: matrices^stash
7946: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7948: @*/
7949: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7950: {
7956: MatStashSetInitialSize_Private(&mat->stash,size);
7957: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7958: return(0);
7959: }
7961: /*@
7962: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7963: the matrix
7965: Neighbor-wise Collective on Mat
7967: Input Parameters:
7968: + mat - the matrix
7969: . x,y - the vectors
7970: - w - where the result is stored
7972: Level: intermediate
7974: Notes:
7975: w may be the same vector as y.
7977: This allows one to use either the restriction or interpolation (its transpose)
7978: matrix to do the interpolation
7980: Concepts: interpolation
7982: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7984: @*/
7985: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7986: {
7988: PetscInt M,N,Ny;
7996: MatCheckPreallocated(A,1);
7997: MatGetSize(A,&M,&N);
7998: VecGetSize(y,&Ny);
7999: if (M == Ny) {
8000: MatMultAdd(A,x,y,w);
8001: } else {
8002: MatMultTransposeAdd(A,x,y,w);
8003: }
8004: return(0);
8005: }
8007: /*@
8008: MatInterpolate - y = A*x or A'*x depending on the shape of
8009: the matrix
8011: Neighbor-wise Collective on Mat
8013: Input Parameters:
8014: + mat - the matrix
8015: - x,y - the vectors
8017: Level: intermediate
8019: Notes:
8020: This allows one to use either the restriction or interpolation (its transpose)
8021: matrix to do the interpolation
8023: Concepts: matrices^interpolation
8025: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8027: @*/
8028: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8029: {
8031: PetscInt M,N,Ny;
8038: MatCheckPreallocated(A,1);
8039: MatGetSize(A,&M,&N);
8040: VecGetSize(y,&Ny);
8041: if (M == Ny) {
8042: MatMult(A,x,y);
8043: } else {
8044: MatMultTranspose(A,x,y);
8045: }
8046: return(0);
8047: }
8049: /*@
8050: MatRestrict - y = A*x or A'*x
8052: Neighbor-wise Collective on Mat
8054: Input Parameters:
8055: + mat - the matrix
8056: - x,y - the vectors
8058: Level: intermediate
8060: Notes:
8061: This allows one to use either the restriction or interpolation (its transpose)
8062: matrix to do the restriction
8064: Concepts: matrices^restriction
8066: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8068: @*/
8069: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8070: {
8072: PetscInt M,N,Ny;
8079: MatCheckPreallocated(A,1);
8081: MatGetSize(A,&M,&N);
8082: VecGetSize(y,&Ny);
8083: if (M == Ny) {
8084: MatMult(A,x,y);
8085: } else {
8086: MatMultTranspose(A,x,y);
8087: }
8088: return(0);
8089: }
8091: /*@
8092: MatGetNullSpace - retrieves the null space to a matrix.
8094: Logically Collective on Mat and MatNullSpace
8096: Input Parameters:
8097: + mat - the matrix
8098: - nullsp - the null space object
8100: Level: developer
8102: Concepts: null space^attaching to matrix
8104: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8105: @*/
8106: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8107: {
8112: *nullsp = mat->nullsp;
8113: return(0);
8114: }
8116: /*@
8117: MatSetNullSpace - attaches a null space to a matrix.
8119: Logically Collective on Mat and MatNullSpace
8121: Input Parameters:
8122: + mat - the matrix
8123: - nullsp - the null space object
8125: Level: advanced
8127: Notes:
8128: This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8130: For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8131: call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8133: You can remove the null space by calling this routine with an nullsp of NULL
8136: The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8137: 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).
8138: 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
8139: 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
8140: 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).
8142: Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8144: 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
8145: routine also automatically calls MatSetTransposeNullSpace().
8147: Concepts: null space^attaching to matrix
8149: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8150: @*/
8151: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8152: {
8159: MatCheckPreallocated(mat,1);
8160: if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8161: MatNullSpaceDestroy(&mat->nullsp);
8162: mat->nullsp = nullsp;
8163: if (mat->symmetric_set && mat->symmetric) {
8164: MatSetTransposeNullSpace(mat,nullsp);
8165: }
8166: return(0);
8167: }
8169: /*@
8170: MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8172: Logically Collective on Mat and MatNullSpace
8174: Input Parameters:
8175: + mat - the matrix
8176: - nullsp - the null space object
8178: Level: developer
8180: Concepts: null space^attaching to matrix
8182: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8183: @*/
8184: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8185: {
8190: *nullsp = mat->transnullsp;
8191: return(0);
8192: }
8194: /*@
8195: MatSetTransposeNullSpace - attaches a null space to a matrix.
8197: Logically Collective on Mat and MatNullSpace
8199: Input Parameters:
8200: + mat - the matrix
8201: - nullsp - the null space object
8203: Level: advanced
8205: Notes:
8206: 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.
8207: You must also call MatSetNullSpace()
8210: The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8211: 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).
8212: 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
8213: 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
8214: 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).
8216: Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8218: Concepts: null space^attaching to matrix
8220: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8221: @*/
8222: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8223: {
8230: MatCheckPreallocated(mat,1);
8231: PetscObjectReference((PetscObject)nullsp);
8232: MatNullSpaceDestroy(&mat->transnullsp);
8233: mat->transnullsp = nullsp;
8234: return(0);
8235: }
8237: /*@
8238: MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8239: This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8241: Logically Collective on Mat and MatNullSpace
8243: Input Parameters:
8244: + mat - the matrix
8245: - nullsp - the null space object
8247: Level: advanced
8249: Notes:
8250: Overwrites any previous near null space that may have been attached
8252: You can remove the null space by calling this routine with an nullsp of NULL
8254: Concepts: null space^attaching to matrix
8256: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8257: @*/
8258: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8259: {
8266: MatCheckPreallocated(mat,1);
8267: if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8268: MatNullSpaceDestroy(&mat->nearnullsp);
8269: mat->nearnullsp = nullsp;
8270: return(0);
8271: }
8273: /*@
8274: MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8276: Not Collective
8278: Input Parameters:
8279: . mat - the matrix
8281: Output Parameters:
8282: . nullsp - the null space object, NULL if not set
8284: Level: developer
8286: Concepts: null space^attaching to matrix
8288: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8289: @*/
8290: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8291: {
8296: MatCheckPreallocated(mat,1);
8297: *nullsp = mat->nearnullsp;
8298: return(0);
8299: }
8301: /*@C
8302: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8304: Collective on Mat
8306: Input Parameters:
8307: + mat - the matrix
8308: . row - row/column permutation
8309: . fill - expected fill factor >= 1.0
8310: - level - level of fill, for ICC(k)
8312: Notes:
8313: Probably really in-place only when level of fill is zero, otherwise allocates
8314: new space to store factored matrix and deletes previous memory.
8316: Most users should employ the simplified KSP interface for linear solvers
8317: instead of working directly with matrix algebra routines such as this.
8318: See, e.g., KSPCreate().
8320: Level: developer
8322: Concepts: matrices^incomplete Cholesky factorization
8323: Concepts: Cholesky factorization
8325: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8327: Developer Note: fortran interface is not autogenerated as the f90
8328: interface defintion cannot be generated correctly [due to MatFactorInfo]
8330: @*/
8331: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8332: {
8340: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8341: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8342: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8343: if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8344: MatCheckPreallocated(mat,1);
8345: (*mat->ops->iccfactor)(mat,row,info);
8346: PetscObjectStateIncrease((PetscObject)mat);
8347: return(0);
8348: }
8350: /*@
8351: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8352: ghosted ones.
8354: Not Collective
8356: Input Parameters:
8357: + mat - the matrix
8358: - diag = the diagonal values, including ghost ones
8360: Level: developer
8362: Notes: Works only for MPIAIJ and MPIBAIJ matrices
8364: .seealso: MatDiagonalScale()
8365: @*/
8366: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8367: {
8369: PetscMPIInt size;
8376: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8377: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8378: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8379: if (size == 1) {
8380: PetscInt n,m;
8381: VecGetSize(diag,&n);
8382: MatGetSize(mat,0,&m);
8383: if (m == n) {
8384: MatDiagonalScale(mat,0,diag);
8385: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8386: } else {
8387: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8388: }
8389: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8390: PetscObjectStateIncrease((PetscObject)mat);
8391: return(0);
8392: }
8394: /*@
8395: MatGetInertia - Gets the inertia from a factored matrix
8397: Collective on Mat
8399: Input Parameter:
8400: . mat - the matrix
8402: Output Parameters:
8403: + nneg - number of negative eigenvalues
8404: . nzero - number of zero eigenvalues
8405: - npos - number of positive eigenvalues
8407: Level: advanced
8409: Notes: Matrix must have been factored by MatCholeskyFactor()
8412: @*/
8413: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8414: {
8420: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8421: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8422: if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8423: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8424: return(0);
8425: }
8427: /* ----------------------------------------------------------------*/
8428: /*@C
8429: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8431: Neighbor-wise Collective on Mat and Vecs
8433: Input Parameters:
8434: + mat - the factored matrix
8435: - b - the right-hand-side vectors
8437: Output Parameter:
8438: . x - the result vectors
8440: Notes:
8441: The vectors b and x cannot be the same. I.e., one cannot
8442: call MatSolves(A,x,x).
8444: Notes:
8445: Most users should employ the simplified KSP interface for linear solvers
8446: instead of working directly with matrix algebra routines such as this.
8447: See, e.g., KSPCreate().
8449: Level: developer
8451: Concepts: matrices^triangular solves
8453: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8454: @*/
8455: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8456: {
8462: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8463: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8464: if (!mat->rmap->N && !mat->cmap->N) return(0);
8466: if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8467: MatCheckPreallocated(mat,1);
8468: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8469: (*mat->ops->solves)(mat,b,x);
8470: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8471: return(0);
8472: }
8474: /*@
8475: MatIsSymmetric - Test whether a matrix is symmetric
8477: Collective on Mat
8479: Input Parameter:
8480: + A - the matrix to test
8481: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8483: Output Parameters:
8484: . flg - the result
8486: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8488: Level: intermediate
8490: Concepts: matrix^symmetry
8492: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8493: @*/
8494: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
8495: {
8502: if (!A->symmetric_set) {
8503: if (!A->ops->issymmetric) {
8504: MatType mattype;
8505: MatGetType(A,&mattype);
8506: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8507: }
8508: (*A->ops->issymmetric)(A,tol,flg);
8509: if (!tol) {
8510: A->symmetric_set = PETSC_TRUE;
8511: A->symmetric = *flg;
8512: if (A->symmetric) {
8513: A->structurally_symmetric_set = PETSC_TRUE;
8514: A->structurally_symmetric = PETSC_TRUE;
8515: }
8516: }
8517: } else if (A->symmetric) {
8518: *flg = PETSC_TRUE;
8519: } else if (!tol) {
8520: *flg = PETSC_FALSE;
8521: } else {
8522: if (!A->ops->issymmetric) {
8523: MatType mattype;
8524: MatGetType(A,&mattype);
8525: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8526: }
8527: (*A->ops->issymmetric)(A,tol,flg);
8528: }
8529: return(0);
8530: }
8532: /*@
8533: MatIsHermitian - Test whether a matrix is Hermitian
8535: Collective on Mat
8537: Input Parameter:
8538: + A - the matrix to test
8539: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8541: Output Parameters:
8542: . flg - the result
8544: Level: intermediate
8546: Concepts: matrix^symmetry
8548: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8549: MatIsSymmetricKnown(), MatIsSymmetric()
8550: @*/
8551: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
8552: {
8559: if (!A->hermitian_set) {
8560: if (!A->ops->ishermitian) {
8561: MatType mattype;
8562: MatGetType(A,&mattype);
8563: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8564: }
8565: (*A->ops->ishermitian)(A,tol,flg);
8566: if (!tol) {
8567: A->hermitian_set = PETSC_TRUE;
8568: A->hermitian = *flg;
8569: if (A->hermitian) {
8570: A->structurally_symmetric_set = PETSC_TRUE;
8571: A->structurally_symmetric = PETSC_TRUE;
8572: }
8573: }
8574: } else if (A->hermitian) {
8575: *flg = PETSC_TRUE;
8576: } else if (!tol) {
8577: *flg = PETSC_FALSE;
8578: } else {
8579: if (!A->ops->ishermitian) {
8580: MatType mattype;
8581: MatGetType(A,&mattype);
8582: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8583: }
8584: (*A->ops->ishermitian)(A,tol,flg);
8585: }
8586: return(0);
8587: }
8589: /*@
8590: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8592: Not Collective
8594: Input Parameter:
8595: . A - the matrix to check
8597: Output Parameters:
8598: + set - if the symmetric flag is set (this tells you if the next flag is valid)
8599: - flg - the result
8601: Level: advanced
8603: Concepts: matrix^symmetry
8605: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8606: if you want it explicitly checked
8608: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8609: @*/
8610: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
8611: {
8616: if (A->symmetric_set) {
8617: *set = PETSC_TRUE;
8618: *flg = A->symmetric;
8619: } else {
8620: *set = PETSC_FALSE;
8621: }
8622: return(0);
8623: }
8625: /*@
8626: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8628: Not Collective
8630: Input Parameter:
8631: . A - the matrix to check
8633: Output Parameters:
8634: + set - if the hermitian flag is set (this tells you if the next flag is valid)
8635: - flg - the result
8637: Level: advanced
8639: Concepts: matrix^symmetry
8641: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8642: if you want it explicitly checked
8644: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8645: @*/
8646: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8647: {
8652: if (A->hermitian_set) {
8653: *set = PETSC_TRUE;
8654: *flg = A->hermitian;
8655: } else {
8656: *set = PETSC_FALSE;
8657: }
8658: return(0);
8659: }
8661: /*@
8662: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8664: Collective on Mat
8666: Input Parameter:
8667: . A - the matrix to test
8669: Output Parameters:
8670: . flg - the result
8672: Level: intermediate
8674: Concepts: matrix^symmetry
8676: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8677: @*/
8678: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8679: {
8685: if (!A->structurally_symmetric_set) {
8686: if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8687: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8689: A->structurally_symmetric_set = PETSC_TRUE;
8690: }
8691: *flg = A->structurally_symmetric;
8692: return(0);
8693: }
8695: /*@
8696: MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8697: to be communicated to other processors during the MatAssemblyBegin/End() process
8699: Not collective
8701: Input Parameter:
8702: . vec - the vector
8704: Output Parameters:
8705: + nstash - the size of the stash
8706: . reallocs - the number of additional mallocs incurred.
8707: . bnstash - the size of the block stash
8708: - breallocs - the number of additional mallocs incurred.in the block stash
8710: Level: advanced
8712: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8714: @*/
8715: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8716: {
8720: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8721: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8722: return(0);
8723: }
8725: /*@C
8726: MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8727: parallel layout
8729: Collective on Mat
8731: Input Parameter:
8732: . mat - the matrix
8734: Output Parameter:
8735: + right - (optional) vector that the matrix can be multiplied against
8736: - left - (optional) vector that the matrix vector product can be stored in
8738: Notes:
8739: 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().
8741: Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8743: Level: advanced
8745: .seealso: MatCreate(), VecDestroy()
8746: @*/
8747: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8748: {
8754: if (mat->ops->getvecs) {
8755: (*mat->ops->getvecs)(mat,right,left);
8756: } else {
8757: PetscInt rbs,cbs;
8758: MatGetBlockSizes(mat,&rbs,&cbs);
8759: if (right) {
8760: if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8761: VecCreate(PetscObjectComm((PetscObject)mat),right);
8762: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8763: VecSetBlockSize(*right,cbs);
8764: VecSetType(*right,VECSTANDARD);
8765: PetscLayoutReference(mat->cmap,&(*right)->map);
8766: }
8767: if (left) {
8768: if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8769: VecCreate(PetscObjectComm((PetscObject)mat),left);
8770: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8771: VecSetBlockSize(*left,rbs);
8772: VecSetType(*left,VECSTANDARD);
8773: PetscLayoutReference(mat->rmap,&(*left)->map);
8774: }
8775: }
8776: return(0);
8777: }
8779: /*@C
8780: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8781: with default values.
8783: Not Collective
8785: Input Parameters:
8786: . info - the MatFactorInfo data structure
8789: Notes: The solvers are generally used through the KSP and PC objects, for example
8790: PCLU, PCILU, PCCHOLESKY, PCICC
8792: Level: developer
8794: .seealso: MatFactorInfo
8796: Developer Note: fortran interface is not autogenerated as the f90
8797: interface defintion cannot be generated correctly [due to MatFactorInfo]
8799: @*/
8801: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8802: {
8806: PetscMemzero(info,sizeof(MatFactorInfo));
8807: return(0);
8808: }
8810: /*@
8811: MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8813: Collective on Mat
8815: Input Parameters:
8816: + mat - the factored matrix
8817: - is - the index set defining the Schur indices (0-based)
8819: Notes: Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8821: You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8823: Level: developer
8825: Concepts:
8827: .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8828: MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8830: @*/
8831: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8832: {
8833: PetscErrorCode ierr,(*f)(Mat,IS);
8841: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8842: PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8843: if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverPackage does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
8844: if (mat->schur) {
8845: MatDestroy(&mat->schur);
8846: }
8847: (*f)(mat,is);
8848: if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8849: MatFactorSetUpInPlaceSchur_Private(mat);
8850: return(0);
8851: }
8853: /*@
8854: MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8856: Logically Collective on Mat
8858: Input Parameters:
8859: + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8860: . S - location where to return the Schur complement, can be NULL
8861: - status - the status of the Schur complement matrix, can be NULL
8863: Notes:
8864: You must call MatFactorSetSchurIS() before calling this routine.
8866: The routine provides a copy of the Schur matrix stored within the solver data structures.
8867: The caller must destroy the object when it is no longer needed.
8868: If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8870: 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)
8872: Developer Notes: The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
8873: matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8875: See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8877: Level: advanced
8879: References:
8881: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8882: @*/
8883: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8884: {
8891: if (S) {
8892: PetscErrorCode (*f)(Mat,Mat*);
8894: PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);
8895: if (f) {
8896: (*f)(F,S);
8897: } else {
8898: MatDuplicate(F->schur,MAT_COPY_VALUES,S);
8899: }
8900: }
8901: if (status) *status = F->schur_status;
8902: return(0);
8903: }
8905: /*@
8906: MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8908: Logically Collective on Mat
8910: Input Parameters:
8911: + F - the factored matrix obtained by calling MatGetFactor()
8912: . *S - location where to return the Schur complement, can be NULL
8913: - status - the status of the Schur complement matrix, can be NULL
8915: Notes:
8916: You must call MatFactorSetSchurIS() before calling this routine.
8918: Schur complement mode is currently implemented for sequential matrices.
8919: The routine returns a the Schur Complement stored within the data strutures of the solver.
8920: If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8921: The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8923: Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8925: See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8927: Level: advanced
8929: References:
8931: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8932: @*/
8933: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8934: {
8939: if (S) *S = F->schur;
8940: if (status) *status = F->schur_status;
8941: return(0);
8942: }
8944: /*@
8945: MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8947: Logically Collective on Mat
8949: Input Parameters:
8950: + F - the factored matrix obtained by calling MatGetFactor()
8951: . *S - location where the Schur complement is stored
8952: - status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8954: Notes:
8956: Level: advanced
8958: References:
8960: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8961: @*/
8962: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8963: {
8968: if (S) {
8970: *S = NULL;
8971: }
8972: F->schur_status = status;
8973: MatFactorUpdateSchurStatus_Private(F);
8974: return(0);
8975: }
8977: /*@
8978: MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8980: Logically Collective on Mat
8982: Input Parameters:
8983: + F - the factored matrix obtained by calling MatGetFactor()
8984: . rhs - location where the right hand side of the Schur complement system is stored
8985: - sol - location where the solution of the Schur complement system has to be returned
8987: Notes:
8988: The sizes of the vectors should match the size of the Schur complement
8990: Must be called after MatFactorSetSchurIS()
8992: Level: advanced
8994: References:
8996: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8997: @*/
8998: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8999: {
9011: MatFactorFactorizeSchurComplement(F);
9012: switch (F->schur_status) {
9013: case MAT_FACTOR_SCHUR_FACTORED:
9014: MatSolveTranspose(F->schur,rhs,sol);
9015: break;
9016: case MAT_FACTOR_SCHUR_INVERTED:
9017: MatMultTranspose(F->schur,rhs,sol);
9018: break;
9019: default:
9020: SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9021: break;
9022: }
9023: return(0);
9024: }
9026: /*@
9027: MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9029: Logically Collective on Mat
9031: Input Parameters:
9032: + F - the factored matrix obtained by calling MatGetFactor()
9033: . rhs - location where the right hand side of the Schur complement system is stored
9034: - sol - location where the solution of the Schur complement system has to be returned
9036: Notes:
9037: The sizes of the vectors should match the size of the Schur complement
9039: Must be called after MatFactorSetSchurIS()
9041: Level: advanced
9043: References:
9045: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9046: @*/
9047: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9048: {
9060: MatFactorFactorizeSchurComplement(F);
9061: switch (F->schur_status) {
9062: case MAT_FACTOR_SCHUR_FACTORED:
9063: MatSolve(F->schur,rhs,sol);
9064: break;
9065: case MAT_FACTOR_SCHUR_INVERTED:
9066: MatMult(F->schur,rhs,sol);
9067: break;
9068: default:
9069: SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9070: break;
9071: }
9072: return(0);
9073: }
9075: /*@
9076: MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9078: Logically Collective on Mat
9080: Input Parameters:
9081: + F - the factored matrix obtained by calling MatGetFactor()
9083: Notes: Must be called after MatFactorSetSchurIS().
9085: Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9087: Level: advanced
9089: References:
9091: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9092: @*/
9093: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9094: {
9100: if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) return(0);
9101: MatFactorFactorizeSchurComplement(F);
9102: MatFactorInvertSchurComplement_Private(F);
9103: F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9104: return(0);
9105: }
9107: /*@
9108: MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9110: Logically Collective on Mat
9112: Input Parameters:
9113: + F - the factored matrix obtained by calling MatGetFactor()
9115: Notes: Must be called after MatFactorSetSchurIS().
9117: Level: advanced
9119: References:
9121: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9122: @*/
9123: PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9124: {
9130: if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) return(0);
9131: MatFactorFactorizeSchurComplement_Private(F);
9132: F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9133: return(0);
9134: }
9136: /*@
9137: MatPtAP - Creates the matrix product C = P^T * A * P
9139: Neighbor-wise Collective on Mat
9141: Input Parameters:
9142: + A - the matrix
9143: . P - the projection matrix
9144: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9145: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9146: if the result is a dense matrix this is irrelevent
9148: Output Parameters:
9149: . C - the product matrix
9151: Notes:
9152: C will be created and must be destroyed by the user with MatDestroy().
9154: This routine is currently only implemented for pairs of AIJ matrices and classes
9155: which inherit from AIJ.
9157: Level: intermediate
9159: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9160: @*/
9161: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9162: {
9164: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9165: PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9166: PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9167: PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
9170: PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
9171: PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);
9175: MatCheckPreallocated(A,1);
9176: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9177: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9178: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9181: MatCheckPreallocated(P,2);
9182: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9183: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9185: 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);
9186: 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);
9187: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9188: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9190: if (scall == MAT_REUSE_MATRIX) {
9193: if (viatranspose || viamatmatmatmult) {
9194: Mat Pt;
9195: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9196: if (viamatmatmatmult) {
9197: MatMatMatMult(Pt,A,P,scall,fill,C);
9198: } else {
9199: Mat AP;
9200: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9201: MatMatMult(Pt,AP,scall,fill,C);
9202: MatDestroy(&AP);
9203: }
9204: MatDestroy(&Pt);
9205: } else {
9206: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9207: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9208: (*(*C)->ops->ptapnumeric)(A,P,*C);
9209: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9210: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9211: }
9212: return(0);
9213: }
9215: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9216: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9218: fA = A->ops->ptap;
9219: fP = P->ops->ptap;
9220: if (fP == fA) {
9221: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9222: ptap = fA;
9223: } else {
9224: /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9225: char ptapname[256];
9226: PetscStrcpy(ptapname,"MatPtAP_");
9227: PetscStrcat(ptapname,((PetscObject)A)->type_name);
9228: PetscStrcat(ptapname,"_");
9229: PetscStrcat(ptapname,((PetscObject)P)->type_name);
9230: PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9231: PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9232: 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);
9233: }
9235: if (viatranspose || viamatmatmatmult) {
9236: Mat Pt;
9237: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9238: if (viamatmatmatmult) {
9239: MatMatMatMult(Pt,A,P,scall,fill,C);
9240: PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
9241: } else {
9242: Mat AP;
9243: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9244: MatMatMult(Pt,AP,scall,fill,C);
9245: MatDestroy(&AP);
9246: PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
9247: }
9248: MatDestroy(&Pt);
9249: } else {
9250: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9251: (*ptap)(A,P,scall,fill,C);
9252: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9253: }
9254: return(0);
9255: }
9257: /*@
9258: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9260: Neighbor-wise Collective on Mat
9262: Input Parameters:
9263: + A - the matrix
9264: - P - the projection matrix
9266: Output Parameters:
9267: . C - the product matrix
9269: Notes:
9270: C must have been created by calling MatPtAPSymbolic and must be destroyed by
9271: the user using MatDeatroy().
9273: This routine is currently only implemented for pairs of AIJ matrices and classes
9274: which inherit from AIJ. C will be of type MATAIJ.
9276: Level: intermediate
9278: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9279: @*/
9280: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9281: {
9287: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9288: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9291: MatCheckPreallocated(P,2);
9292: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9293: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9296: MatCheckPreallocated(C,3);
9297: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9298: 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);
9299: 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);
9300: 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);
9301: 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);
9302: MatCheckPreallocated(A,1);
9304: if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9305: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9306: (*C->ops->ptapnumeric)(A,P,C);
9307: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9308: return(0);
9309: }
9311: /*@
9312: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9314: Neighbor-wise Collective on Mat
9316: Input Parameters:
9317: + A - the matrix
9318: - P - the projection matrix
9320: Output Parameters:
9321: . C - the (i,j) structure of the product matrix
9323: Notes:
9324: C will be created and must be destroyed by the user with MatDestroy().
9326: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9327: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
9328: this (i,j) structure by calling MatPtAPNumeric().
9330: Level: intermediate
9332: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9333: @*/
9334: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9335: {
9341: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9342: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9343: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9346: MatCheckPreallocated(P,2);
9347: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9348: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9351: 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);
9352: 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);
9353: MatCheckPreallocated(A,1);
9355: if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9356: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9357: (*A->ops->ptapsymbolic)(A,P,fill,C);
9358: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
9360: /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
9361: return(0);
9362: }
9364: /*@
9365: MatRARt - Creates the matrix product C = R * A * R^T
9367: Neighbor-wise Collective on Mat
9369: Input Parameters:
9370: + A - the matrix
9371: . R - the projection matrix
9372: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9373: - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9374: if the result is a dense matrix this is irrelevent
9376: Output Parameters:
9377: . C - the product matrix
9379: Notes:
9380: C will be created and must be destroyed by the user with MatDestroy().
9382: This routine is currently only implemented for pairs of AIJ matrices and classes
9383: which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9384: parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9385: We recommend using MatPtAP().
9387: Level: intermediate
9389: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9390: @*/
9391: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9392: {
9398: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9399: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9400: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9403: MatCheckPreallocated(R,2);
9404: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9405: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9407: 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);
9409: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9410: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9411: MatCheckPreallocated(A,1);
9413: if (!A->ops->rart) {
9414: Mat Rt;
9415: MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);
9416: MatMatMatMult(R,A,Rt,scall,fill,C);
9417: MatDestroy(&Rt);
9418: return(0);
9419: }
9420: PetscLogEventBegin(MAT_RARt,A,R,0,0);
9421: (*A->ops->rart)(A,R,scall,fill,C);
9422: PetscLogEventEnd(MAT_RARt,A,R,0,0);
9423: return(0);
9424: }
9426: /*@
9427: MatRARtNumeric - Computes the matrix product C = R * A * R^T
9429: Neighbor-wise Collective on Mat
9431: Input Parameters:
9432: + A - the matrix
9433: - R - the projection matrix
9435: Output Parameters:
9436: . C - the product matrix
9438: Notes:
9439: C must have been created by calling MatRARtSymbolic and must be destroyed by
9440: the user using MatDestroy().
9442: This routine is currently only implemented for pairs of AIJ matrices and classes
9443: which inherit from AIJ. C will be of type MATAIJ.
9445: Level: intermediate
9447: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9448: @*/
9449: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9450: {
9456: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9457: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9460: MatCheckPreallocated(R,2);
9461: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9462: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9465: MatCheckPreallocated(C,3);
9466: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9467: 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);
9468: 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);
9469: 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);
9470: if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
9471: MatCheckPreallocated(A,1);
9473: PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
9474: (*A->ops->rartnumeric)(A,R,C);
9475: PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
9476: return(0);
9477: }
9479: /*@
9480: MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9482: Neighbor-wise Collective on Mat
9484: Input Parameters:
9485: + A - the matrix
9486: - R - the projection matrix
9488: Output Parameters:
9489: . C - the (i,j) structure of the product matrix
9491: Notes:
9492: C will be created and must be destroyed by the user with MatDestroy().
9494: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9495: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
9496: this (i,j) structure by calling MatRARtNumeric().
9498: Level: intermediate
9500: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9501: @*/
9502: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9503: {
9509: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9510: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9511: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9514: MatCheckPreallocated(R,2);
9515: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9516: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9519: 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);
9520: 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);
9521: MatCheckPreallocated(A,1);
9522: PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9523: (*A->ops->rartsymbolic)(A,R,fill,C);
9524: PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
9526: MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9527: return(0);
9528: }
9530: /*@
9531: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9533: Neighbor-wise Collective on Mat
9535: Input Parameters:
9536: + A - the left matrix
9537: . B - the right matrix
9538: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9539: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9540: if the result is a dense matrix this is irrelevent
9542: Output Parameters:
9543: . C - the product matrix
9545: Notes:
9546: Unless scall is MAT_REUSE_MATRIX C will be created.
9548: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call and C was obtained from a previous
9549: call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9551: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9552: actually needed.
9554: If you have many matrices with the same non-zero structure to multiply, you
9555: should either
9556: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
9557: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9558: In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine
9559: with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9561: Level: intermediate
9563: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
9564: @*/
9565: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9566: {
9568: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9569: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9570: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9575: MatCheckPreallocated(A,1);
9576: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9577: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9580: MatCheckPreallocated(B,2);
9581: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9582: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9584: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9585: if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9586: if (scall == MAT_REUSE_MATRIX) {
9589: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9590: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9591: (*(*C)->ops->matmultnumeric)(A,B,*C);
9592: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9593: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9594: return(0);
9595: }
9596: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9597: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9599: fA = A->ops->matmult;
9600: fB = B->ops->matmult;
9601: if (fB == fA) {
9602: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9603: mult = fB;
9604: } else {
9605: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9606: char multname[256];
9607: PetscStrcpy(multname,"MatMatMult_");
9608: PetscStrcat(multname,((PetscObject)A)->type_name);
9609: PetscStrcat(multname,"_");
9610: PetscStrcat(multname,((PetscObject)B)->type_name);
9611: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9612: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9613: if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9614: }
9615: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9616: (*mult)(A,B,scall,fill,C);
9617: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9618: return(0);
9619: }
9621: /*@
9622: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9623: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
9625: Neighbor-wise Collective on Mat
9627: Input Parameters:
9628: + A - the left matrix
9629: . B - the right matrix
9630: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9631: if C is a dense matrix this is irrelevent
9633: Output Parameters:
9634: . C - the product matrix
9636: Notes:
9637: Unless scall is MAT_REUSE_MATRIX C will be created.
9639: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9640: actually needed.
9642: This routine is currently implemented for
9643: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9644: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9645: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9647: Level: intermediate
9649: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9650: We should incorporate them into PETSc.
9652: .seealso: MatMatMult(), MatMatMultNumeric()
9653: @*/
9654: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9655: {
9657: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9658: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9659: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9664: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9665: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9669: MatCheckPreallocated(B,2);
9670: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9671: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9674: if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9675: if (fill == PETSC_DEFAULT) fill = 2.0;
9676: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9677: MatCheckPreallocated(A,1);
9679: Asymbolic = A->ops->matmultsymbolic;
9680: Bsymbolic = B->ops->matmultsymbolic;
9681: if (Asymbolic == Bsymbolic) {
9682: if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9683: symbolic = Bsymbolic;
9684: } else { /* dispatch based on the type of A and B */
9685: char symbolicname[256];
9686: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9687: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9688: PetscStrcat(symbolicname,"_");
9689: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9690: PetscStrcat(symbolicname,"_C");
9691: PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9692: if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9693: }
9694: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9695: (*symbolic)(A,B,fill,C);
9696: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9697: return(0);
9698: }
9700: /*@
9701: MatMatMultNumeric - Performs the numeric matrix-matrix product.
9702: Call this routine after first calling MatMatMultSymbolic().
9704: Neighbor-wise Collective on Mat
9706: Input Parameters:
9707: + A - the left matrix
9708: - B - the right matrix
9710: Output Parameters:
9711: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9713: Notes:
9714: C must have been created with MatMatMultSymbolic().
9716: This routine is currently implemented for
9717: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9718: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9719: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9721: Level: intermediate
9723: .seealso: MatMatMult(), MatMatMultSymbolic()
9724: @*/
9725: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9726: {
9730: MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9731: return(0);
9732: }
9734: /*@
9735: MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9737: Neighbor-wise Collective on Mat
9739: Input Parameters:
9740: + A - the left matrix
9741: . B - the right matrix
9742: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9743: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9745: Output Parameters:
9746: . C - the product matrix
9748: Notes:
9749: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9751: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9753: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9754: actually needed.
9756: This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class.
9758: Level: intermediate
9760: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9761: @*/
9762: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9763: {
9765: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9766: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9771: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9772: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9773: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9776: MatCheckPreallocated(B,2);
9777: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9778: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9780: if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
9781: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9782: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9783: MatCheckPreallocated(A,1);
9785: fA = A->ops->mattransposemult;
9786: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9787: fB = B->ops->mattransposemult;
9788: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9789: if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9791: PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9792: if (scall == MAT_INITIAL_MATRIX) {
9793: PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9794: (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9795: PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9796: }
9797: PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9798: (*A->ops->mattransposemultnumeric)(A,B,*C);
9799: PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9800: PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9801: return(0);
9802: }
9804: /*@
9805: MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9807: Neighbor-wise Collective on Mat
9809: Input Parameters:
9810: + A - the left matrix
9811: . B - the right matrix
9812: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9813: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9815: Output Parameters:
9816: . C - the product matrix
9818: Notes:
9819: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9821: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9823: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9824: actually needed.
9826: This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9827: which inherit from SeqAIJ. C will be of same type as the input matrices.
9829: Level: intermediate
9831: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9832: @*/
9833: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9834: {
9836: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9837: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9838: PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9843: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9844: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9845: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9848: MatCheckPreallocated(B,2);
9849: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9850: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9852: if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
9853: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9854: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9855: MatCheckPreallocated(A,1);
9857: fA = A->ops->transposematmult;
9858: fB = B->ops->transposematmult;
9859: if (fB==fA) {
9860: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9861: transposematmult = fA;
9862: } else {
9863: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9864: char multname[256];
9865: PetscStrcpy(multname,"MatTransposeMatMult_");
9866: PetscStrcat(multname,((PetscObject)A)->type_name);
9867: PetscStrcat(multname,"_");
9868: PetscStrcat(multname,((PetscObject)B)->type_name);
9869: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9870: PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9871: if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9872: }
9873: PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9874: (*transposematmult)(A,B,scall,fill,C);
9875: PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9876: return(0);
9877: }
9879: /*@
9880: MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9882: Neighbor-wise Collective on Mat
9884: Input Parameters:
9885: + A - the left matrix
9886: . B - the middle matrix
9887: . C - the right matrix
9888: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9889: - fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate
9890: if the result is a dense matrix this is irrelevent
9892: Output Parameters:
9893: . D - the product matrix
9895: Notes:
9896: Unless scall is MAT_REUSE_MATRIX D will be created.
9898: MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9900: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9901: actually needed.
9903: If you have many matrices with the same non-zero structure to multiply, you
9904: should use MAT_REUSE_MATRIX in all calls but the first or
9906: Level: intermediate
9908: .seealso: MatMatMult, MatPtAP()
9909: @*/
9910: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9911: {
9913: PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9914: PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9915: PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9916: PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9921: MatCheckPreallocated(A,1);
9922: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9923: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9924: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9927: MatCheckPreallocated(B,2);
9928: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9929: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9932: MatCheckPreallocated(C,3);
9933: if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9934: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9935: if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9936: if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
9937: if (scall == MAT_REUSE_MATRIX) {
9940: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9941: (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9942: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9943: return(0);
9944: }
9945: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9946: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9948: fA = A->ops->matmatmult;
9949: fB = B->ops->matmatmult;
9950: fC = C->ops->matmatmult;
9951: if (fA == fB && fA == fC) {
9952: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9953: mult = fA;
9954: } else {
9955: /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9956: char multname[256];
9957: PetscStrcpy(multname,"MatMatMatMult_");
9958: PetscStrcat(multname,((PetscObject)A)->type_name);
9959: PetscStrcat(multname,"_");
9960: PetscStrcat(multname,((PetscObject)B)->type_name);
9961: PetscStrcat(multname,"_");
9962: PetscStrcat(multname,((PetscObject)C)->type_name);
9963: PetscStrcat(multname,"_C");
9964: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9965: if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9966: }
9967: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9968: (*mult)(A,B,C,scall,fill,D);
9969: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9970: return(0);
9971: }
9973: /*@
9974: MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9976: Collective on Mat
9978: Input Parameters:
9979: + mat - the matrix
9980: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9981: . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9982: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9984: Output Parameter:
9985: . matredundant - redundant matrix
9987: Notes:
9988: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9989: original matrix has not changed from that last call to MatCreateRedundantMatrix().
9991: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9992: calling it.
9994: Level: advanced
9996: Concepts: subcommunicator
9997: Concepts: duplicate matrix
9999: .seealso: MatDestroy()
10000: @*/
10001: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10002: {
10004: MPI_Comm comm;
10005: PetscMPIInt size;
10006: PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10007: Mat_Redundant *redund=NULL;
10008: PetscSubcomm psubcomm=NULL;
10009: MPI_Comm subcomm_in=subcomm;
10010: Mat *matseq;
10011: IS isrow,iscol;
10012: PetscBool newsubcomm=PETSC_FALSE;
10016: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10019: }
10021: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
10022: if (size == 1 || nsubcomm == 1) {
10023: if (reuse == MAT_INITIAL_MATRIX) {
10024: MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
10025: } else {
10026: if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10027: MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
10028: }
10029: return(0);
10030: }
10032: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10033: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10034: MatCheckPreallocated(mat,1);
10036: PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
10037: if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10038: /* create psubcomm, then get subcomm */
10039: PetscObjectGetComm((PetscObject)mat,&comm);
10040: MPI_Comm_size(comm,&size);
10041: if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10043: PetscSubcommCreate(comm,&psubcomm);
10044: PetscSubcommSetNumber(psubcomm,nsubcomm);
10045: PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
10046: PetscSubcommSetFromOptions(psubcomm);
10047: PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);
10048: newsubcomm = PETSC_TRUE;
10049: PetscSubcommDestroy(&psubcomm);
10050: }
10052: /* get isrow, iscol and a local sequential matrix matseq[0] */
10053: if (reuse == MAT_INITIAL_MATRIX) {
10054: mloc_sub = PETSC_DECIDE;
10055: nloc_sub = PETSC_DECIDE;
10056: if (bs < 1) {
10057: PetscSplitOwnership(subcomm,&mloc_sub,&M);
10058: PetscSplitOwnership(subcomm,&nloc_sub,&N);
10059: } else {
10060: PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
10061: PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);
10062: }
10063: MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
10064: rstart = rend - mloc_sub;
10065: ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
10066: ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
10067: } else { /* reuse == MAT_REUSE_MATRIX */
10068: if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10069: /* retrieve subcomm */
10070: PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
10071: redund = (*matredundant)->redundant;
10072: isrow = redund->isrow;
10073: iscol = redund->iscol;
10074: matseq = redund->matseq;
10075: }
10076: MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);
10078: /* get matredundant over subcomm */
10079: if (reuse == MAT_INITIAL_MATRIX) {
10080: MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);
10082: /* create a supporting struct and attach it to C for reuse */
10083: PetscNewLog(*matredundant,&redund);
10084: (*matredundant)->redundant = redund;
10085: redund->isrow = isrow;
10086: redund->iscol = iscol;
10087: redund->matseq = matseq;
10088: if (newsubcomm) {
10089: redund->subcomm = subcomm;
10090: } else {
10091: redund->subcomm = MPI_COMM_NULL;
10092: }
10093: } else {
10094: MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
10095: }
10096: PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
10097: return(0);
10098: }
10100: /*@C
10101: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10102: a given 'mat' object. Each submatrix can span multiple procs.
10104: Collective on Mat
10106: Input Parameters:
10107: + mat - the matrix
10108: . subcomm - the subcommunicator obtained by com_split(comm)
10109: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10111: Output Parameter:
10112: . subMat - 'parallel submatrices each spans a given subcomm
10114: Notes:
10115: The submatrix partition across processors is dictated by 'subComm' a
10116: communicator obtained by com_split(comm). The comm_split
10117: is not restriced to be grouped with consecutive original ranks.
10119: Due the comm_split() usage, the parallel layout of the submatrices
10120: map directly to the layout of the original matrix [wrt the local
10121: row,col partitioning]. So the original 'DiagonalMat' naturally maps
10122: into the 'DiagonalMat' of the subMat, hence it is used directly from
10123: the subMat. However the offDiagMat looses some columns - and this is
10124: reconstructed with MatSetValues()
10126: Level: advanced
10128: Concepts: subcommunicator
10129: Concepts: submatrices
10131: .seealso: MatCreateSubMatrices()
10132: @*/
10133: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10134: {
10136: PetscMPIInt commsize,subCommSize;
10139: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
10140: MPI_Comm_size(subComm,&subCommSize);
10141: if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10143: if (scall == MAT_REUSE_MATRIX && *subMat == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10144: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
10145: (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
10146: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
10147: return(0);
10148: }
10150: /*@
10151: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10153: Not Collective
10155: Input Arguments:
10156: mat - matrix to extract local submatrix from
10157: isrow - local row indices for submatrix
10158: iscol - local column indices for submatrix
10160: Output Arguments:
10161: submat - the submatrix
10163: Level: intermediate
10165: Notes:
10166: The submat should be returned with MatRestoreLocalSubMatrix().
10168: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
10169: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10171: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
10172: MatSetValuesBlockedLocal() will also be implemented.
10174: The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10175: matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10177: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10178: @*/
10179: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10180: {
10189: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10191: if (mat->ops->getlocalsubmatrix) {
10192: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
10193: } else {
10194: MatCreateLocalRef(mat,isrow,iscol,submat);
10195: }
10196: return(0);
10197: }
10199: /*@
10200: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10202: Not Collective
10204: Input Arguments:
10205: mat - matrix to extract local submatrix from
10206: isrow - local row indices for submatrix
10207: iscol - local column indices for submatrix
10208: submat - the submatrix
10210: Level: intermediate
10212: .seealso: MatGetLocalSubMatrix()
10213: @*/
10214: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10215: {
10224: if (*submat) {
10226: }
10228: if (mat->ops->restorelocalsubmatrix) {
10229: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
10230: } else {
10231: MatDestroy(submat);
10232: }
10233: *submat = NULL;
10234: return(0);
10235: }
10237: /* --------------------------------------------------------*/
10238: /*@
10239: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10241: Collective on Mat
10243: Input Parameter:
10244: . mat - the matrix
10246: Output Parameter:
10247: . is - if any rows have zero diagonals this contains the list of them
10249: Level: developer
10251: Concepts: matrix-vector product
10253: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10254: @*/
10255: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10256: {
10262: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10263: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10265: if (!mat->ops->findzerodiagonals) {
10266: Vec diag;
10267: const PetscScalar *a;
10268: PetscInt *rows;
10269: PetscInt rStart, rEnd, r, nrow = 0;
10271: MatCreateVecs(mat, &diag, NULL);
10272: MatGetDiagonal(mat, diag);
10273: MatGetOwnershipRange(mat, &rStart, &rEnd);
10274: VecGetArrayRead(diag, &a);
10275: for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10276: PetscMalloc1(nrow, &rows);
10277: nrow = 0;
10278: for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10279: VecRestoreArrayRead(diag, &a);
10280: VecDestroy(&diag);
10281: ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);
10282: } else {
10283: (*mat->ops->findzerodiagonals)(mat, is);
10284: }
10285: return(0);
10286: }
10288: /*@
10289: MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10291: Collective on Mat
10293: Input Parameter:
10294: . mat - the matrix
10296: Output Parameter:
10297: . is - contains the list of rows with off block diagonal entries
10299: Level: developer
10301: Concepts: matrix-vector product
10303: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10304: @*/
10305: PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10306: {
10312: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10313: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10315: if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10316: (*mat->ops->findoffblockdiagonalentries)(mat,is);
10317: return(0);
10318: }
10320: /*@C
10321: MatInvertBlockDiagonal - Inverts the block diagonal entries.
10323: Collective on Mat
10325: Input Parameters:
10326: . mat - the matrix
10328: Output Parameters:
10329: . values - the block inverses in column major order (FORTRAN-like)
10331: Note:
10332: This routine is not available from Fortran.
10334: Level: advanced
10335: @*/
10336: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10337: {
10342: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10343: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10344: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10345: (*mat->ops->invertblockdiagonal)(mat,values);
10346: return(0);
10347: }
10349: /*@C
10350: MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10351: via MatTransposeColoringCreate().
10353: Collective on MatTransposeColoring
10355: Input Parameter:
10356: . c - coloring context
10358: Level: intermediate
10360: .seealso: MatTransposeColoringCreate()
10361: @*/
10362: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10363: {
10364: PetscErrorCode ierr;
10365: MatTransposeColoring matcolor=*c;
10368: if (!matcolor) return(0);
10369: if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
10371: PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
10372: PetscFree(matcolor->rows);
10373: PetscFree(matcolor->den2sp);
10374: PetscFree(matcolor->colorforcol);
10375: PetscFree(matcolor->columns);
10376: if (matcolor->brows>0) {
10377: PetscFree(matcolor->lstart);
10378: }
10379: PetscHeaderDestroy(c);
10380: return(0);
10381: }
10383: /*@C
10384: MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10385: a MatTransposeColoring context has been created, computes a dense B^T by Apply
10386: MatTransposeColoring to sparse B.
10388: Collective on MatTransposeColoring
10390: Input Parameters:
10391: + B - sparse matrix B
10392: . Btdense - symbolic dense matrix B^T
10393: - coloring - coloring context created with MatTransposeColoringCreate()
10395: Output Parameter:
10396: . Btdense - dense matrix B^T
10398: Level: advanced
10400: Notes: These are used internally for some implementations of MatRARt()
10402: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10404: .keywords: coloring
10405: @*/
10406: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10407: {
10415: if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10416: (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
10417: return(0);
10418: }
10420: /*@C
10421: MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10422: a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10423: in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10424: Csp from Cden.
10426: Collective on MatTransposeColoring
10428: Input Parameters:
10429: + coloring - coloring context created with MatTransposeColoringCreate()
10430: - Cden - matrix product of a sparse matrix and a dense matrix Btdense
10432: Output Parameter:
10433: . Csp - sparse matrix
10435: Level: advanced
10437: Notes: These are used internally for some implementations of MatRARt()
10439: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10441: .keywords: coloring
10442: @*/
10443: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10444: {
10452: if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10453: (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
10454: return(0);
10455: }
10457: /*@C
10458: MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10460: Collective on Mat
10462: Input Parameters:
10463: + mat - the matrix product C
10464: - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10466: Output Parameter:
10467: . color - the new coloring context
10469: Level: intermediate
10471: .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(),
10472: MatTransColoringApplyDenToSp()
10473: @*/
10474: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10475: {
10476: MatTransposeColoring c;
10477: MPI_Comm comm;
10478: PetscErrorCode ierr;
10481: PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
10482: PetscObjectGetComm((PetscObject)mat,&comm);
10483: PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);
10485: c->ctype = iscoloring->ctype;
10486: if (mat->ops->transposecoloringcreate) {
10487: (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
10488: } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10490: *color = c;
10491: PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
10492: return(0);
10493: }
10495: /*@
10496: MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10497: matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10498: same, otherwise it will be larger
10500: Not Collective
10502: Input Parameter:
10503: . A - the matrix
10505: Output Parameter:
10506: . state - the current state
10508: Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10509: different matrices
10511: Level: intermediate
10513: @*/
10514: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10515: {
10518: *state = mat->nonzerostate;
10519: return(0);
10520: }
10522: /*@
10523: MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10524: matrices from each processor
10526: Collective on MPI_Comm
10528: Input Parameters:
10529: + comm - the communicators the parallel matrix will live on
10530: . seqmat - the input sequential matrices
10531: . n - number of local columns (or PETSC_DECIDE)
10532: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10534: Output Parameter:
10535: . mpimat - the parallel matrix generated
10537: Level: advanced
10539: Notes: The number of columns of the matrix in EACH processor MUST be the same.
10541: @*/
10542: PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10543: {
10547: if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10548: if (reuse == MAT_REUSE_MATRIX && seqmat == *mpimat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10550: PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);
10551: (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);
10552: PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);
10553: return(0);
10554: }
10556: /*@
10557: MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10558: ranks' ownership ranges.
10560: Collective on A
10562: Input Parameters:
10563: + A - the matrix to create subdomains from
10564: - N - requested number of subdomains
10567: Output Parameters:
10568: + n - number of subdomains resulting on this rank
10569: - iss - IS list with indices of subdomains on this rank
10571: Level: advanced
10573: Notes: number of subdomains must be smaller than the communicator size
10574: @*/
10575: PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10576: {
10577: MPI_Comm comm,subcomm;
10578: PetscMPIInt size,rank,color;
10579: PetscInt rstart,rend,k;
10580: PetscErrorCode ierr;
10583: PetscObjectGetComm((PetscObject)A,&comm);
10584: MPI_Comm_size(comm,&size);
10585: MPI_Comm_rank(comm,&rank);
10586: if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N);
10587: *n = 1;
10588: k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10589: color = rank/k;
10590: MPI_Comm_split(comm,color,rank,&subcomm);
10591: PetscMalloc1(1,iss);
10592: MatGetOwnershipRange(A,&rstart,&rend);
10593: ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);
10594: MPI_Comm_free(&subcomm);
10595: return(0);
10596: }
10598: /*@
10599: MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10601: If the interpolation and restriction operators are the same, uses MatPtAP.
10602: If they are not the same, use MatMatMatMult.
10604: Once the coarse grid problem is constructed, correct for interpolation operators
10605: that are not of full rank, which can legitimately happen in the case of non-nested
10606: geometric multigrid.
10608: Input Parameters:
10609: + restrct - restriction operator
10610: . dA - fine grid matrix
10611: . interpolate - interpolation operator
10612: . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10613: - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10615: Output Parameters:
10616: . A - the Galerkin coarse matrix
10618: Options Database Key:
10619: . -pc_mg_galerkin <both,pmat,mat,none>
10621: Level: developer
10623: .keywords: MG, multigrid, Galerkin
10625: .seealso: MatPtAP(), MatMatMatMult()
10626: @*/
10627: PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10628: {
10630: IS zerorows;
10631: Vec diag;
10634: if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10635: /* Construct the coarse grid matrix */
10636: if (interpolate == restrct) {
10637: MatPtAP(dA,interpolate,reuse,fill,A);
10638: } else {
10639: MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);
10640: }
10642: /* If the interpolation matrix is not of full rank, A will have zero rows.
10643: This can legitimately happen in the case of non-nested geometric multigrid.
10644: In that event, we set the rows of the matrix to the rows of the identity,
10645: ignoring the equations (as the RHS will also be zero). */
10647: MatFindZeroRows(*A, &zerorows);
10649: if (zerorows != NULL) { /* if there are any zero rows */
10650: MatCreateVecs(*A, &diag, NULL);
10651: MatGetDiagonal(*A, diag);
10652: VecISSet(diag, zerorows, 1.0);
10653: MatDiagonalSet(*A, diag, INSERT_VALUES);
10654: VecDestroy(&diag);
10655: ISDestroy(&zerorows);
10656: }
10657: return(0);
10658: }