Actual source code: matrix.c
petsc-3.7.1 2016-05-15
2: /*
3: This is where the abstract matrix operations are defined
4: */
6: #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/
7: #include <petsc/private/vecimpl.h>
8: #include <petsc/private/isimpl.h>
10: /* Logging support */
11: PetscClassId MAT_CLASSID;
12: PetscClassId MAT_COLORING_CLASSID;
13: PetscClassId MAT_FDCOLORING_CLASSID;
14: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
16: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
18: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23: PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_GetSubMatrix;
24: PetscLogEvent MAT_TransposeColoringCreate;
25: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27: PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28: PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29: PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34: PetscLogEvent MAT_GetMultiProcBlock;
35: PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
36: PetscLogEvent MAT_ViennaCLCopyToGPU;
37: PetscLogEvent MAT_Merge,MAT_Residual;
38: PetscLogEvent Mat_Coloring_Apply,Mat_Coloring_Comm,Mat_Coloring_Local,Mat_Coloring_ISCreate,Mat_Coloring_SetUp,Mat_Coloring_Weights;
40: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
44: /*@
45: MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
47: Logically Collective on Vec
49: Input Parameters:
50: + x - the vector
51: - rctx - the random number context, formed by PetscRandomCreate(), or NULL and
52: it will create one internally.
54: Output Parameter:
55: . x - the vector
57: Example of Usage:
58: .vb
59: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
60: VecSetRandom(x,rctx);
61: PetscRandomDestroy(rctx);
62: .ve
64: Level: intermediate
66: Concepts: vector^setting to random
67: Concepts: random^vector
69: .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
70: @*/
71: PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
72: {
74: PetscRandom randObj = NULL;
81: if (!rctx) {
82: MPI_Comm comm;
83: PetscObjectGetComm((PetscObject)x,&comm);
84: PetscRandomCreate(comm,&randObj);
85: PetscRandomSetFromOptions(randObj);
86: rctx = randObj;
87: }
89: PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
90: (*x->ops->setrandom)(x,rctx);
91: PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);
93: x->assembled = PETSC_TRUE;
94: PetscRandomDestroy(&randObj);
95: return(0);
96: }
101: /*@
102: MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
104: Input Parameter:
105: . A - the matrix
107: Output Parameter:
108: . keptrows - the rows that are not completely zero
110: Level: intermediate
112: @*/
113: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
114: {
119: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
120: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
121: if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
122: (*mat->ops->findnonzerorows)(mat,keptrows);
123: return(0);
124: }
128: /*@
129: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
131: Not Collective
133: Input Parameters:
134: . A - the matrix
136: Output Parameters:
137: . a - the diagonal part (which is a SEQUENTIAL matrix)
139: Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
140: Use caution, as the reference count on the returned matrix is not incremented and it is used as
141: part of the containing MPI Mat's normal operation.
143: Level: advanced
145: @*/
146: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
147: {
148: PetscErrorCode ierr,(*f)(Mat,Mat*);
149: PetscMPIInt size;
155: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
156: MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
157: PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);
158: if (f) {
159: (*f)(A,a);
160: return(0);
161: } else if (size == 1) {
162: *a = A;
163: } else {
164: MatType mattype;
165: MatGetType(A,&mattype);
166: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
167: }
168: return(0);
169: }
173: /*@
174: MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
176: Collective on Mat
178: Input Parameters:
179: . mat - the matrix
181: Output Parameter:
182: . trace - the sum of the diagonal entries
184: Level: advanced
186: @*/
187: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
188: {
190: Vec diag;
193: MatCreateVecs(mat,&diag,NULL);
194: MatGetDiagonal(mat,diag);
195: VecSum(diag,trace);
196: VecDestroy(&diag);
197: return(0);
198: }
202: /*@
203: MatRealPart - Zeros out the imaginary part of the matrix
205: Logically Collective on Mat
207: Input Parameters:
208: . mat - the matrix
210: Level: advanced
213: .seealso: MatImaginaryPart()
214: @*/
215: PetscErrorCode MatRealPart(Mat mat)
216: {
222: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
223: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
224: if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
225: MatCheckPreallocated(mat,1);
226: (*mat->ops->realpart)(mat);
227: #if defined(PETSC_HAVE_CUSP)
228: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
229: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
230: }
231: #elif defined(PETSC_HAVE_VIENNACL)
232: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
233: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
234: }
235: #elif defined(PETSC_HAVE_VECCUDA)
236: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
237: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
238: }
239: #endif
240: return(0);
241: }
245: /*@C
246: MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
248: Collective on Mat
250: Input Parameter:
251: . mat - the matrix
253: Output Parameters:
254: + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
255: - ghosts - the global indices of the ghost points
257: Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
259: Level: advanced
261: @*/
262: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
263: {
269: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
270: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
271: if (!mat->ops->getghosts) {
272: if (nghosts) *nghosts = 0;
273: if (ghosts) *ghosts = 0;
274: } else {
275: (*mat->ops->getghosts)(mat,nghosts,ghosts);
276: }
277: return(0);
278: }
283: /*@
284: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
286: Logically Collective on Mat
288: Input Parameters:
289: . mat - the matrix
291: Level: advanced
294: .seealso: MatRealPart()
295: @*/
296: PetscErrorCode MatImaginaryPart(Mat mat)
297: {
303: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
304: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
305: if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
306: MatCheckPreallocated(mat,1);
307: (*mat->ops->imaginarypart)(mat);
308: #if defined(PETSC_HAVE_CUSP)
309: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
310: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
311: }
312: #elif defined(PETSC_HAVE_VIENNACL)
313: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
314: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
315: }
316: #elif defined(PETSC_HAVE_VECCUDA)
317: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
318: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
319: }
320: #endif
321: return(0);
322: }
326: /*@
327: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
329: Collective on Mat
331: Input Parameter:
332: . mat - the matrix
334: Output Parameters:
335: + missing - is any diagonal missing
336: - dd - first diagonal entry that is missing (optional)
338: Level: advanced
341: .seealso: MatRealPart()
342: @*/
343: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
344: {
350: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
351: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
352: if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
353: (*mat->ops->missingdiagonal)(mat,missing,dd);
354: return(0);
355: }
359: /*@C
360: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
361: for each row that you get to ensure that your application does
362: not bleed memory.
364: Not Collective
366: Input Parameters:
367: + mat - the matrix
368: - row - the row to get
370: Output Parameters:
371: + ncols - if not NULL, the number of nonzeros in the row
372: . cols - if not NULL, the column numbers
373: - vals - if not NULL, the values
375: Notes:
376: This routine is provided for people who need to have direct access
377: to the structure of a matrix. We hope that we provide enough
378: high-level matrix routines that few users will need it.
380: MatGetRow() always returns 0-based column indices, regardless of
381: whether the internal representation is 0-based (default) or 1-based.
383: For better efficiency, set cols and/or vals to NULL if you do
384: not wish to extract these quantities.
386: The user can only examine the values extracted with MatGetRow();
387: the values cannot be altered. To change the matrix entries, one
388: must use MatSetValues().
390: You can only have one call to MatGetRow() outstanding for a particular
391: matrix at a time, per processor. MatGetRow() can only obtain rows
392: associated with the given processor, it cannot get rows from the
393: other processors; for that we suggest using MatGetSubMatrices(), then
394: MatGetRow() on the submatrix. The row indix passed to MatGetRows()
395: is in the global number of rows.
397: Fortran Notes:
398: The calling sequence from Fortran is
399: .vb
400: MatGetRow(matrix,row,ncols,cols,values,ierr)
401: Mat matrix (input)
402: integer row (input)
403: integer ncols (output)
404: integer cols(maxcols) (output)
405: double precision (or double complex) values(maxcols) output
406: .ve
407: where maxcols >= maximum nonzeros in any row of the matrix.
410: Caution:
411: Do not try to change the contents of the output arrays (cols and vals).
412: In some cases, this may corrupt the matrix.
414: Level: advanced
416: Concepts: matrices^row access
418: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
419: @*/
420: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
421: {
423: PetscInt incols;
428: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
429: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
430: if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
431: MatCheckPreallocated(mat,1);
432: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
433: (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
434: if (ncols) *ncols = incols;
435: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
436: return(0);
437: }
441: /*@
442: MatConjugate - replaces the matrix values with their complex conjugates
444: Logically Collective on Mat
446: Input Parameters:
447: . mat - the matrix
449: Level: advanced
451: .seealso: VecConjugate()
452: @*/
453: PetscErrorCode MatConjugate(Mat mat)
454: {
455: #if defined(PETSC_USE_COMPLEX)
460: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
461: if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
462: (*mat->ops->conjugate)(mat);
463: #if defined(PETSC_HAVE_CUSP)
464: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
465: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
466: }
467: #elif defined(PETSC_HAVE_VIENNACL)
468: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
469: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
470: }
471: #elif defined(PETSC_HAVE_VECCUDA)
472: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
473: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
474: }
475: #endif
476: return(0);
477: #else
478: return 0;
479: #endif
480: }
484: /*@C
485: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
487: Not Collective
489: Input Parameters:
490: + mat - the matrix
491: . row - the row to get
492: . ncols, cols - the number of nonzeros and their columns
493: - vals - if nonzero the column values
495: Notes:
496: This routine should be called after you have finished examining the entries.
498: This routine zeros out ncols, cols, and vals. This is to prevent accidental
499: us of the array after it has been restored. If you pass NULL, it will
500: not zero the pointers. Use of cols or vals after MatRestoreRow is invalid.
502: Fortran Notes:
503: The calling sequence from Fortran is
504: .vb
505: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
506: Mat matrix (input)
507: integer row (input)
508: integer ncols (output)
509: integer cols(maxcols) (output)
510: double precision (or double complex) values(maxcols) output
511: .ve
512: Where maxcols >= maximum nonzeros in any row of the matrix.
514: In Fortran MatRestoreRow() MUST be called after MatGetRow()
515: before another call to MatGetRow() can be made.
517: Level: advanced
519: .seealso: MatGetRow()
520: @*/
521: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
522: {
528: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
529: if (!mat->ops->restorerow) return(0);
530: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
531: if (ncols) *ncols = 0;
532: if (cols) *cols = NULL;
533: if (vals) *vals = NULL;
534: return(0);
535: }
539: /*@
540: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
541: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
543: Not Collective
545: Input Parameters:
546: + mat - the matrix
548: Notes:
549: The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
551: Level: advanced
553: Concepts: matrices^row access
555: .seealso: MatRestoreRowRowUpperTriangular()
556: @*/
557: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
558: {
564: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
565: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
566: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
567: MatCheckPreallocated(mat,1);
568: (*mat->ops->getrowuppertriangular)(mat);
569: return(0);
570: }
574: /*@
575: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
577: Not Collective
579: Input Parameters:
580: + mat - the matrix
582: Notes:
583: This routine should be called after you have finished MatGetRow/MatRestoreRow().
586: Level: advanced
588: .seealso: MatGetRowUpperTriangular()
589: @*/
590: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
591: {
596: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
597: if (!mat->ops->restorerowuppertriangular) return(0);
598: (*mat->ops->restorerowuppertriangular)(mat);
599: return(0);
600: }
604: /*@C
605: MatSetOptionsPrefix - Sets the prefix used for searching for all
606: Mat options in the database.
608: Logically Collective on Mat
610: Input Parameter:
611: + A - the Mat context
612: - prefix - the prefix to prepend to all option names
614: Notes:
615: A hyphen (-) must NOT be given at the beginning of the prefix name.
616: The first character of all runtime options is AUTOMATICALLY the hyphen.
618: Level: advanced
620: .keywords: Mat, set, options, prefix, database
622: .seealso: MatSetFromOptions()
623: @*/
624: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
625: {
630: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
631: return(0);
632: }
636: /*@C
637: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
638: Mat options in the database.
640: Logically Collective on Mat
642: Input Parameters:
643: + A - the Mat context
644: - prefix - the prefix to prepend to all option names
646: Notes:
647: A hyphen (-) must NOT be given at the beginning of the prefix name.
648: The first character of all runtime options is AUTOMATICALLY the hyphen.
650: Level: advanced
652: .keywords: Mat, append, options, prefix, database
654: .seealso: MatGetOptionsPrefix()
655: @*/
656: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
657: {
662: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
663: return(0);
664: }
668: /*@C
669: MatGetOptionsPrefix - Sets the prefix used for searching for all
670: Mat options in the database.
672: Not Collective
674: Input Parameter:
675: . A - the Mat context
677: Output Parameter:
678: . prefix - pointer to the prefix string used
680: Notes: On the fortran side, the user should pass in a string 'prefix' of
681: sufficient length to hold the prefix.
683: Level: advanced
685: .keywords: Mat, get, options, prefix, database
687: .seealso: MatAppendOptionsPrefix()
688: @*/
689: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
690: {
695: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
696: return(0);
697: }
701: /*@
702: MatSetUp - Sets up the internal matrix data structures for the later use.
704: Collective on Mat
706: Input Parameters:
707: . A - the Mat context
709: Notes:
710: If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
712: If a suitable preallocation routine is used, this function does not need to be called.
714: See the Performance chapter of the PETSc users manual for how to preallocate matrices
716: Level: beginner
718: .keywords: Mat, setup
720: .seealso: MatCreate(), MatDestroy()
721: @*/
722: PetscErrorCode MatSetUp(Mat A)
723: {
724: PetscMPIInt size;
729: if (!((PetscObject)A)->type_name) {
730: MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
731: if (size == 1) {
732: MatSetType(A, MATSEQAIJ);
733: } else {
734: MatSetType(A, MATMPIAIJ);
735: }
736: }
737: if (!A->preallocated && A->ops->setup) {
738: PetscInfo(A,"Warning not preallocating matrix storage\n");
739: (*A->ops->setup)(A);
740: }
741: A->preallocated = PETSC_TRUE;
742: return(0);
743: }
745: #if defined(PETSC_HAVE_SAWS)
746: #include <petscviewersaws.h>
747: #endif
750: /*@C
751: MatView - Visualizes a matrix object.
753: Collective on Mat
755: Input Parameters:
756: + mat - the matrix
757: - viewer - visualization context
759: Notes:
760: The available visualization contexts include
761: + PETSC_VIEWER_STDOUT_SELF - for sequential matrices
762: . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
763: . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
764: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
766: The user can open alternative visualization contexts with
767: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
768: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
769: specified file; corresponding input uses MatLoad()
770: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
771: an X window display
772: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
773: Currently only the sequential dense and AIJ
774: matrix types support the Socket viewer.
776: The user can call PetscViewerPushFormat() to specify the output
777: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
778: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
779: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
780: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
781: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
782: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
783: format common among all matrix types
784: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
785: format (which is in many cases the same as the default)
786: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
787: size and structure (not the matrix entries)
788: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
789: the matrix structure
791: Options Database Keys:
792: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
793: . -mat_view ::ascii_info_detail - Prints more detailed info
794: . -mat_view - Prints matrix in ASCII format
795: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
796: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
797: . -display <name> - Sets display name (default is host)
798: . -draw_pause <sec> - Sets number of seconds to pause after display
799: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 11 Using MATLAB with PETSc for details)
800: . -viewer_socket_machine <machine> -
801: . -viewer_socket_port <port> -
802: . -mat_view binary - save matrix to file in binary format
803: - -viewer_binary_filename <name> -
804: Level: beginner
806: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
807: viewer is used.
809: See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
810: viewer is used.
812: One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
813: And then use the following mouse functions:
814: left mouse: zoom in
815: middle mouse: zoom out
816: right mouse: continue with the simulation
818: Concepts: matrices^viewing
819: Concepts: matrices^plotting
820: Concepts: matrices^printing
822: .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
823: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
824: @*/
825: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
826: {
827: PetscErrorCode ierr;
828: PetscInt rows,cols,rbs,cbs;
829: PetscBool iascii,ibinary;
830: PetscViewerFormat format;
831: #if defined(PETSC_HAVE_SAWS)
832: PetscBool issaws;
833: #endif
838: if (!viewer) {
839: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
840: }
843: MatCheckPreallocated(mat,1);
844: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
845: if (ibinary) {
846: PetscBool mpiio;
847: PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
848: if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
849: }
851: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
852: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
853: PetscViewerGetFormat(viewer,&format);
854: if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
855: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
856: }
858: #if defined(PETSC_HAVE_SAWS)
859: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
860: #endif
861: if (iascii) {
862: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
863: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
864: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
865: PetscViewerASCIIPushTab(viewer);
866: MatGetSize(mat,&rows,&cols);
867: MatGetBlockSizes(mat,&rbs,&cbs);
868: if (rbs != 1 || cbs != 1) {
869: if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
870: else {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
871: } else {
872: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
873: }
874: if (mat->factortype) {
875: const MatSolverPackage solver;
876: MatFactorGetSolverPackage(mat,&solver);
877: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
878: }
879: if (mat->ops->getinfo) {
880: MatInfo info;
881: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
882: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
883: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
884: }
885: if (mat->nullsp) {PetscViewerASCIIPrintf(viewer," has attached null space\n");}
886: if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer," has attached near null space\n");}
887: }
888: #if defined(PETSC_HAVE_SAWS)
889: } else if (issaws) {
890: PetscMPIInt rank;
892: PetscObjectName((PetscObject)mat);
893: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
894: if (!((PetscObject)mat)->amsmem && !rank) {
895: PetscObjectViewSAWs((PetscObject)mat,viewer);
896: }
897: #endif
898: }
899: if (mat->ops->view) {
900: PetscViewerASCIIPushTab(viewer);
901: (*mat->ops->view)(mat,viewer);
902: PetscViewerASCIIPopTab(viewer);
903: }
904: if (iascii) {
905: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
906: PetscViewerGetFormat(viewer,&format);
907: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
908: PetscViewerASCIIPopTab(viewer);
909: }
910: }
911: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
912: return(0);
913: }
915: #if defined(PETSC_USE_DEBUG)
916: #include <../src/sys/totalview/tv_data_display.h>
917: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
918: {
919: TV_add_row("Local rows", "int", &mat->rmap->n);
920: TV_add_row("Local columns", "int", &mat->cmap->n);
921: TV_add_row("Global rows", "int", &mat->rmap->N);
922: TV_add_row("Global columns", "int", &mat->cmap->N);
923: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
924: return TV_format_OK;
925: }
926: #endif
930: /*@C
931: MatLoad - Loads a matrix that has been stored in binary format
932: with MatView(). The matrix format is determined from the options database.
933: Generates a parallel MPI matrix if the communicator has more than one
934: processor. The default matrix type is AIJ.
936: Collective on PetscViewer
938: Input Parameters:
939: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
940: or some related function before a call to MatLoad()
941: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
943: Options Database Keys:
944: Used with block matrix formats (MATSEQBAIJ, ...) to specify
945: block size
946: . -matload_block_size <bs>
948: Level: beginner
950: Notes:
951: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
952: Mat before calling this routine if you wish to set it from the options database.
954: MatLoad() automatically loads into the options database any options
955: given in the file filename.info where filename is the name of the file
956: that was passed to the PetscViewerBinaryOpen(). The options in the info
957: file will be ignored if you use the -viewer_binary_skip_info option.
959: If the type or size of newmat is not set before a call to MatLoad, PETSc
960: sets the default matrix type AIJ and sets the local and global sizes.
961: If type and/or size is already set, then the same are used.
963: In parallel, each processor can load a subset of rows (or the
964: entire matrix). This routine is especially useful when a large
965: matrix is stored on disk and only part of it is desired on each
966: processor. For example, a parallel solver may access only some of
967: the rows from each processor. The algorithm used here reads
968: relatively small blocks of data rather than reading the entire
969: matrix and then subsetting it.
971: Notes for advanced users:
972: Most users should not need to know the details of the binary storage
973: format, since MatLoad() and MatView() completely hide these details.
974: But for anyone who's interested, the standard binary matrix storage
975: format is
977: $ int MAT_FILE_CLASSID
978: $ int number of rows
979: $ int number of columns
980: $ int total number of nonzeros
981: $ int *number nonzeros in each row
982: $ int *column indices of all nonzeros (starting index is zero)
983: $ PetscScalar *values of all nonzeros
985: PETSc automatically does the byte swapping for
986: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
987: linux, Windows and the paragon; thus if you write your own binary
988: read/write routines you have to swap the bytes; see PetscBinaryRead()
989: and PetscBinaryWrite() to see how this may be done.
991: .keywords: matrix, load, binary, input
993: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
995: @*/
996: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
997: {
999: PetscBool isbinary,flg;
1004: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
1005: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1007: if (!((PetscObject)newmat)->type_name) {
1008: MatSetType(newmat,MATAIJ);
1009: }
1011: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1012: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1013: (*newmat->ops->load)(newmat,viewer);
1014: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
1016: flg = PETSC_FALSE;
1017: PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1018: if (flg) {
1019: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1020: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1021: }
1022: flg = PETSC_FALSE;
1023: PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1024: if (flg) {
1025: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1026: }
1027: return(0);
1028: }
1032: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1033: {
1035: Mat_Redundant *redund = *redundant;
1036: PetscInt i;
1039: if (redund){
1040: if (redund->matseq) { /* via MatGetSubMatrices() */
1041: ISDestroy(&redund->isrow);
1042: ISDestroy(&redund->iscol);
1043: MatDestroy(&redund->matseq[0]);
1044: PetscFree(redund->matseq);
1045: } else {
1046: PetscFree2(redund->send_rank,redund->recv_rank);
1047: PetscFree(redund->sbuf_j);
1048: PetscFree(redund->sbuf_a);
1049: for (i=0; i<redund->nrecvs; i++) {
1050: PetscFree(redund->rbuf_j[i]);
1051: PetscFree(redund->rbuf_a[i]);
1052: }
1053: PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1054: }
1056: if (redund->subcomm) {
1057: PetscCommDestroy(&redund->subcomm);
1058: }
1059: PetscFree(redund);
1060: }
1061: return(0);
1062: }
1066: /*@
1067: MatDestroy - Frees space taken by a matrix.
1069: Collective on Mat
1071: Input Parameter:
1072: . A - the matrix
1074: Level: beginner
1076: @*/
1077: PetscErrorCode MatDestroy(Mat *A)
1078: {
1082: if (!*A) return(0);
1084: if (--((PetscObject)(*A))->refct > 0) {*A = NULL; return(0);}
1086: /* if memory was published with SAWs then destroy it */
1087: PetscObjectSAWsViewOff((PetscObject)*A);
1088: if ((*A)->ops->destroy) {
1089: (*(*A)->ops->destroy)(*A);
1090: }
1092: PetscFree((*A)->solvertype);
1093: MatDestroy_Redundant(&(*A)->redundant);
1094: MatNullSpaceDestroy(&(*A)->nullsp);
1095: MatNullSpaceDestroy(&(*A)->transnullsp);
1096: MatNullSpaceDestroy(&(*A)->nearnullsp);
1097: PetscLayoutDestroy(&(*A)->rmap);
1098: PetscLayoutDestroy(&(*A)->cmap);
1099: PetscHeaderDestroy(A);
1100: return(0);
1101: }
1105: /*@
1106: MatSetValues - Inserts or adds a block of values into a matrix.
1107: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1108: MUST be called after all calls to MatSetValues() have been completed.
1110: Not Collective
1112: Input Parameters:
1113: + mat - the matrix
1114: . v - a logically two-dimensional array of values
1115: . m, idxm - the number of rows and their global indices
1116: . n, idxn - the number of columns and their global indices
1117: - addv - either ADD_VALUES or INSERT_VALUES, where
1118: ADD_VALUES adds values to any existing entries, and
1119: INSERT_VALUES replaces existing entries with new values
1121: Notes:
1122: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1123: MatSetUp() before using this routine
1125: By default the values, v, are row-oriented. See MatSetOption() for other options.
1127: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1128: options cannot be mixed without intervening calls to the assembly
1129: routines.
1131: MatSetValues() uses 0-based row and column numbers in Fortran
1132: as well as in C.
1134: Negative indices may be passed in idxm and idxn, these rows and columns are
1135: simply ignored. This allows easily inserting element stiffness matrices
1136: with homogeneous Dirchlet boundary conditions that you don't want represented
1137: in the matrix.
1139: Efficiency Alert:
1140: The routine MatSetValuesBlocked() may offer much better efficiency
1141: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1143: Level: beginner
1145: Concepts: matrices^putting entries in
1147: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1148: InsertMode, INSERT_VALUES, ADD_VALUES
1149: @*/
1150: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1151: {
1153: #if defined(PETSC_USE_DEBUG)
1154: PetscInt i,j;
1155: #endif
1160: if (!m || !n) return(0); /* no values to insert */
1164: MatCheckPreallocated(mat,1);
1165: if (mat->insertmode == NOT_SET_VALUES) {
1166: mat->insertmode = addv;
1167: }
1168: #if defined(PETSC_USE_DEBUG)
1169: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1170: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1171: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1173: for (i=0; i<m; i++) {
1174: for (j=0; j<n; j++) {
1175: if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1176: #if defined(PETSC_USE_COMPLEX)
1177: SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1178: #else
1179: SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1180: #endif
1181: }
1182: }
1183: #endif
1185: if (mat->assembled) {
1186: mat->was_assembled = PETSC_TRUE;
1187: mat->assembled = PETSC_FALSE;
1188: }
1189: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1190: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1191: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1192: #if defined(PETSC_HAVE_CUSP)
1193: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1194: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1195: }
1196: #elif defined(PETSC_HAVE_VIENNACL)
1197: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1198: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1199: }
1200: #elif defined(PETSC_HAVE_VECCUDA)
1201: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1202: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1203: }
1204: #endif
1205: return(0);
1206: }
1211: /*@
1212: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1213: values into a matrix
1215: Not Collective
1217: Input Parameters:
1218: + mat - the matrix
1219: . row - the (block) row to set
1220: - v - a logically two-dimensional array of values
1222: Notes:
1223: By the values, v, are column-oriented (for the block version) and sorted
1225: All the nonzeros in the row must be provided
1227: The matrix must have previously had its column indices set
1229: The row must belong to this process
1231: Level: intermediate
1233: Concepts: matrices^putting entries in
1235: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1236: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1237: @*/
1238: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1239: {
1241: PetscInt globalrow;
1247: ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1248: MatSetValuesRow(mat,globalrow,v);
1249: #if defined(PETSC_HAVE_CUSP)
1250: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1251: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1252: }
1253: #elif defined(PETSC_HAVE_VIENNACL)
1254: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1255: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1256: }
1257: #elif defined(PETSC_HAVE_VECCUDA)
1258: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1259: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1260: }
1261: #endif
1262: return(0);
1263: }
1267: /*@
1268: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1269: values into a matrix
1271: Not Collective
1273: Input Parameters:
1274: + mat - the matrix
1275: . row - the (block) row to set
1276: - v - a logically two-dimensional array of values
1278: Notes:
1279: The values, v, are column-oriented for the block version.
1281: All the nonzeros in the row must be provided
1283: THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1285: The row must belong to this process
1287: Level: advanced
1289: Concepts: matrices^putting entries in
1291: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1292: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1293: @*/
1294: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1295: {
1301: MatCheckPreallocated(mat,1);
1303: #if defined(PETSC_USE_DEBUG)
1304: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1305: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1306: #endif
1307: mat->insertmode = INSERT_VALUES;
1309: if (mat->assembled) {
1310: mat->was_assembled = PETSC_TRUE;
1311: mat->assembled = PETSC_FALSE;
1312: }
1313: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1314: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1315: (*mat->ops->setvaluesrow)(mat,row,v);
1316: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1317: #if defined(PETSC_HAVE_CUSP)
1318: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1319: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1320: }
1321: #elif defined(PETSC_HAVE_VIENNACL)
1322: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1323: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1324: }
1325: #elif defined(PETSC_HAVE_VECCUDA)
1326: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1327: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1328: }
1329: #endif
1330: return(0);
1331: }
1335: /*@
1336: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1337: Using structured grid indexing
1339: Not Collective
1341: Input Parameters:
1342: + mat - the matrix
1343: . m - number of rows being entered
1344: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1345: . n - number of columns being entered
1346: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1347: . v - a logically two-dimensional array of values
1348: - addv - either ADD_VALUES or INSERT_VALUES, where
1349: ADD_VALUES adds values to any existing entries, and
1350: INSERT_VALUES replaces existing entries with new values
1352: Notes:
1353: By default the values, v, are row-oriented. See MatSetOption() for other options.
1355: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1356: options cannot be mixed without intervening calls to the assembly
1357: routines.
1359: The grid coordinates are across the entire grid, not just the local portion
1361: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1362: as well as in C.
1364: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1366: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1367: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1369: The columns and rows in the stencil passed in MUST be contained within the
1370: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1371: if you create a DMDA with an overlap of one grid level and on a particular process its first
1372: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1373: first i index you can use in your column and row indices in MatSetStencil() is 5.
1375: In Fortran idxm and idxn should be declared as
1376: $ MatStencil idxm(4,m),idxn(4,n)
1377: and the values inserted using
1378: $ idxm(MatStencil_i,1) = i
1379: $ idxm(MatStencil_j,1) = j
1380: $ idxm(MatStencil_k,1) = k
1381: $ idxm(MatStencil_c,1) = c
1382: etc
1384: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1385: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1386: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1387: DM_BOUNDARY_PERIODIC boundary type.
1389: For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1390: a single value per point) you can skip filling those indices.
1392: Inspired by the structured grid interface to the HYPRE package
1393: (http://www.llnl.gov/CASC/hypre)
1395: Efficiency Alert:
1396: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1397: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1399: Level: beginner
1401: Concepts: matrices^putting entries in
1403: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1404: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1405: @*/
1406: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1407: {
1409: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1410: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1411: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1414: if (!m || !n) return(0); /* no values to insert */
1421: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1422: jdxm = buf; jdxn = buf+m;
1423: } else {
1424: PetscMalloc2(m,&bufm,n,&bufn);
1425: jdxm = bufm; jdxn = bufn;
1426: }
1427: for (i=0; i<m; i++) {
1428: for (j=0; j<3-sdim; j++) dxm++;
1429: tmp = *dxm++ - starts[0];
1430: for (j=0; j<dim-1; j++) {
1431: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1432: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1433: }
1434: if (mat->stencil.noc) dxm++;
1435: jdxm[i] = tmp;
1436: }
1437: for (i=0; i<n; i++) {
1438: for (j=0; j<3-sdim; j++) dxn++;
1439: tmp = *dxn++ - starts[0];
1440: for (j=0; j<dim-1; j++) {
1441: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1442: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1443: }
1444: if (mat->stencil.noc) dxn++;
1445: jdxn[i] = tmp;
1446: }
1447: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1448: PetscFree2(bufm,bufn);
1449: return(0);
1450: }
1454: /*@
1455: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1456: Using structured grid indexing
1458: Not Collective
1460: Input Parameters:
1461: + mat - the matrix
1462: . m - number of rows being entered
1463: . idxm - grid coordinates for matrix rows being entered
1464: . n - number of columns being entered
1465: . idxn - grid coordinates for matrix columns being entered
1466: . v - a logically two-dimensional array of values
1467: - addv - either ADD_VALUES or INSERT_VALUES, where
1468: ADD_VALUES adds values to any existing entries, and
1469: INSERT_VALUES replaces existing entries with new values
1471: Notes:
1472: By default the values, v, are row-oriented and unsorted.
1473: See MatSetOption() for other options.
1475: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1476: options cannot be mixed without intervening calls to the assembly
1477: routines.
1479: The grid coordinates are across the entire grid, not just the local portion
1481: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1482: as well as in C.
1484: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1486: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1487: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1489: The columns and rows in the stencil passed in MUST be contained within the
1490: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1491: if you create a DMDA with an overlap of one grid level and on a particular process its first
1492: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1493: first i index you can use in your column and row indices in MatSetStencil() is 5.
1495: In Fortran idxm and idxn should be declared as
1496: $ MatStencil idxm(4,m),idxn(4,n)
1497: and the values inserted using
1498: $ idxm(MatStencil_i,1) = i
1499: $ idxm(MatStencil_j,1) = j
1500: $ idxm(MatStencil_k,1) = k
1501: etc
1503: Negative indices may be passed in idxm and idxn, these rows and columns are
1504: simply ignored. This allows easily inserting element stiffness matrices
1505: with homogeneous Dirchlet boundary conditions that you don't want represented
1506: in the matrix.
1508: Inspired by the structured grid interface to the HYPRE package
1509: (http://www.llnl.gov/CASC/hypre)
1511: Level: beginner
1513: Concepts: matrices^putting entries in
1515: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1516: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1517: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1518: @*/
1519: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1520: {
1522: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1523: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1524: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1527: if (!m || !n) return(0); /* no values to insert */
1534: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1535: jdxm = buf; jdxn = buf+m;
1536: } else {
1537: PetscMalloc2(m,&bufm,n,&bufn);
1538: jdxm = bufm; jdxn = bufn;
1539: }
1540: for (i=0; i<m; i++) {
1541: for (j=0; j<3-sdim; j++) dxm++;
1542: tmp = *dxm++ - starts[0];
1543: for (j=0; j<sdim-1; j++) {
1544: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1545: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1546: }
1547: dxm++;
1548: jdxm[i] = tmp;
1549: }
1550: for (i=0; i<n; i++) {
1551: for (j=0; j<3-sdim; j++) dxn++;
1552: tmp = *dxn++ - starts[0];
1553: for (j=0; j<sdim-1; j++) {
1554: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1555: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1556: }
1557: dxn++;
1558: jdxn[i] = tmp;
1559: }
1560: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1561: PetscFree2(bufm,bufn);
1562: #if defined(PETSC_HAVE_CUSP)
1563: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1564: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1565: }
1566: #elif defined(PETSC_HAVE_VIENNACL)
1567: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1568: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1569: }
1570: #elif defined(PETSC_HAVE_VECCUDA)
1571: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1572: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1573: }
1574: #endif
1575: return(0);
1576: }
1580: /*@
1581: MatSetStencil - Sets the grid information for setting values into a matrix via
1582: MatSetValuesStencil()
1584: Not Collective
1586: Input Parameters:
1587: + mat - the matrix
1588: . dim - dimension of the grid 1, 2, or 3
1589: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1590: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1591: - dof - number of degrees of freedom per node
1594: Inspired by the structured grid interface to the HYPRE package
1595: (www.llnl.gov/CASC/hyper)
1597: For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1598: user.
1600: Level: beginner
1602: Concepts: matrices^putting entries in
1604: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1605: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1606: @*/
1607: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1608: {
1609: PetscInt i;
1616: mat->stencil.dim = dim + (dof > 1);
1617: for (i=0; i<dim; i++) {
1618: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1619: mat->stencil.starts[i] = starts[dim-i-1];
1620: }
1621: mat->stencil.dims[dim] = dof;
1622: mat->stencil.starts[dim] = 0;
1623: mat->stencil.noc = (PetscBool)(dof == 1);
1624: return(0);
1625: }
1629: /*@
1630: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1632: Not Collective
1634: Input Parameters:
1635: + mat - the matrix
1636: . v - a logically two-dimensional array of values
1637: . m, idxm - the number of block rows and their global block indices
1638: . n, idxn - the number of block columns and their global block indices
1639: - addv - either ADD_VALUES or INSERT_VALUES, where
1640: ADD_VALUES adds values to any existing entries, and
1641: INSERT_VALUES replaces existing entries with new values
1643: Notes:
1644: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1645: MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1647: The m and n count the NUMBER of blocks in the row direction and column direction,
1648: NOT the total number of rows/columns; for example, if the block size is 2 and
1649: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1650: The values in idxm would be 1 2; that is the first index for each block divided by
1651: the block size.
1653: Note that you must call MatSetBlockSize() when constructing this matrix (before
1654: preallocating it).
1656: By default the values, v, are row-oriented, so the layout of
1657: v is the same as for MatSetValues(). See MatSetOption() for other options.
1659: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1660: options cannot be mixed without intervening calls to the assembly
1661: routines.
1663: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1664: as well as in C.
1666: Negative indices may be passed in idxm and idxn, these rows and columns are
1667: simply ignored. This allows easily inserting element stiffness matrices
1668: with homogeneous Dirchlet boundary conditions that you don't want represented
1669: in the matrix.
1671: Each time an entry is set within a sparse matrix via MatSetValues(),
1672: internal searching must be done to determine where to place the the
1673: data in the matrix storage space. By instead inserting blocks of
1674: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1675: reduced.
1677: Example:
1678: $ Suppose m=n=2 and block size(bs) = 2 The array is
1679: $
1680: $ 1 2 | 3 4
1681: $ 5 6 | 7 8
1682: $ - - - | - - -
1683: $ 9 10 | 11 12
1684: $ 13 14 | 15 16
1685: $
1686: $ v[] should be passed in like
1687: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1688: $
1689: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1690: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1692: Level: intermediate
1694: Concepts: matrices^putting entries in blocked
1696: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1697: @*/
1698: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1699: {
1705: if (!m || !n) return(0); /* no values to insert */
1709: MatCheckPreallocated(mat,1);
1710: if (mat->insertmode == NOT_SET_VALUES) {
1711: mat->insertmode = addv;
1712: }
1713: #if defined(PETSC_USE_DEBUG)
1714: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1715: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1716: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1717: #endif
1719: if (mat->assembled) {
1720: mat->was_assembled = PETSC_TRUE;
1721: mat->assembled = PETSC_FALSE;
1722: }
1723: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1724: if (mat->ops->setvaluesblocked) {
1725: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1726: } else {
1727: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1728: PetscInt i,j,bs,cbs;
1729: MatGetBlockSizes(mat,&bs,&cbs);
1730: if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1731: iidxm = buf; iidxn = buf + m*bs;
1732: } else {
1733: PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1734: iidxm = bufr; iidxn = bufc;
1735: }
1736: for (i=0; i<m; i++) {
1737: for (j=0; j<bs; j++) {
1738: iidxm[i*bs+j] = bs*idxm[i] + j;
1739: }
1740: }
1741: for (i=0; i<n; i++) {
1742: for (j=0; j<cbs; j++) {
1743: iidxn[i*cbs+j] = cbs*idxn[i] + j;
1744: }
1745: }
1746: MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1747: PetscFree2(bufr,bufc);
1748: }
1749: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1750: #if defined(PETSC_HAVE_CUSP)
1751: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1752: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1753: }
1754: #elif defined(PETSC_HAVE_VIENNACL)
1755: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1756: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1757: }
1758: #elif defined(PETSC_HAVE_VECCUDA)
1759: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1760: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1761: }
1762: #endif
1763: return(0);
1764: }
1768: /*@
1769: MatGetValues - Gets a block of values from a matrix.
1771: Not Collective; currently only returns a local block
1773: Input Parameters:
1774: + mat - the matrix
1775: . v - a logically two-dimensional array for storing the values
1776: . m, idxm - the number of rows and their global indices
1777: - n, idxn - the number of columns and their global indices
1779: Notes:
1780: The user must allocate space (m*n PetscScalars) for the values, v.
1781: The values, v, are then returned in a row-oriented format,
1782: analogous to that used by default in MatSetValues().
1784: MatGetValues() uses 0-based row and column numbers in
1785: Fortran as well as in C.
1787: MatGetValues() requires that the matrix has been assembled
1788: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1789: MatSetValues() and MatGetValues() CANNOT be made in succession
1790: without intermediate matrix assembly.
1792: Negative row or column indices will be ignored and those locations in v[] will be
1793: left unchanged.
1795: Level: advanced
1797: Concepts: matrices^accessing values
1799: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1800: @*/
1801: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1802: {
1808: if (!m || !n) return(0);
1812: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1813: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1814: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1815: MatCheckPreallocated(mat,1);
1817: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1818: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1819: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1820: return(0);
1821: }
1825: /*@
1826: MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1827: the same size. Currently, this can only be called once and creates the given matrix.
1829: Not Collective
1831: Input Parameters:
1832: + mat - the matrix
1833: . nb - the number of blocks
1834: . bs - the number of rows (and columns) in each block
1835: . rows - a concatenation of the rows for each block
1836: - v - a concatenation of logically two-dimensional arrays of values
1838: Notes:
1839: In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1841: Level: advanced
1843: Concepts: matrices^putting entries in
1845: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1846: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1847: @*/
1848: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1849: {
1857: #if defined(PETSC_USE_DEBUG)
1858: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1859: #endif
1861: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1862: if (mat->ops->setvaluesbatch) {
1863: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1864: } else {
1865: PetscInt b;
1866: for (b = 0; b < nb; ++b) {
1867: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1868: }
1869: }
1870: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1871: return(0);
1872: }
1876: /*@
1877: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1878: the routine MatSetValuesLocal() to allow users to insert matrix entries
1879: using a local (per-processor) numbering.
1881: Not Collective
1883: Input Parameters:
1884: + x - the matrix
1885: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS()
1886: - cmapping - column mapping
1888: Level: intermediate
1890: Concepts: matrices^local to global mapping
1891: Concepts: local to global mapping^for matrices
1893: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1894: @*/
1895: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1896: {
1905: if (x->ops->setlocaltoglobalmapping) {
1906: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1907: } else {
1908: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1909: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1910: }
1911: return(0);
1912: }
1917: /*@
1918: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1920: Not Collective
1922: Input Parameters:
1923: . A - the matrix
1925: Output Parameters:
1926: + rmapping - row mapping
1927: - cmapping - column mapping
1929: Level: advanced
1931: Concepts: matrices^local to global mapping
1932: Concepts: local to global mapping^for matrices
1934: .seealso: MatSetValuesLocal()
1935: @*/
1936: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1937: {
1943: if (rmapping) *rmapping = A->rmap->mapping;
1944: if (cmapping) *cmapping = A->cmap->mapping;
1945: return(0);
1946: }
1950: /*@
1951: MatGetLayouts - Gets the PetscLayout objects for rows and columns
1953: Not Collective
1955: Input Parameters:
1956: . A - the matrix
1958: Output Parameters:
1959: + rmap - row layout
1960: - cmap - column layout
1962: Level: advanced
1964: .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping()
1965: @*/
1966: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1967: {
1973: if (rmap) *rmap = A->rmap;
1974: if (cmap) *cmap = A->cmap;
1975: return(0);
1976: }
1980: /*@
1981: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1982: using a local ordering of the nodes.
1984: Not Collective
1986: Input Parameters:
1987: + x - the matrix
1988: . nrow, irow - number of rows and their local indices
1989: . ncol, icol - number of columns and their local indices
1990: . y - a logically two-dimensional array of values
1991: - addv - either INSERT_VALUES or ADD_VALUES, where
1992: ADD_VALUES adds values to any existing entries, and
1993: INSERT_VALUES replaces existing entries with new values
1995: Notes:
1996: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1997: MatSetUp() before using this routine
1999: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2001: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2002: options cannot be mixed without intervening calls to the assembly
2003: routines.
2005: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2006: MUST be called after all calls to MatSetValuesLocal() have been completed.
2008: Level: intermediate
2010: Concepts: matrices^putting entries in with local numbering
2012: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2013: MatSetValueLocal()
2014: @*/
2015: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2016: {
2022: MatCheckPreallocated(mat,1);
2023: if (!nrow || !ncol) return(0); /* no values to insert */
2027: if (mat->insertmode == NOT_SET_VALUES) {
2028: mat->insertmode = addv;
2029: }
2030: #if defined(PETSC_USE_DEBUG)
2031: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2032: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2033: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2034: #endif
2036: if (mat->assembled) {
2037: mat->was_assembled = PETSC_TRUE;
2038: mat->assembled = PETSC_FALSE;
2039: }
2040: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2041: if (mat->ops->setvalueslocal) {
2042: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
2043: } else {
2044: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2045: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2046: irowm = buf; icolm = buf+nrow;
2047: } else {
2048: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2049: irowm = bufr; icolm = bufc;
2050: }
2051: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
2052: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
2053: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
2054: PetscFree2(bufr,bufc);
2055: }
2056: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2057: #if defined(PETSC_HAVE_CUSP)
2058: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2059: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2060: }
2061: #elif defined(PETSC_HAVE_VIENNACL)
2062: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2063: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2064: }
2065: #elif defined(PETSC_HAVE_VECCUDA)
2066: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2067: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2068: }
2069: #endif
2070: return(0);
2071: }
2075: /*@
2076: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2077: using a local ordering of the nodes a block at a time.
2079: Not Collective
2081: Input Parameters:
2082: + x - the matrix
2083: . nrow, irow - number of rows and their local indices
2084: . ncol, icol - number of columns and their local indices
2085: . y - a logically two-dimensional array of values
2086: - addv - either INSERT_VALUES or ADD_VALUES, where
2087: ADD_VALUES adds values to any existing entries, and
2088: INSERT_VALUES replaces existing entries with new values
2090: Notes:
2091: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2092: MatSetUp() before using this routine
2094: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2095: before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2097: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2098: options cannot be mixed without intervening calls to the assembly
2099: routines.
2101: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2102: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2104: Level: intermediate
2106: Concepts: matrices^putting blocked values in with local numbering
2108: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2109: MatSetValuesLocal(), MatSetValuesBlocked()
2110: @*/
2111: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2112: {
2118: MatCheckPreallocated(mat,1);
2119: if (!nrow || !ncol) return(0); /* no values to insert */
2123: if (mat->insertmode == NOT_SET_VALUES) {
2124: mat->insertmode = addv;
2125: }
2126: #if defined(PETSC_USE_DEBUG)
2127: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2128: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2129: if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2130: #endif
2132: if (mat->assembled) {
2133: mat->was_assembled = PETSC_TRUE;
2134: mat->assembled = PETSC_FALSE;
2135: }
2136: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2137: if (mat->ops->setvaluesblockedlocal) {
2138: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2139: } else {
2140: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2141: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2142: irowm = buf; icolm = buf + nrow;
2143: } else {
2144: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2145: irowm = bufr; icolm = bufc;
2146: }
2147: ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2148: ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2149: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2150: PetscFree2(bufr,bufc);
2151: }
2152: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2153: #if defined(PETSC_HAVE_CUSP)
2154: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2155: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2156: }
2157: #elif defined(PETSC_HAVE_VIENNACL)
2158: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2159: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2160: }
2161: #elif defined(PETSC_HAVE_VECCUDA)
2162: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2163: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2164: }
2165: #endif
2166: return(0);
2167: }
2171: /*@
2172: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2174: Collective on Mat and Vec
2176: Input Parameters:
2177: + mat - the matrix
2178: - x - the vector to be multiplied
2180: Output Parameters:
2181: . y - the result
2183: Notes:
2184: The vectors x and y cannot be the same. I.e., one cannot
2185: call MatMult(A,y,y).
2187: Level: developer
2189: Concepts: matrix-vector product
2191: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2192: @*/
2193: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2194: {
2203: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2204: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2205: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2206: MatCheckPreallocated(mat,1);
2208: if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2209: (*mat->ops->multdiagonalblock)(mat,x,y);
2210: PetscObjectStateIncrease((PetscObject)y);
2211: return(0);
2212: }
2214: /* --------------------------------------------------------*/
2217: /*@
2218: MatMult - Computes the matrix-vector product, y = Ax.
2220: Neighbor-wise Collective on Mat and Vec
2222: Input Parameters:
2223: + mat - the matrix
2224: - x - the vector to be multiplied
2226: Output Parameters:
2227: . y - the result
2229: Notes:
2230: The vectors x and y cannot be the same. I.e., one cannot
2231: call MatMult(A,y,y).
2233: Level: beginner
2235: Concepts: matrix-vector product
2237: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2238: @*/
2239: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2240: {
2248: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2249: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2250: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2251: #if !defined(PETSC_HAVE_CONSTRAINTS)
2252: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2253: if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2254: if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2255: #endif
2256: VecLocked(y,3);
2257: if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2258: MatCheckPreallocated(mat,1);
2260: VecLockPush(x);
2261: if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2262: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2263: (*mat->ops->mult)(mat,x,y);
2264: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2265: if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2266: VecLockPop(x);
2267: return(0);
2268: }
2272: /*@
2273: MatMultTranspose - Computes matrix transpose times a vector.
2275: Neighbor-wise Collective on Mat and Vec
2277: Input Parameters:
2278: + mat - the matrix
2279: - x - the vector to be multilplied
2281: Output Parameters:
2282: . y - the result
2284: Notes:
2285: The vectors x and y cannot be the same. I.e., one cannot
2286: call MatMultTranspose(A,y,y).
2288: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2289: use MatMultHermitianTranspose()
2291: Level: beginner
2293: Concepts: matrix vector product^transpose
2295: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2296: @*/
2297: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2298: {
2307: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2308: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2309: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2310: #if !defined(PETSC_HAVE_CONSTRAINTS)
2311: if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2312: if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2313: #endif
2314: if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2315: MatCheckPreallocated(mat,1);
2317: if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2318: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2319: VecLockPush(x);
2320: (*mat->ops->multtranspose)(mat,x,y);
2321: VecLockPop(x);
2322: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2323: PetscObjectStateIncrease((PetscObject)y);
2324: if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2325: return(0);
2326: }
2330: /*@
2331: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2333: Neighbor-wise Collective on Mat and Vec
2335: Input Parameters:
2336: + mat - the matrix
2337: - x - the vector to be multilplied
2339: Output Parameters:
2340: . y - the result
2342: Notes:
2343: The vectors x and y cannot be the same. I.e., one cannot
2344: call MatMultHermitianTranspose(A,y,y).
2346: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2348: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2350: Level: beginner
2352: Concepts: matrix vector product^transpose
2354: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2355: @*/
2356: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2357: {
2359: Vec w;
2367: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2368: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2369: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2370: #if !defined(PETSC_HAVE_CONSTRAINTS)
2371: if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2372: if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2373: #endif
2374: MatCheckPreallocated(mat,1);
2376: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2377: if (mat->ops->multhermitiantranspose) {
2378: VecLockPush(x);
2379: (*mat->ops->multhermitiantranspose)(mat,x,y);
2380: VecLockPop(x);
2381: } else {
2382: VecDuplicate(x,&w);
2383: VecCopy(x,w);
2384: VecConjugate(w);
2385: MatMultTranspose(mat,w,y);
2386: VecDestroy(&w);
2387: VecConjugate(y);
2388: }
2389: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2390: PetscObjectStateIncrease((PetscObject)y);
2391: return(0);
2392: }
2396: /*@
2397: MatMultAdd - Computes v3 = v2 + A * v1.
2399: Neighbor-wise Collective on Mat and Vec
2401: Input Parameters:
2402: + mat - the matrix
2403: - v1, v2 - the vectors
2405: Output Parameters:
2406: . v3 - the result
2408: Notes:
2409: The vectors v1 and v3 cannot be the same. I.e., one cannot
2410: call MatMultAdd(A,v1,v2,v1).
2412: Level: beginner
2414: Concepts: matrix vector product^addition
2416: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2417: @*/
2418: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2419: {
2429: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2430: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2431: if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2432: /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2433: if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2434: if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2435: if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2436: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2437: MatCheckPreallocated(mat,1);
2439: if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2440: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2441: VecLockPush(v1);
2442: (*mat->ops->multadd)(mat,v1,v2,v3);
2443: VecLockPop(v1);
2444: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2445: PetscObjectStateIncrease((PetscObject)v3);
2446: return(0);
2447: }
2451: /*@
2452: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2454: Neighbor-wise Collective on Mat and Vec
2456: Input Parameters:
2457: + mat - the matrix
2458: - v1, v2 - the vectors
2460: Output Parameters:
2461: . v3 - the result
2463: Notes:
2464: The vectors v1 and v3 cannot be the same. I.e., one cannot
2465: call MatMultTransposeAdd(A,v1,v2,v1).
2467: Level: beginner
2469: Concepts: matrix vector product^transpose and addition
2471: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2472: @*/
2473: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2474: {
2484: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2485: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2486: if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2487: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2488: if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2489: if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2490: if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2491: MatCheckPreallocated(mat,1);
2493: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2494: VecLockPush(v1);
2495: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2496: VecLockPop(v1);
2497: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2498: PetscObjectStateIncrease((PetscObject)v3);
2499: return(0);
2500: }
2504: /*@
2505: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2507: Neighbor-wise Collective on Mat and Vec
2509: Input Parameters:
2510: + mat - the matrix
2511: - v1, v2 - the vectors
2513: Output Parameters:
2514: . v3 - the result
2516: Notes:
2517: The vectors v1 and v3 cannot be the same. I.e., one cannot
2518: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2520: Level: beginner
2522: Concepts: matrix vector product^transpose and addition
2524: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2525: @*/
2526: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2527: {
2537: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2538: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2539: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2540: if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2541: if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2542: if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2543: MatCheckPreallocated(mat,1);
2545: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2546: VecLockPush(v1);
2547: if (mat->ops->multhermitiantransposeadd) {
2548: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2549: } else {
2550: Vec w,z;
2551: VecDuplicate(v1,&w);
2552: VecCopy(v1,w);
2553: VecConjugate(w);
2554: VecDuplicate(v3,&z);
2555: MatMultTranspose(mat,w,z);
2556: VecDestroy(&w);
2557: VecConjugate(z);
2558: VecWAXPY(v3,1.0,v2,z);
2559: VecDestroy(&z);
2560: }
2561: VecLockPop(v1);
2562: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2563: PetscObjectStateIncrease((PetscObject)v3);
2564: return(0);
2565: }
2569: /*@
2570: MatMultConstrained - The inner multiplication routine for a
2571: constrained matrix P^T A P.
2573: Neighbor-wise Collective on Mat and Vec
2575: Input Parameters:
2576: + mat - the matrix
2577: - x - the vector to be multilplied
2579: Output Parameters:
2580: . y - the result
2582: Notes:
2583: The vectors x and y cannot be the same. I.e., one cannot
2584: call MatMult(A,y,y).
2586: Level: beginner
2588: .keywords: matrix, multiply, matrix-vector product, constraint
2589: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2590: @*/
2591: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2592: {
2599: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2600: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2601: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2602: if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2603: if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2604: if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2606: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2607: VecLockPush(x);
2608: (*mat->ops->multconstrained)(mat,x,y);
2609: VecLockPop(x);
2610: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2611: PetscObjectStateIncrease((PetscObject)y);
2612: return(0);
2613: }
2617: /*@
2618: MatMultTransposeConstrained - The inner multiplication routine for a
2619: constrained matrix P^T A^T P.
2621: Neighbor-wise Collective on Mat and Vec
2623: Input Parameters:
2624: + mat - the matrix
2625: - x - the vector to be multilplied
2627: Output Parameters:
2628: . y - the result
2630: Notes:
2631: The vectors x and y cannot be the same. I.e., one cannot
2632: call MatMult(A,y,y).
2634: Level: beginner
2636: .keywords: matrix, multiply, matrix-vector product, constraint
2637: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2638: @*/
2639: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2640: {
2647: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2648: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2649: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2650: if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2651: if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2653: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2654: (*mat->ops->multtransposeconstrained)(mat,x,y);
2655: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2656: PetscObjectStateIncrease((PetscObject)y);
2657: return(0);
2658: }
2662: /*@C
2663: MatGetFactorType - gets the type of factorization it is
2665: Note Collective
2666: as the flag
2668: Input Parameters:
2669: . mat - the matrix
2671: Output Parameters:
2672: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2674: Level: intermediate
2676: .seealso: MatFactorType, MatGetFactor()
2677: @*/
2678: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2679: {
2683: *t = mat->factortype;
2684: return(0);
2685: }
2687: /* ------------------------------------------------------------*/
2690: /*@C
2691: MatGetInfo - Returns information about matrix storage (number of
2692: nonzeros, memory, etc.).
2694: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2696: Input Parameters:
2697: . mat - the matrix
2699: Output Parameters:
2700: + flag - flag indicating the type of parameters to be returned
2701: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2702: MAT_GLOBAL_SUM - sum over all processors)
2703: - info - matrix information context
2705: Notes:
2706: The MatInfo context contains a variety of matrix data, including
2707: number of nonzeros allocated and used, number of mallocs during
2708: matrix assembly, etc. Additional information for factored matrices
2709: is provided (such as the fill ratio, number of mallocs during
2710: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2711: when using the runtime options
2712: $ -info -mat_view ::ascii_info
2714: Example for C/C++ Users:
2715: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2716: data within the MatInfo context. For example,
2717: .vb
2718: MatInfo info;
2719: Mat A;
2720: double mal, nz_a, nz_u;
2722: MatGetInfo(A,MAT_LOCAL,&info);
2723: mal = info.mallocs;
2724: nz_a = info.nz_allocated;
2725: .ve
2727: Example for Fortran Users:
2728: Fortran users should declare info as a double precision
2729: array of dimension MAT_INFO_SIZE, and then extract the parameters
2730: of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2731: a complete list of parameter names.
2732: .vb
2733: double precision info(MAT_INFO_SIZE)
2734: double precision mal, nz_a
2735: Mat A
2736: integer ierr
2738: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2739: mal = info(MAT_INFO_MALLOCS)
2740: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2741: .ve
2743: Level: intermediate
2745: Concepts: matrices^getting information on
2747: Developer Note: fortran interface is not autogenerated as the f90
2748: interface defintion cannot be generated correctly [due to MatInfo]
2750: .seealso: MatStashGetInfo()
2752: @*/
2753: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2754: {
2761: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2762: MatCheckPreallocated(mat,1);
2763: (*mat->ops->getinfo)(mat,flag,info);
2764: return(0);
2765: }
2767: /* ----------------------------------------------------------*/
2771: /*@C
2772: MatLUFactor - Performs in-place LU factorization of matrix.
2774: Collective on Mat
2776: Input Parameters:
2777: + mat - the matrix
2778: . row - row permutation
2779: . col - column permutation
2780: - info - options for factorization, includes
2781: $ fill - expected fill as ratio of original fill.
2782: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2783: $ Run with the option -info to determine an optimal value to use
2785: Notes:
2786: Most users should employ the simplified KSP interface for linear solvers
2787: instead of working directly with matrix algebra routines such as this.
2788: See, e.g., KSPCreate().
2790: This changes the state of the matrix to a factored matrix; it cannot be used
2791: for example with MatSetValues() unless one first calls MatSetUnfactored().
2793: Level: developer
2795: Concepts: matrices^LU factorization
2797: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2798: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2800: Developer Note: fortran interface is not autogenerated as the f90
2801: interface defintion cannot be generated correctly [due to MatFactorInfo]
2803: @*/
2804: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2805: {
2807: MatFactorInfo tinfo;
2815: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2816: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2817: if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2818: MatCheckPreallocated(mat,1);
2819: if (!info) {
2820: MatFactorInfoInitialize(&tinfo);
2821: info = &tinfo;
2822: }
2824: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2825: (*mat->ops->lufactor)(mat,row,col,info);
2826: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2827: PetscObjectStateIncrease((PetscObject)mat);
2828: return(0);
2829: }
2833: /*@C
2834: MatILUFactor - Performs in-place ILU factorization of matrix.
2836: Collective on Mat
2838: Input Parameters:
2839: + mat - the matrix
2840: . row - row permutation
2841: . col - column permutation
2842: - info - structure containing
2843: $ levels - number of levels of fill.
2844: $ expected fill - as ratio of original fill.
2845: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2846: missing diagonal entries)
2848: Notes:
2849: Probably really in-place only when level of fill is zero, otherwise allocates
2850: new space to store factored matrix and deletes previous memory.
2852: Most users should employ the simplified KSP interface for linear solvers
2853: instead of working directly with matrix algebra routines such as this.
2854: See, e.g., KSPCreate().
2856: Level: developer
2858: Concepts: matrices^ILU factorization
2860: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2862: Developer Note: fortran interface is not autogenerated as the f90
2863: interface defintion cannot be generated correctly [due to MatFactorInfo]
2865: @*/
2866: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2867: {
2876: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2877: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2878: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2879: if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2880: MatCheckPreallocated(mat,1);
2882: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2883: (*mat->ops->ilufactor)(mat,row,col,info);
2884: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2885: PetscObjectStateIncrease((PetscObject)mat);
2886: return(0);
2887: }
2891: /*@C
2892: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2893: Call this routine before calling MatLUFactorNumeric().
2895: Collective on Mat
2897: Input Parameters:
2898: + fact - the factor matrix obtained with MatGetFactor()
2899: . mat - the matrix
2900: . row, col - row and column permutations
2901: - info - options for factorization, includes
2902: $ fill - expected fill as ratio of original fill.
2903: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2904: $ Run with the option -info to determine an optimal value to use
2907: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2909: Most users should employ the simplified KSP interface for linear solvers
2910: instead of working directly with matrix algebra routines such as this.
2911: See, e.g., KSPCreate().
2913: Level: developer
2915: Concepts: matrices^LU symbolic factorization
2917: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
2919: Developer Note: fortran interface is not autogenerated as the f90
2920: interface defintion cannot be generated correctly [due to MatFactorInfo]
2922: @*/
2923: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2924: {
2934: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2935: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2936: if (!(fact)->ops->lufactorsymbolic) {
2937: const MatSolverPackage spackage;
2938: MatFactorGetSolverPackage(fact,&spackage);
2939: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2940: }
2941: MatCheckPreallocated(mat,2);
2943: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2944: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2945: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2946: PetscObjectStateIncrease((PetscObject)fact);
2947: return(0);
2948: }
2952: /*@C
2953: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2954: Call this routine after first calling MatLUFactorSymbolic().
2956: Collective on Mat
2958: Input Parameters:
2959: + fact - the factor matrix obtained with MatGetFactor()
2960: . mat - the matrix
2961: - info - options for factorization
2963: Notes:
2964: See MatLUFactor() for in-place factorization. See
2965: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2967: Most users should employ the simplified KSP interface for linear solvers
2968: instead of working directly with matrix algebra routines such as this.
2969: See, e.g., KSPCreate().
2971: Level: developer
2973: Concepts: matrices^LU numeric factorization
2975: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2977: Developer Note: fortran interface is not autogenerated as the f90
2978: interface defintion cannot be generated correctly [due to MatFactorInfo]
2980: @*/
2981: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2982: {
2990: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2991: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
2993: if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2994: MatCheckPreallocated(mat,2);
2995: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2996: (fact->ops->lufactornumeric)(fact,mat,info);
2997: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2998: MatViewFromOptions(fact,NULL,"-mat_factor_view");
2999: PetscObjectStateIncrease((PetscObject)fact);
3000: return(0);
3001: }
3005: /*@C
3006: MatCholeskyFactor - Performs in-place Cholesky factorization of a
3007: symmetric matrix.
3009: Collective on Mat
3011: Input Parameters:
3012: + mat - the matrix
3013: . perm - row and column permutations
3014: - f - expected fill as ratio of original fill
3016: Notes:
3017: See MatLUFactor() for the nonsymmetric case. See also
3018: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3020: Most users should employ the simplified KSP interface for linear solvers
3021: instead of working directly with matrix algebra routines such as this.
3022: See, e.g., KSPCreate().
3024: Level: developer
3026: Concepts: matrices^Cholesky factorization
3028: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3029: MatGetOrdering()
3031: Developer Note: fortran interface is not autogenerated as the f90
3032: interface defintion cannot be generated correctly [due to MatFactorInfo]
3034: @*/
3035: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3036: {
3044: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3045: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3046: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3047: if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3048: MatCheckPreallocated(mat,1);
3050: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3051: (*mat->ops->choleskyfactor)(mat,perm,info);
3052: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3053: PetscObjectStateIncrease((PetscObject)mat);
3054: return(0);
3055: }
3059: /*@C
3060: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3061: of a symmetric matrix.
3063: Collective on Mat
3065: Input Parameters:
3066: + fact - the factor matrix obtained with MatGetFactor()
3067: . mat - the matrix
3068: . perm - row and column permutations
3069: - info - options for factorization, includes
3070: $ fill - expected fill as ratio of original fill.
3071: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3072: $ Run with the option -info to determine an optimal value to use
3074: Notes:
3075: See MatLUFactorSymbolic() for the nonsymmetric case. See also
3076: MatCholeskyFactor() and MatCholeskyFactorNumeric().
3078: Most users should employ the simplified KSP interface for linear solvers
3079: instead of working directly with matrix algebra routines such as this.
3080: See, e.g., KSPCreate().
3082: Level: developer
3084: Concepts: matrices^Cholesky symbolic factorization
3086: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3087: MatGetOrdering()
3089: Developer Note: fortran interface is not autogenerated as the f90
3090: interface defintion cannot be generated correctly [due to MatFactorInfo]
3092: @*/
3093: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3094: {
3103: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3104: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3105: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3106: if (!(fact)->ops->choleskyfactorsymbolic) {
3107: const MatSolverPackage spackage;
3108: MatFactorGetSolverPackage(fact,&spackage);
3109: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3110: }
3111: MatCheckPreallocated(mat,2);
3113: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3114: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3115: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3116: PetscObjectStateIncrease((PetscObject)fact);
3117: return(0);
3118: }
3122: /*@C
3123: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3124: of a symmetric matrix. Call this routine after first calling
3125: MatCholeskyFactorSymbolic().
3127: Collective on Mat
3129: Input Parameters:
3130: + fact - the factor matrix obtained with MatGetFactor()
3131: . mat - the initial matrix
3132: . info - options for factorization
3133: - fact - the symbolic factor of mat
3136: Notes:
3137: Most users should employ the simplified KSP interface for linear solvers
3138: instead of working directly with matrix algebra routines such as this.
3139: See, e.g., KSPCreate().
3141: Level: developer
3143: Concepts: matrices^Cholesky numeric factorization
3145: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3147: Developer Note: fortran interface is not autogenerated as the f90
3148: interface defintion cannot be generated correctly [due to MatFactorInfo]
3150: @*/
3151: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3152: {
3160: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3161: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3162: if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3163: MatCheckPreallocated(mat,2);
3165: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3166: (fact->ops->choleskyfactornumeric)(fact,mat,info);
3167: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3168: MatViewFromOptions(fact,NULL,"-mat_factor_view");
3169: PetscObjectStateIncrease((PetscObject)fact);
3170: return(0);
3171: }
3173: /* ----------------------------------------------------------------*/
3176: /*@
3177: MatSolve - Solves A x = b, given a factored matrix.
3179: Neighbor-wise Collective on Mat and Vec
3181: Input Parameters:
3182: + mat - the factored matrix
3183: - b - the right-hand-side vector
3185: Output Parameter:
3186: . x - the result vector
3188: Notes:
3189: The vectors b and x cannot be the same. I.e., one cannot
3190: call MatSolve(A,x,x).
3192: Notes:
3193: Most users should employ the simplified KSP interface for linear solvers
3194: instead of working directly with matrix algebra routines such as this.
3195: See, e.g., KSPCreate().
3197: Level: developer
3199: Concepts: matrices^triangular solves
3201: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3202: @*/
3203: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3204: {
3214: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3215: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3216: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3217: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3218: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3219: if (!mat->rmap->N && !mat->cmap->N) return(0);
3220: if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3221: MatCheckPreallocated(mat,1);
3223: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3224: if (mat->errortype) {
3225: PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3226: VecSetInf(x);
3227: } else {
3228: (*mat->ops->solve)(mat,b,x);
3229: }
3230: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3231: PetscObjectStateIncrease((PetscObject)x);
3232: return(0);
3233: }
3237: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3238: {
3240: Vec b,x;
3241: PetscInt m,N,i;
3242: PetscScalar *bb,*xx;
3243: PetscBool flg;
3246: PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3247: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3248: PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3249: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3251: MatDenseGetArray(B,&bb);
3252: MatDenseGetArray(X,&xx);
3253: MatGetLocalSize(B,&m,NULL); /* number local rows */
3254: MatGetSize(B,NULL,&N); /* total columns in dense matrix */
3255: MatCreateVecs(A,&x,&b);
3256: for (i=0; i<N; i++) {
3257: VecPlaceArray(b,bb + i*m);
3258: VecPlaceArray(x,xx + i*m);
3259: MatSolve(A,b,x);
3260: VecResetArray(x);
3261: VecResetArray(b);
3262: }
3263: VecDestroy(&b);
3264: VecDestroy(&x);
3265: MatDenseRestoreArray(B,&bb);
3266: MatDenseRestoreArray(X,&xx);
3267: return(0);
3268: }
3272: /*@
3273: MatMatSolve - Solves A X = B, given a factored matrix.
3275: Neighbor-wise Collective on Mat
3277: Input Parameters:
3278: + A - the factored matrix
3279: - B - the right-hand-side matrix (dense matrix)
3281: Output Parameter:
3282: . X - the result matrix (dense matrix)
3284: Notes:
3285: The matrices b and x cannot be the same. I.e., one cannot
3286: call MatMatSolve(A,x,x).
3288: Notes:
3289: Most users should usually employ the simplified KSP interface for linear solvers
3290: instead of working directly with matrix algebra routines such as this.
3291: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3292: at a time.
3294: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3295: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3297: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3299: Level: developer
3301: Concepts: matrices^triangular solves
3303: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3304: @*/
3305: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3306: {
3316: if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3317: if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3318: if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3319: if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3320: if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3321: if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3322: if (!A->rmap->N && !A->cmap->N) return(0);
3323: MatCheckPreallocated(A,1);
3325: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3326: if (!A->ops->matsolve) {
3327: PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3328: MatMatSolve_Basic(A,B,X);
3329: } else {
3330: (*A->ops->matsolve)(A,B,X);
3331: }
3332: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3333: PetscObjectStateIncrease((PetscObject)X);
3334: return(0);
3335: }
3340: /*@
3341: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3342: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3344: Neighbor-wise Collective on Mat and Vec
3346: Input Parameters:
3347: + mat - the factored matrix
3348: - b - the right-hand-side vector
3350: Output Parameter:
3351: . x - the result vector
3353: Notes:
3354: MatSolve() should be used for most applications, as it performs
3355: a forward solve followed by a backward solve.
3357: The vectors b and x cannot be the same, i.e., one cannot
3358: call MatForwardSolve(A,x,x).
3360: For matrix in seqsbaij format with block size larger than 1,
3361: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3362: MatForwardSolve() solves U^T*D y = b, and
3363: MatBackwardSolve() solves U x = y.
3364: Thus they do not provide a symmetric preconditioner.
3366: Most users should employ the simplified KSP interface for linear solvers
3367: instead of working directly with matrix algebra routines such as this.
3368: See, e.g., KSPCreate().
3370: Level: developer
3372: Concepts: matrices^forward solves
3374: .seealso: MatSolve(), MatBackwardSolve()
3375: @*/
3376: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3377: {
3387: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3388: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3389: if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3390: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3391: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3392: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3393: MatCheckPreallocated(mat,1);
3394: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3395: (*mat->ops->forwardsolve)(mat,b,x);
3396: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3397: PetscObjectStateIncrease((PetscObject)x);
3398: return(0);
3399: }
3403: /*@
3404: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3405: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3407: Neighbor-wise Collective on Mat and Vec
3409: Input Parameters:
3410: + mat - the factored matrix
3411: - b - the right-hand-side vector
3413: Output Parameter:
3414: . x - the result vector
3416: Notes:
3417: MatSolve() should be used for most applications, as it performs
3418: a forward solve followed by a backward solve.
3420: The vectors b and x cannot be the same. I.e., one cannot
3421: call MatBackwardSolve(A,x,x).
3423: For matrix in seqsbaij format with block size larger than 1,
3424: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3425: MatForwardSolve() solves U^T*D y = b, and
3426: MatBackwardSolve() solves U x = y.
3427: Thus they do not provide a symmetric preconditioner.
3429: Most users should employ the simplified KSP interface for linear solvers
3430: instead of working directly with matrix algebra routines such as this.
3431: See, e.g., KSPCreate().
3433: Level: developer
3435: Concepts: matrices^backward solves
3437: .seealso: MatSolve(), MatForwardSolve()
3438: @*/
3439: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3440: {
3450: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3451: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3452: if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3453: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3454: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3455: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3456: MatCheckPreallocated(mat,1);
3458: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3459: (*mat->ops->backwardsolve)(mat,b,x);
3460: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3461: PetscObjectStateIncrease((PetscObject)x);
3462: return(0);
3463: }
3467: /*@
3468: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3470: Neighbor-wise Collective on Mat and Vec
3472: Input Parameters:
3473: + mat - the factored matrix
3474: . b - the right-hand-side vector
3475: - y - the vector to be added to
3477: Output Parameter:
3478: . x - the result vector
3480: Notes:
3481: The vectors b and x cannot be the same. I.e., one cannot
3482: call MatSolveAdd(A,x,y,x).
3484: Most users should employ the simplified KSP interface for linear solvers
3485: instead of working directly with matrix algebra routines such as this.
3486: See, e.g., KSPCreate().
3488: Level: developer
3490: Concepts: matrices^triangular solves
3492: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3493: @*/
3494: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3495: {
3496: PetscScalar one = 1.0;
3497: Vec tmp;
3509: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3510: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3511: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3512: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3513: if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3514: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3515: if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3516: MatCheckPreallocated(mat,1);
3518: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3519: if (mat->ops->solveadd) {
3520: (*mat->ops->solveadd)(mat,b,y,x);
3521: } else {
3522: /* do the solve then the add manually */
3523: if (x != y) {
3524: MatSolve(mat,b,x);
3525: VecAXPY(x,one,y);
3526: } else {
3527: VecDuplicate(x,&tmp);
3528: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3529: VecCopy(x,tmp);
3530: MatSolve(mat,b,x);
3531: VecAXPY(x,one,tmp);
3532: VecDestroy(&tmp);
3533: }
3534: }
3535: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3536: PetscObjectStateIncrease((PetscObject)x);
3537: return(0);
3538: }
3542: /*@
3543: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3545: Neighbor-wise Collective on Mat and Vec
3547: Input Parameters:
3548: + mat - the factored matrix
3549: - b - the right-hand-side vector
3551: Output Parameter:
3552: . x - the result vector
3554: Notes:
3555: The vectors b and x cannot be the same. I.e., one cannot
3556: call MatSolveTranspose(A,x,x).
3558: Most users should employ the simplified KSP interface for linear solvers
3559: instead of working directly with matrix algebra routines such as this.
3560: See, e.g., KSPCreate().
3562: Level: developer
3564: Concepts: matrices^triangular solves
3566: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3567: @*/
3568: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3569: {
3579: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3580: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3581: if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3582: if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3583: if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3584: MatCheckPreallocated(mat,1);
3585: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3586: if (mat->errortype) {
3587: PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3588: VecSetInf(x);
3589: } else {
3590: (*mat->ops->solvetranspose)(mat,b,x);
3591: }
3592: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3593: PetscObjectStateIncrease((PetscObject)x);
3594: return(0);
3595: }
3599: /*@
3600: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3601: factored matrix.
3603: Neighbor-wise Collective on Mat and Vec
3605: Input Parameters:
3606: + mat - the factored matrix
3607: . b - the right-hand-side vector
3608: - y - the vector to be added to
3610: Output Parameter:
3611: . x - the result vector
3613: Notes:
3614: The vectors b and x cannot be the same. I.e., one cannot
3615: call MatSolveTransposeAdd(A,x,y,x).
3617: Most users should employ the simplified KSP interface for linear solvers
3618: instead of working directly with matrix algebra routines such as this.
3619: See, e.g., KSPCreate().
3621: Level: developer
3623: Concepts: matrices^triangular solves
3625: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3626: @*/
3627: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3628: {
3629: PetscScalar one = 1.0;
3631: Vec tmp;
3642: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3643: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3644: if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3645: if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3646: if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3647: if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3648: MatCheckPreallocated(mat,1);
3650: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3651: if (mat->ops->solvetransposeadd) {
3652: if (mat->errortype) {
3653: PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3654: VecSetInf(x);
3655: } else {
3656: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3657: }
3658: } else {
3659: /* do the solve then the add manually */
3660: if (x != y) {
3661: MatSolveTranspose(mat,b,x);
3662: VecAXPY(x,one,y);
3663: } else {
3664: VecDuplicate(x,&tmp);
3665: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3666: VecCopy(x,tmp);
3667: MatSolveTranspose(mat,b,x);
3668: VecAXPY(x,one,tmp);
3669: VecDestroy(&tmp);
3670: }
3671: }
3672: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3673: PetscObjectStateIncrease((PetscObject)x);
3674: return(0);
3675: }
3676: /* ----------------------------------------------------------------*/
3680: /*@
3681: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3683: Neighbor-wise Collective on Mat and Vec
3685: Input Parameters:
3686: + mat - the matrix
3687: . b - the right hand side
3688: . omega - the relaxation factor
3689: . flag - flag indicating the type of SOR (see below)
3690: . shift - diagonal shift
3691: . its - the number of iterations
3692: - lits - the number of local iterations
3694: Output Parameters:
3695: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3697: SOR Flags:
3698: . SOR_FORWARD_SWEEP - forward SOR
3699: . SOR_BACKWARD_SWEEP - backward SOR
3700: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3701: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3702: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3703: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3704: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3705: upper/lower triangular part of matrix to
3706: vector (with omega)
3707: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3709: Notes:
3710: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3711: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3712: on each processor.
3714: Application programmers will not generally use MatSOR() directly,
3715: but instead will employ the KSP/PC interface.
3717: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3719: Notes for Advanced Users:
3720: The flags are implemented as bitwise inclusive or operations.
3721: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3722: to specify a zero initial guess for SSOR.
3724: Most users should employ the simplified KSP interface for linear solvers
3725: instead of working directly with matrix algebra routines such as this.
3726: See, e.g., KSPCreate().
3728: Vectors x and b CANNOT be the same
3730: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3732: Level: developer
3734: Concepts: matrices^relaxation
3735: Concepts: matrices^SOR
3736: Concepts: matrices^Gauss-Seidel
3738: @*/
3739: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3740: {
3750: if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3751: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3752: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3753: if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3754: if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3755: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3756: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3757: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3758: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3760: MatCheckPreallocated(mat,1);
3761: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3762: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3763: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3764: PetscObjectStateIncrease((PetscObject)x);
3765: return(0);
3766: }
3770: /*
3771: Default matrix copy routine.
3772: */
3773: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3774: {
3775: PetscErrorCode ierr;
3776: PetscInt i,rstart = 0,rend = 0,nz;
3777: const PetscInt *cwork;
3778: const PetscScalar *vwork;
3781: if (B->assembled) {
3782: MatZeroEntries(B);
3783: }
3784: MatGetOwnershipRange(A,&rstart,&rend);
3785: for (i=rstart; i<rend; i++) {
3786: MatGetRow(A,i,&nz,&cwork,&vwork);
3787: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3788: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3789: }
3790: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3791: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3792: PetscObjectStateIncrease((PetscObject)B);
3793: return(0);
3794: }
3798: /*@
3799: MatCopy - Copys a matrix to another matrix.
3801: Collective on Mat
3803: Input Parameters:
3804: + A - the matrix
3805: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3807: Output Parameter:
3808: . B - where the copy is put
3810: Notes:
3811: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3812: same nonzero pattern or the routine will crash.
3814: MatCopy() copies the matrix entries of a matrix to another existing
3815: matrix (after first zeroing the second matrix). A related routine is
3816: MatConvert(), which first creates a new matrix and then copies the data.
3818: Level: intermediate
3820: Concepts: matrices^copying
3822: .seealso: MatConvert(), MatDuplicate()
3824: @*/
3825: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3826: {
3828: PetscInt i;
3836: MatCheckPreallocated(B,2);
3837: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3838: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3839: if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
3840: MatCheckPreallocated(A,1);
3842: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3843: if (A->ops->copy) {
3844: (*A->ops->copy)(A,B,str);
3845: } else { /* generic conversion */
3846: MatCopy_Basic(A,B,str);
3847: }
3849: B->stencil.dim = A->stencil.dim;
3850: B->stencil.noc = A->stencil.noc;
3851: for (i=0; i<=A->stencil.dim; i++) {
3852: B->stencil.dims[i] = A->stencil.dims[i];
3853: B->stencil.starts[i] = A->stencil.starts[i];
3854: }
3856: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3857: PetscObjectStateIncrease((PetscObject)B);
3858: return(0);
3859: }
3863: /*@C
3864: MatConvert - Converts a matrix to another matrix, either of the same
3865: or different type.
3867: Collective on Mat
3869: Input Parameters:
3870: + mat - the matrix
3871: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3872: same type as the original matrix.
3873: - reuse - denotes if the destination matrix is to be created or reused.
3874: Use MAT_INPLACE_MATRIX for inplace conversion, otherwise use
3875: MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX.
3877: Output Parameter:
3878: . M - pointer to place new matrix
3880: Notes:
3881: MatConvert() first creates a new matrix and then copies the data from
3882: the first matrix. A related routine is MatCopy(), which copies the matrix
3883: entries of one matrix to another already existing matrix context.
3885: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3886: the MPI communicator of the generated matrix is always the same as the communicator
3887: of the input matrix.
3889: Level: intermediate
3891: Concepts: matrices^converting between storage formats
3893: .seealso: MatCopy(), MatDuplicate()
3894: @*/
3895: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3896: {
3898: PetscBool sametype,issame,flg;
3899: char convname[256],mtype[256];
3900: Mat B;
3906: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3907: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3908: MatCheckPreallocated(mat,1);
3909: MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);
3911: PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3912: if (flg) {
3913: newtype = mtype;
3914: }
3915: PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3916: PetscStrcmp(newtype,"same",&issame);
3917: if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
3919: if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) return(0);
3921: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3922: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3923: } else {
3924: PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3925: const char *prefix[3] = {"seq","mpi",""};
3926: PetscInt i;
3927: /*
3928: Order of precedence:
3929: 1) See if a specialized converter is known to the current matrix.
3930: 2) See if a specialized converter is known to the desired matrix class.
3931: 3) See if a good general converter is registered for the desired class
3932: (as of 6/27/03 only MATMPIADJ falls into this category).
3933: 4) See if a good general converter is known for the current matrix.
3934: 5) Use a really basic converter.
3935: */
3937: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3938: for (i=0; i<3; i++) {
3939: PetscStrcpy(convname,"MatConvert_");
3940: PetscStrcat(convname,((PetscObject)mat)->type_name);
3941: PetscStrcat(convname,"_");
3942: PetscStrcat(convname,prefix[i]);
3943: PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3944: PetscStrcat(convname,"_C");
3945: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3946: if (conv) goto foundconv;
3947: }
3949: /* 2) See if a specialized converter is known to the desired matrix class. */
3950: MatCreate(PetscObjectComm((PetscObject)mat),&B);
3951: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3952: MatSetType(B,newtype);
3953: for (i=0; i<3; i++) {
3954: PetscStrcpy(convname,"MatConvert_");
3955: PetscStrcat(convname,((PetscObject)mat)->type_name);
3956: PetscStrcat(convname,"_");
3957: PetscStrcat(convname,prefix[i]);
3958: PetscStrcat(convname,newtype);
3959: PetscStrcat(convname,"_C");
3960: PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3961: if (conv) {
3962: MatDestroy(&B);
3963: goto foundconv;
3964: }
3965: }
3967: /* 3) See if a good general converter is registered for the desired class */
3968: conv = B->ops->convertfrom;
3969: MatDestroy(&B);
3970: if (conv) goto foundconv;
3972: /* 4) See if a good general converter is known for the current matrix */
3973: if (mat->ops->convert) {
3974: conv = mat->ops->convert;
3975: }
3976: if (conv) goto foundconv;
3978: /* 5) Use a really basic converter. */
3979: conv = MatConvert_Basic;
3981: foundconv:
3982: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3983: (*conv)(mat,newtype,reuse,M);
3984: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3985: }
3986: PetscObjectStateIncrease((PetscObject)*M);
3988: /* Copy Mat options */
3989: if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3990: if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3991: return(0);
3992: }
3996: /*@C
3997: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3999: Not Collective
4001: Input Parameter:
4002: . mat - the matrix, must be a factored matrix
4004: Output Parameter:
4005: . type - the string name of the package (do not free this string)
4007: Notes:
4008: In Fortran you pass in a empty string and the package name will be copied into it.
4009: (Make sure the string is long enough)
4011: Level: intermediate
4013: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4014: @*/
4015: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4016: {
4017: PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
4022: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4023: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
4024: if (!conv) {
4025: *type = MATSOLVERPETSC;
4026: } else {
4027: (*conv)(mat,type);
4028: }
4029: return(0);
4030: }
4032: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4033: struct _MatSolverPackageForSpecifcType {
4034: MatType mtype;
4035: PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*);
4036: MatSolverPackageForSpecifcType next;
4037: };
4039: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4040: struct _MatSolverPackageHolder {
4041: char *name;
4042: MatSolverPackageForSpecifcType handlers;
4043: MatSolverPackageHolder next;
4044: };
4046: static MatSolverPackageHolder MatSolverPackageHolders = NULL;
4050: /*@C
4051: MatSolvePackageRegister - Registers a MatSolverPackage that works for a particular matrix type
4053: Input Parameters:
4054: + package - name of the package, for example petsc or superlu
4055: . mtype - the matrix type that works with this package
4056: . ftype - the type of factorization supported by the package
4057: - getfactor - routine that will create the factored matrix ready to be used
4059: Level: intermediate
4061: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4062: @*/
4063: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4064: {
4065: PetscErrorCode ierr;
4066: MatSolverPackageHolder next = MatSolverPackageHolders,prev;
4067: PetscBool flg;
4068: MatSolverPackageForSpecifcType inext,iprev = NULL;
4071: if (!next) {
4072: PetscNew(&MatSolverPackageHolders);
4073: PetscStrallocpy(package,&MatSolverPackageHolders->name);
4074: PetscNew(&MatSolverPackageHolders->handlers);
4075: PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4076: MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4077: return(0);
4078: }
4079: while (next) {
4080: PetscStrcasecmp(package,next->name,&flg);
4081: if (flg) {
4082: inext = next->handlers;
4083: while (inext) {
4084: PetscStrcasecmp(mtype,inext->mtype,&flg);
4085: if (flg) {
4086: inext->getfactor[(int)ftype-1] = getfactor;
4087: return(0);
4088: }
4089: iprev = inext;
4090: inext = inext->next;
4091: }
4092: PetscNew(&iprev->next);
4093: PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4094: iprev->next->getfactor[(int)ftype-1] = getfactor;
4095: return(0);
4096: }
4097: prev = next;
4098: next = next->next;
4099: }
4100: PetscNew(&prev->next);
4101: PetscStrallocpy(package,&prev->next->name);
4102: PetscNew(&prev->next->handlers);
4103: PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4104: prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4105: return(0);
4106: }
4110: /*@C
4111: MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4113: Input Parameters:
4114: + package - name of the package, for example petsc or superlu
4115: . ftype - the type of factorization supported by the package
4116: - mtype - the matrix type that works with this package
4118: Output Parameters:
4119: + foundpackage - PETSC_TRUE if the package was registered
4120: . foundmtype - PETSC_TRUE if the package supports the requested mtype
4121: - getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4123: Level: intermediate
4125: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4126: @*/
4127: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4128: {
4129: PetscErrorCode ierr;
4130: MatSolverPackageHolder next = MatSolverPackageHolders;
4131: PetscBool flg;
4132: MatSolverPackageForSpecifcType inext;
4135: if (foundpackage) *foundpackage = PETSC_FALSE;
4136: if (foundmtype) *foundmtype = PETSC_FALSE;
4137: if (getfactor) *getfactor = NULL;
4139: if (package) {
4140: while (next) {
4141: PetscStrcasecmp(package,next->name,&flg);
4142: if (flg) {
4143: if (foundpackage) *foundpackage = PETSC_TRUE;
4144: inext = next->handlers;
4145: while (inext) {
4146: PetscStrcasecmp(mtype,inext->mtype,&flg);
4147: if (flg) {
4148: if (foundmtype) *foundmtype = PETSC_TRUE;
4149: if (getfactor) *getfactor = inext->getfactor[(int)ftype-1];
4150: return(0);
4151: }
4152: inext = inext->next;
4153: }
4154: }
4155: next = next->next;
4156: }
4157: } else {
4158: while (next) {
4159: inext = next->handlers;
4160: while (inext) {
4161: PetscStrcasecmp(mtype,inext->mtype,&flg);
4162: if (flg && inext->getfactor[(int)ftype-1]) {
4163: if (foundpackage) *foundpackage = PETSC_TRUE;
4164: if (foundmtype) *foundmtype = PETSC_TRUE;
4165: if (getfactor) *getfactor = inext->getfactor[(int)ftype-1];
4166: return(0);
4167: }
4168: inext = inext->next;
4169: }
4170: next = next->next;
4171: }
4172: }
4173: return(0);
4174: }
4178: PetscErrorCode MatSolverPackageDestroy(void)
4179: {
4180: PetscErrorCode ierr;
4181: MatSolverPackageHolder next = MatSolverPackageHolders,prev;
4182: MatSolverPackageForSpecifcType inext,iprev;
4185: while (next) {
4186: PetscFree(next->name);
4187: inext = next->handlers;
4188: while (inext) {
4189: PetscFree(inext->mtype);
4190: iprev = inext;
4191: inext = inext->next;
4192: PetscFree(iprev);
4193: }
4194: prev = next;
4195: next = next->next;
4196: PetscFree(prev);
4197: }
4198: MatSolverPackageHolders = NULL;
4199: return(0);
4200: }
4204: /*@C
4205: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4207: Collective on Mat
4209: Input Parameters:
4210: + mat - the matrix
4211: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4212: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4214: Output Parameters:
4215: . f - the factor matrix used with MatXXFactorSymbolic() calls
4217: Notes:
4218: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4219: such as pastix, superlu, mumps etc.
4221: PETSc must have been ./configure to use the external solver, using the option --download-package
4223: Level: intermediate
4225: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4226: @*/
4227: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4228: {
4229: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4230: PetscBool foundpackage,foundmtype;
4236: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4237: MatCheckPreallocated(mat,1);
4239: MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4240: if (!foundpackage) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4241: if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4242: 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);
4244: (*conv)(mat,ftype,f);
4245: return(0);
4246: }
4250: /*@C
4251: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4253: Not Collective
4255: Input Parameters:
4256: + mat - the matrix
4257: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4258: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4260: Output Parameter:
4261: . flg - PETSC_TRUE if the factorization is available
4263: Notes:
4264: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4265: such as pastix, superlu, mumps etc.
4267: PETSc must have been ./configure to use the external solver, using the option --download-package
4269: Level: intermediate
4271: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4272: @*/
4273: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg)
4274: {
4275: PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4281: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4282: MatCheckPreallocated(mat,1);
4284: *flg = PETSC_FALSE;
4285: MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4286: if (gconv) {
4287: *flg = PETSC_TRUE;
4288: }
4289: return(0);
4290: }
4292: #include <petscdmtypes.h>
4296: /*@
4297: MatDuplicate - Duplicates a matrix including the non-zero structure.
4299: Collective on Mat
4301: Input Parameters:
4302: + mat - the matrix
4303: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4304: MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4306: Output Parameter:
4307: . M - pointer to place new matrix
4309: Level: intermediate
4311: Concepts: matrices^duplicating
4313: Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4315: .seealso: MatCopy(), MatConvert()
4316: @*/
4317: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4318: {
4320: Mat B;
4321: PetscInt i;
4322: DM dm;
4328: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4329: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4330: MatCheckPreallocated(mat,1);
4332: *M = 0;
4333: if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4334: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4335: (*mat->ops->duplicate)(mat,op,M);
4336: B = *M;
4338: B->stencil.dim = mat->stencil.dim;
4339: B->stencil.noc = mat->stencil.noc;
4340: for (i=0; i<=mat->stencil.dim; i++) {
4341: B->stencil.dims[i] = mat->stencil.dims[i];
4342: B->stencil.starts[i] = mat->stencil.starts[i];
4343: }
4345: B->nooffproczerorows = mat->nooffproczerorows;
4346: B->nooffprocentries = mat->nooffprocentries;
4348: PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4349: if (dm) {
4350: PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4351: }
4352: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4353: PetscObjectStateIncrease((PetscObject)B);
4354: return(0);
4355: }
4359: /*@
4360: MatGetDiagonal - Gets the diagonal of a matrix.
4362: Logically Collective on Mat and Vec
4364: Input Parameters:
4365: + mat - the matrix
4366: - v - the vector for storing the diagonal
4368: Output Parameter:
4369: . v - the diagonal of the matrix
4371: Level: intermediate
4373: Note:
4374: Currently only correct in parallel for square matrices.
4376: Concepts: matrices^accessing diagonals
4378: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4379: @*/
4380: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4381: {
4388: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4389: if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4390: MatCheckPreallocated(mat,1);
4392: (*mat->ops->getdiagonal)(mat,v);
4393: PetscObjectStateIncrease((PetscObject)v);
4394: return(0);
4395: }
4399: /*@C
4400: MatGetRowMin - Gets the minimum value (of the real part) of each
4401: row of the matrix
4403: Logically Collective on Mat and Vec
4405: Input Parameters:
4406: . mat - the matrix
4408: Output Parameter:
4409: + v - the vector for storing the maximums
4410: - idx - the indices of the column found for each row (optional)
4412: Level: intermediate
4414: Notes: The result of this call are the same as if one converted the matrix to dense format
4415: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4417: This code is only implemented for a couple of matrix formats.
4419: Concepts: matrices^getting row maximums
4421: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4422: MatGetRowMax()
4423: @*/
4424: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4425: {
4432: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4433: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4434: MatCheckPreallocated(mat,1);
4436: (*mat->ops->getrowmin)(mat,v,idx);
4437: PetscObjectStateIncrease((PetscObject)v);
4438: return(0);
4439: }
4443: /*@C
4444: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4445: row of the matrix
4447: Logically Collective on Mat and Vec
4449: Input Parameters:
4450: . mat - the matrix
4452: Output Parameter:
4453: + v - the vector for storing the minimums
4454: - idx - the indices of the column found for each row (or NULL if not needed)
4456: Level: intermediate
4458: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4459: row is 0 (the first column).
4461: This code is only implemented for a couple of matrix formats.
4463: Concepts: matrices^getting row maximums
4465: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4466: @*/
4467: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4468: {
4475: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4476: if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4477: MatCheckPreallocated(mat,1);
4478: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4480: (*mat->ops->getrowminabs)(mat,v,idx);
4481: PetscObjectStateIncrease((PetscObject)v);
4482: return(0);
4483: }
4487: /*@C
4488: MatGetRowMax - Gets the maximum value (of the real part) of each
4489: row of the matrix
4491: Logically Collective on Mat and Vec
4493: Input Parameters:
4494: . mat - the matrix
4496: Output Parameter:
4497: + v - the vector for storing the maximums
4498: - idx - the indices of the column found for each row (optional)
4500: Level: intermediate
4502: Notes: The result of this call are the same as if one converted the matrix to dense format
4503: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4505: This code is only implemented for a couple of matrix formats.
4507: Concepts: matrices^getting row maximums
4509: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4510: @*/
4511: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4512: {
4519: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4520: if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4521: MatCheckPreallocated(mat,1);
4523: (*mat->ops->getrowmax)(mat,v,idx);
4524: PetscObjectStateIncrease((PetscObject)v);
4525: return(0);
4526: }
4530: /*@C
4531: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4532: row of the matrix
4534: Logically Collective on Mat and Vec
4536: Input Parameters:
4537: . mat - the matrix
4539: Output Parameter:
4540: + v - the vector for storing the maximums
4541: - idx - the indices of the column found for each row (or NULL if not needed)
4543: Level: intermediate
4545: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4546: row is 0 (the first column).
4548: This code is only implemented for a couple of matrix formats.
4550: Concepts: matrices^getting row maximums
4552: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4553: @*/
4554: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4555: {
4562: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4563: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4564: MatCheckPreallocated(mat,1);
4565: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4567: (*mat->ops->getrowmaxabs)(mat,v,idx);
4568: PetscObjectStateIncrease((PetscObject)v);
4569: return(0);
4570: }
4574: /*@
4575: MatGetRowSum - Gets the sum of each row of the matrix
4577: Logically Collective on Mat and Vec
4579: Input Parameters:
4580: . mat - the matrix
4582: Output Parameter:
4583: . v - the vector for storing the sum of rows
4585: Level: intermediate
4587: Notes: This code is slow since it is not currently specialized for different formats
4589: Concepts: matrices^getting row sums
4591: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4592: @*/
4593: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4594: {
4595: PetscInt start = 0, end = 0, row;
4596: PetscScalar *array;
4603: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4604: MatCheckPreallocated(mat,1);
4605: MatGetOwnershipRange(mat, &start, &end);
4606: VecGetArray(v, &array);
4607: for (row = start; row < end; ++row) {
4608: PetscInt ncols, col;
4609: const PetscInt *cols;
4610: const PetscScalar *vals;
4612: array[row - start] = 0.0;
4614: MatGetRow(mat, row, &ncols, &cols, &vals);
4615: for (col = 0; col < ncols; col++) {
4616: array[row - start] += vals[col];
4617: }
4618: MatRestoreRow(mat, row, &ncols, &cols, &vals);
4619: }
4620: VecRestoreArray(v, &array);
4621: PetscObjectStateIncrease((PetscObject) v);
4622: return(0);
4623: }
4627: /*@
4628: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4630: Collective on Mat
4632: Input Parameter:
4633: + mat - the matrix to transpose
4634: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4636: Output Parameters:
4637: . B - the transpose
4639: Notes:
4640: If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4642: Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4644: Level: intermediate
4646: Concepts: matrices^transposing
4648: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4649: @*/
4650: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4651: {
4657: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4658: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4659: if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4660: MatCheckPreallocated(mat,1);
4662: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4663: (*mat->ops->transpose)(mat,reuse,B);
4664: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4665: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4666: return(0);
4667: }
4671: /*@
4672: MatIsTranspose - Test whether a matrix is another one's transpose,
4673: or its own, in which case it tests symmetry.
4675: Collective on Mat
4677: Input Parameter:
4678: + A - the matrix to test
4679: - B - the matrix to test against, this can equal the first parameter
4681: Output Parameters:
4682: . flg - the result
4684: Notes:
4685: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4686: has a running time of the order of the number of nonzeros; the parallel
4687: test involves parallel copies of the block-offdiagonal parts of the matrix.
4689: Level: intermediate
4691: Concepts: matrices^transposing, matrix^symmetry
4693: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4694: @*/
4695: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4696: {
4697: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4703: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4704: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4705: *flg = PETSC_FALSE;
4706: if (f && g) {
4707: if (f == g) {
4708: (*f)(A,B,tol,flg);
4709: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4710: } else {
4711: MatType mattype;
4712: if (!f) {
4713: MatGetType(A,&mattype);
4714: } else {
4715: MatGetType(B,&mattype);
4716: }
4717: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4718: }
4719: return(0);
4720: }
4724: /*@
4725: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4727: Collective on Mat
4729: Input Parameter:
4730: + mat - the matrix to transpose and complex conjugate
4731: - reuse - store the transpose matrix in the provided B
4733: Output Parameters:
4734: . B - the Hermitian
4736: Notes:
4737: If you pass in &mat for B the Hermitian will be done in place
4739: Level: intermediate
4741: Concepts: matrices^transposing, complex conjugatex
4743: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4744: @*/
4745: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4746: {
4750: MatTranspose(mat,reuse,B);
4751: #if defined(PETSC_USE_COMPLEX)
4752: MatConjugate(*B);
4753: #endif
4754: return(0);
4755: }
4759: /*@
4760: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4762: Collective on Mat
4764: Input Parameter:
4765: + A - the matrix to test
4766: - B - the matrix to test against, this can equal the first parameter
4768: Output Parameters:
4769: . flg - the result
4771: Notes:
4772: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4773: has a running time of the order of the number of nonzeros; the parallel
4774: test involves parallel copies of the block-offdiagonal parts of the matrix.
4776: Level: intermediate
4778: Concepts: matrices^transposing, matrix^symmetry
4780: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4781: @*/
4782: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4783: {
4784: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4790: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4791: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
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 Hermitian test");
4796: }
4797: return(0);
4798: }
4802: /*@
4803: MatPermute - Creates a new matrix with rows and columns permuted from the
4804: original.
4806: Collective on Mat
4808: Input Parameters:
4809: + mat - the matrix to permute
4810: . row - row permutation, each processor supplies only the permutation for its rows
4811: - col - column permutation, each processor supplies only the permutation for its columns
4813: Output Parameters:
4814: . B - the permuted matrix
4816: Level: advanced
4818: Note:
4819: The index sets map from row/col of permuted matrix to row/col of original matrix.
4820: The index sets should be on the same communicator as Mat and have the same local sizes.
4822: Concepts: matrices^permuting
4824: .seealso: MatGetOrdering(), ISAllGather()
4826: @*/
4827: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4828: {
4837: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4838: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4839: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4840: MatCheckPreallocated(mat,1);
4842: (*mat->ops->permute)(mat,row,col,B);
4843: PetscObjectStateIncrease((PetscObject)*B);
4844: return(0);
4845: }
4849: /*@
4850: MatEqual - Compares two matrices.
4852: Collective on Mat
4854: Input Parameters:
4855: + A - the first matrix
4856: - B - the second matrix
4858: Output Parameter:
4859: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4861: Level: intermediate
4863: Concepts: matrices^equality between
4864: @*/
4865: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4866: {
4876: MatCheckPreallocated(B,2);
4877: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4878: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4879: 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);
4880: if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4881: if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4882: 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);
4883: MatCheckPreallocated(A,1);
4885: (*A->ops->equal)(A,B,flg);
4886: return(0);
4887: }
4891: /*@
4892: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4893: matrices that are stored as vectors. Either of the two scaling
4894: matrices can be NULL.
4896: Collective on Mat
4898: Input Parameters:
4899: + mat - the matrix to be scaled
4900: . l - the left scaling vector (or NULL)
4901: - r - the right scaling vector (or NULL)
4903: Notes:
4904: MatDiagonalScale() computes A = LAR, where
4905: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4906: The L scales the rows of the matrix, the R scales the columns of the matrix.
4908: Level: intermediate
4910: Concepts: matrices^diagonal scaling
4911: Concepts: diagonal scaling of matrices
4913: .seealso: MatScale()
4914: @*/
4915: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4916: {
4922: if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4925: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4926: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4927: MatCheckPreallocated(mat,1);
4929: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4930: (*mat->ops->diagonalscale)(mat,l,r);
4931: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4932: PetscObjectStateIncrease((PetscObject)mat);
4933: #if defined(PETSC_HAVE_CUSP)
4934: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4935: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4936: }
4937: #elif defined(PETSC_HAVE_VIENNACL)
4938: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4939: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4940: }
4941: #elif defined(PETSC_HAVE_VECCUDA)
4942: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4943: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4944: }
4945: #endif
4946: return(0);
4947: }
4951: /*@
4952: MatScale - Scales all elements of a matrix by a given number.
4954: Logically Collective on Mat
4956: Input Parameters:
4957: + mat - the matrix to be scaled
4958: - a - the scaling value
4960: Output Parameter:
4961: . mat - the scaled matrix
4963: Level: intermediate
4965: Concepts: matrices^scaling all entries
4967: .seealso: MatDiagonalScale()
4968: @*/
4969: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4970: {
4976: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4977: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4978: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4980: MatCheckPreallocated(mat,1);
4982: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4983: if (a != (PetscScalar)1.0) {
4984: (*mat->ops->scale)(mat,a);
4985: PetscObjectStateIncrease((PetscObject)mat);
4986: }
4987: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4988: #if defined(PETSC_HAVE_CUSP)
4989: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4990: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4991: }
4992: #elif defined(PETSC_HAVE_VIENNACL)
4993: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4994: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4995: }
4996: #elif defined(PETSC_HAVE_VECCUDA)
4997: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4998: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4999: }
5000: #endif
5001: return(0);
5002: }
5006: /*@
5007: MatNorm - Calculates various norms of a matrix.
5009: Collective on Mat
5011: Input Parameters:
5012: + mat - the matrix
5013: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5015: Output Parameters:
5016: . nrm - the resulting norm
5018: Level: intermediate
5020: Concepts: matrices^norm
5021: Concepts: norm^of matrix
5022: @*/
5023: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5024: {
5032: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5033: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5034: if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5035: MatCheckPreallocated(mat,1);
5037: (*mat->ops->norm)(mat,type,nrm);
5038: return(0);
5039: }
5041: /*
5042: This variable is used to prevent counting of MatAssemblyBegin() that
5043: are called from within a MatAssemblyEnd().
5044: */
5045: static PetscInt MatAssemblyEnd_InUse = 0;
5048: /*@
5049: MatAssemblyBegin - Begins assembling the matrix. This routine should
5050: be called after completing all calls to MatSetValues().
5052: Collective on Mat
5054: Input Parameters:
5055: + mat - the matrix
5056: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5058: Notes:
5059: MatSetValues() generally caches the values. The matrix is ready to
5060: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5061: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5062: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5063: using the matrix.
5065: ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5066: 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
5067: a global collective operation requring all processes that share the matrix.
5069: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5070: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5071: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5073: Level: beginner
5075: Concepts: matrices^assembling
5077: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5078: @*/
5079: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5080: {
5086: MatCheckPreallocated(mat,1);
5087: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5088: if (mat->assembled) {
5089: mat->was_assembled = PETSC_TRUE;
5090: mat->assembled = PETSC_FALSE;
5091: }
5092: if (!MatAssemblyEnd_InUse) {
5093: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5094: if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5095: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5096: } else if (mat->ops->assemblybegin) {
5097: (*mat->ops->assemblybegin)(mat,type);
5098: }
5099: return(0);
5100: }
5104: /*@
5105: MatAssembled - Indicates if a matrix has been assembled and is ready for
5106: use; for example, in matrix-vector product.
5108: Not Collective
5110: Input Parameter:
5111: . mat - the matrix
5113: Output Parameter:
5114: . assembled - PETSC_TRUE or PETSC_FALSE
5116: Level: advanced
5118: Concepts: matrices^assembled?
5120: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5121: @*/
5122: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
5123: {
5128: *assembled = mat->assembled;
5129: return(0);
5130: }
5134: /*@
5135: MatAssemblyEnd - Completes assembling the matrix. This routine should
5136: be called after MatAssemblyBegin().
5138: Collective on Mat
5140: Input Parameters:
5141: + mat - the matrix
5142: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5144: Options Database Keys:
5145: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5146: . -mat_view ::ascii_info_detail - Prints more detailed info
5147: . -mat_view - Prints matrix in ASCII format
5148: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
5149: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5150: . -display <name> - Sets display name (default is host)
5151: . -draw_pause <sec> - Sets number of seconds to pause after display
5152: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 11 Using MATLAB with PETSc )
5153: . -viewer_socket_machine <machine> - Machine to use for socket
5154: . -viewer_socket_port <port> - Port number to use for socket
5155: - -mat_view binary:filename[:append] - Save matrix to file in binary format
5157: Notes:
5158: MatSetValues() generally caches the values. The matrix is ready to
5159: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5160: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5161: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5162: using the matrix.
5164: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5165: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5166: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5168: Level: beginner
5170: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5171: @*/
5172: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5173: {
5174: PetscErrorCode ierr;
5175: static PetscInt inassm = 0;
5176: PetscBool flg = PETSC_FALSE;
5182: inassm++;
5183: MatAssemblyEnd_InUse++;
5184: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5185: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5186: if (mat->ops->assemblyend) {
5187: (*mat->ops->assemblyend)(mat,type);
5188: }
5189: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5190: } else if (mat->ops->assemblyend) {
5191: (*mat->ops->assemblyend)(mat,type);
5192: }
5194: /* Flush assembly is not a true assembly */
5195: if (type != MAT_FLUSH_ASSEMBLY) {
5196: mat->assembled = PETSC_TRUE; mat->num_ass++;
5197: }
5198: mat->insertmode = NOT_SET_VALUES;
5199: MatAssemblyEnd_InUse--;
5200: PetscObjectStateIncrease((PetscObject)mat);
5201: if (!mat->symmetric_eternal) {
5202: mat->symmetric_set = PETSC_FALSE;
5203: mat->hermitian_set = PETSC_FALSE;
5204: mat->structurally_symmetric_set = PETSC_FALSE;
5205: }
5206: #if defined(PETSC_HAVE_CUSP)
5207: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5208: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5209: }
5210: #elif defined(PETSC_HAVE_VIENNACL)
5211: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5212: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5213: }
5214: #elif defined(PETSC_HAVE_VECCUDA)
5215: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5216: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5217: }
5218: #endif
5219: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5220: MatViewFromOptions(mat,NULL,"-mat_view");
5222: if (mat->checksymmetryonassembly) {
5223: MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5224: if (flg) {
5225: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5226: } else {
5227: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5228: }
5229: }
5230: if (mat->nullsp && mat->checknullspaceonassembly) {
5231: MatNullSpaceTest(mat->nullsp,mat,NULL);
5232: }
5233: }
5234: inassm--;
5235: return(0);
5236: }
5240: /*@
5241: MatSetOption - Sets a parameter option for a matrix. Some options
5242: may be specific to certain storage formats. Some options
5243: determine how values will be inserted (or added). Sorted,
5244: row-oriented input will generally assemble the fastest. The default
5245: is row-oriented.
5247: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5249: Input Parameters:
5250: + mat - the matrix
5251: . option - the option, one of those listed below (and possibly others),
5252: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5254: Options Describing Matrix Structure:
5255: + MAT_SPD - symmetric positive definite
5256: . MAT_SYMMETRIC - symmetric in terms of both structure and value
5257: . MAT_HERMITIAN - transpose is the complex conjugation
5258: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5259: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5260: you set to be kept with all future use of the matrix
5261: including after MatAssemblyBegin/End() which could
5262: potentially change the symmetry structure, i.e. you
5263: KNOW the matrix will ALWAYS have the property you set.
5266: Options For Use with MatSetValues():
5267: Insert a logically dense subblock, which can be
5268: . MAT_ROW_ORIENTED - row-oriented (default)
5270: Note these options reflect the data you pass in with MatSetValues(); it has
5271: nothing to do with how the data is stored internally in the matrix
5272: data structure.
5274: When (re)assembling a matrix, we can restrict the input for
5275: efficiency/debugging purposes. These options include:
5276: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5277: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5278: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5279: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5280: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5281: . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5282: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5283: performance for very large process counts.
5284: - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5285: of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5286: functions, instead sending only neighbor messages.
5288: Notes:
5289: Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5291: Some options are relevant only for particular matrix types and
5292: are thus ignored by others. Other options are not supported by
5293: certain matrix types and will generate an error message if set.
5295: If using a Fortran 77 module to compute a matrix, one may need to
5296: use the column-oriented option (or convert to the row-oriented
5297: format).
5299: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5300: that would generate a new entry in the nonzero structure is instead
5301: ignored. Thus, if memory has not alredy been allocated for this particular
5302: data, then the insertion is ignored. For dense matrices, in which
5303: the entire array is allocated, no entries are ever ignored.
5304: Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5306: MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5307: that would generate a new entry in the nonzero structure instead produces
5308: 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
5310: MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5311: that would generate a new entry that has not been preallocated will
5312: instead produce an error. (Currently supported for AIJ and BAIJ formats
5313: only.) This is a useful flag when debugging matrix memory preallocation.
5314: If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5316: MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5317: other processors should be dropped, rather than stashed.
5318: This is useful if you know that the "owning" processor is also
5319: always generating the correct matrix entries, so that PETSc need
5320: not transfer duplicate entries generated on another processor.
5322: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5323: searches during matrix assembly. When this flag is set, the hash table
5324: is created during the first Matrix Assembly. This hash table is
5325: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5326: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5327: should be used with MAT_USE_HASH_TABLE flag. This option is currently
5328: supported by MATMPIBAIJ format only.
5330: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5331: are kept in the nonzero structure
5333: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5334: a zero location in the matrix
5336: MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5338: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5339: zero row routines and thus improves performance for very large process counts.
5341: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5342: part of the matrix (since they should match the upper triangular part).
5344: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5346: Level: intermediate
5348: Concepts: matrices^setting options
5350: .seealso: MatOption, Mat
5352: @*/
5353: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5354: {
5360: if (op > 0) {
5363: }
5365: 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);
5366: 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()");
5368: switch (op) {
5369: case MAT_NO_OFF_PROC_ENTRIES:
5370: mat->nooffprocentries = flg;
5371: return(0);
5372: break;
5373: case MAT_SUBSET_OFF_PROC_ENTRIES:
5374: mat->subsetoffprocentries = flg;
5375: return(0);
5376: case MAT_NO_OFF_PROC_ZERO_ROWS:
5377: mat->nooffproczerorows = flg;
5378: return(0);
5379: break;
5380: case MAT_SPD:
5381: mat->spd_set = PETSC_TRUE;
5382: mat->spd = flg;
5383: if (flg) {
5384: mat->symmetric = PETSC_TRUE;
5385: mat->structurally_symmetric = PETSC_TRUE;
5386: mat->symmetric_set = PETSC_TRUE;
5387: mat->structurally_symmetric_set = PETSC_TRUE;
5388: }
5389: break;
5390: case MAT_SYMMETRIC:
5391: mat->symmetric = flg;
5392: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5393: mat->symmetric_set = PETSC_TRUE;
5394: mat->structurally_symmetric_set = flg;
5395: break;
5396: case MAT_HERMITIAN:
5397: mat->hermitian = flg;
5398: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5399: mat->hermitian_set = PETSC_TRUE;
5400: mat->structurally_symmetric_set = flg;
5401: break;
5402: case MAT_STRUCTURALLY_SYMMETRIC:
5403: mat->structurally_symmetric = flg;
5404: mat->structurally_symmetric_set = PETSC_TRUE;
5405: break;
5406: case MAT_SYMMETRY_ETERNAL:
5407: mat->symmetric_eternal = flg;
5408: break;
5409: default:
5410: break;
5411: }
5412: if (mat->ops->setoption) {
5413: (*mat->ops->setoption)(mat,op,flg);
5414: }
5415: return(0);
5416: }
5420: /*@
5421: MatGetOption - Gets a parameter option that has been set for a matrix.
5423: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5425: Input Parameters:
5426: + mat - the matrix
5427: - option - the option, this only responds to certain options, check the code for which ones
5429: Output Parameter:
5430: . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5432: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5434: Level: intermediate
5436: Concepts: matrices^setting options
5438: .seealso: MatOption, MatSetOption()
5440: @*/
5441: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5442: {
5447: 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);
5448: 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()");
5450: switch (op) {
5451: case MAT_NO_OFF_PROC_ENTRIES:
5452: *flg = mat->nooffprocentries;
5453: break;
5454: case MAT_NO_OFF_PROC_ZERO_ROWS:
5455: *flg = mat->nooffproczerorows;
5456: break;
5457: case MAT_SYMMETRIC:
5458: *flg = mat->symmetric;
5459: break;
5460: case MAT_HERMITIAN:
5461: *flg = mat->hermitian;
5462: break;
5463: case MAT_STRUCTURALLY_SYMMETRIC:
5464: *flg = mat->structurally_symmetric;
5465: break;
5466: case MAT_SYMMETRY_ETERNAL:
5467: *flg = mat->symmetric_eternal;
5468: break;
5469: default:
5470: break;
5471: }
5472: return(0);
5473: }
5477: /*@
5478: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5479: this routine retains the old nonzero structure.
5481: Logically Collective on Mat
5483: Input Parameters:
5484: . mat - the matrix
5486: Level: intermediate
5488: 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.
5489: See the Performance chapter of the users manual for information on preallocating matrices.
5491: Concepts: matrices^zeroing
5493: .seealso: MatZeroRows()
5494: @*/
5495: PetscErrorCode MatZeroEntries(Mat mat)
5496: {
5502: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5503: 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");
5504: if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5505: MatCheckPreallocated(mat,1);
5507: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5508: (*mat->ops->zeroentries)(mat);
5509: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5510: PetscObjectStateIncrease((PetscObject)mat);
5511: #if defined(PETSC_HAVE_CUSP)
5512: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5513: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5514: }
5515: #elif defined(PETSC_HAVE_VIENNACL)
5516: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5517: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5518: }
5519: #elif defined(PETSC_HAVE_VECCUDA)
5520: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5521: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5522: }
5523: #endif
5524: return(0);
5525: }
5529: /*@C
5530: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5531: of a set of rows and columns of a matrix.
5533: Collective on Mat
5535: Input Parameters:
5536: + mat - the matrix
5537: . numRows - the number of rows to remove
5538: . rows - the global row indices
5539: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5540: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5541: - b - optional vector of right hand side, that will be adjusted by provided solution
5543: Notes:
5544: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5546: The user can set a value in the diagonal entry (or for the AIJ and
5547: row formats can optionally remove the main diagonal entry from the
5548: nonzero structure as well, by passing 0.0 as the final argument).
5550: For the parallel case, all processes that share the matrix (i.e.,
5551: those in the communicator used for matrix creation) MUST call this
5552: routine, regardless of whether any rows being zeroed are owned by
5553: them.
5555: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5556: list only rows local to itself).
5558: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5560: Level: intermediate
5562: Concepts: matrices^zeroing rows
5564: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5565: @*/
5566: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5567: {
5574: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5575: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5576: if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5577: MatCheckPreallocated(mat,1);
5579: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5580: MatViewFromOptions(mat,NULL,"-mat_view");
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: }
5600: /*@C
5601: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5602: of a set of rows and columns of a matrix.
5604: Collective on Mat
5606: Input Parameters:
5607: + mat - the matrix
5608: . is - the rows to zero
5609: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5610: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5611: - b - optional vector of right hand side, that will be adjusted by provided solution
5613: Notes:
5614: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5616: The user can set a value in the diagonal entry (or for the AIJ and
5617: row formats can optionally remove the main diagonal entry from the
5618: nonzero structure as well, by passing 0.0 as the final argument).
5620: For the parallel case, all processes that share the matrix (i.e.,
5621: those in the communicator used for matrix creation) MUST call this
5622: routine, regardless of whether any rows being zeroed are owned by
5623: them.
5625: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5626: list only rows local to itself).
5628: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5630: Level: intermediate
5632: Concepts: matrices^zeroing rows
5634: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5635: @*/
5636: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5637: {
5639: PetscInt numRows;
5640: const PetscInt *rows;
5647: ISGetLocalSize(is,&numRows);
5648: ISGetIndices(is,&rows);
5649: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5650: ISRestoreIndices(is,&rows);
5651: return(0);
5652: }
5656: /*@C
5657: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5658: of a set of rows of a matrix.
5660: Collective on Mat
5662: Input Parameters:
5663: + mat - the matrix
5664: . numRows - the number of rows to remove
5665: . rows - the global row indices
5666: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5667: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5668: - b - optional vector of right hand side, that will be adjusted by provided solution
5670: Notes:
5671: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5672: but does not release memory. For the dense and block diagonal
5673: formats this does not alter the nonzero structure.
5675: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5676: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5677: merely zeroed.
5679: The user can set a value in the diagonal entry (or for the AIJ and
5680: row formats can optionally remove the main diagonal entry from the
5681: nonzero structure as well, by passing 0.0 as the final argument).
5683: For the parallel case, all processes that share the matrix (i.e.,
5684: those in the communicator used for matrix creation) MUST call this
5685: routine, regardless of whether any rows being zeroed are owned by
5686: them.
5688: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5689: list only rows local to itself).
5691: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5692: owns that are to be zeroed. This saves a global synchronization in the implementation.
5694: Level: intermediate
5696: Concepts: matrices^zeroing rows
5698: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5699: @*/
5700: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5701: {
5708: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5709: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5710: if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5711: MatCheckPreallocated(mat,1);
5713: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5714: MatViewFromOptions(mat,NULL,"-mat_view");
5715: PetscObjectStateIncrease((PetscObject)mat);
5716: #if defined(PETSC_HAVE_CUSP)
5717: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5718: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5719: }
5720: #elif defined(PETSC_HAVE_VIENNACL)
5721: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5722: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5723: }
5724: #elif defined(PETSC_HAVE_VECCUDA)
5725: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5726: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5727: }
5728: #endif
5729: return(0);
5730: }
5734: /*@C
5735: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5736: of a set of rows of a matrix.
5738: Collective on Mat
5740: Input Parameters:
5741: + mat - the matrix
5742: . is - index set of rows to remove
5743: . diag - value put in all diagonals of eliminated rows
5744: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5745: - b - optional vector of right hand side, that will be adjusted by provided solution
5747: Notes:
5748: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5749: but does not release memory. For the dense and block diagonal
5750: formats this does not alter the nonzero structure.
5752: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5753: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5754: merely zeroed.
5756: The user can set a value in the diagonal entry (or for the AIJ and
5757: row formats can optionally remove the main diagonal entry from the
5758: nonzero structure as well, by passing 0.0 as the final argument).
5760: For the parallel case, all processes that share the matrix (i.e.,
5761: those in the communicator used for matrix creation) MUST call this
5762: routine, regardless of whether any rows being zeroed are owned by
5763: them.
5765: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5766: list only rows local to itself).
5768: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5769: owns that are to be zeroed. This saves a global synchronization in the implementation.
5771: Level: intermediate
5773: Concepts: matrices^zeroing rows
5775: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5776: @*/
5777: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5778: {
5779: PetscInt numRows;
5780: const PetscInt *rows;
5787: ISGetLocalSize(is,&numRows);
5788: ISGetIndices(is,&rows);
5789: MatZeroRows(mat,numRows,rows,diag,x,b);
5790: ISRestoreIndices(is,&rows);
5791: return(0);
5792: }
5796: /*@C
5797: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5798: of a set of rows of a matrix. These rows must be local to the process.
5800: Collective on Mat
5802: Input Parameters:
5803: + mat - the matrix
5804: . numRows - the number of rows to remove
5805: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5806: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5807: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5808: - b - optional vector of right hand side, that will be adjusted by provided solution
5810: Notes:
5811: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5812: but does not release memory. For the dense and block diagonal
5813: formats this does not alter the nonzero structure.
5815: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5816: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5817: merely zeroed.
5819: The user can set a value in the diagonal entry (or for the AIJ and
5820: row formats can optionally remove the main diagonal entry from the
5821: nonzero structure as well, by passing 0.0 as the final argument).
5823: For the parallel case, all processes that share the matrix (i.e.,
5824: those in the communicator used for matrix creation) MUST call this
5825: routine, regardless of whether any rows being zeroed are owned by
5826: them.
5828: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5829: list only rows local to itself).
5831: The grid coordinates are across the entire grid, not just the local portion
5833: In Fortran idxm and idxn should be declared as
5834: $ MatStencil idxm(4,m)
5835: and the values inserted using
5836: $ idxm(MatStencil_i,1) = i
5837: $ idxm(MatStencil_j,1) = j
5838: $ idxm(MatStencil_k,1) = k
5839: $ idxm(MatStencil_c,1) = c
5840: etc
5842: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5843: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5844: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5845: DM_BOUNDARY_PERIODIC boundary type.
5847: 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
5848: a single value per point) you can skip filling those indices.
5850: Level: intermediate
5852: Concepts: matrices^zeroing rows
5854: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5855: @*/
5856: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5857: {
5858: PetscInt dim = mat->stencil.dim;
5859: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5860: PetscInt *dims = mat->stencil.dims+1;
5861: PetscInt *starts = mat->stencil.starts;
5862: PetscInt *dxm = (PetscInt*) rows;
5863: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5871: PetscMalloc1(numRows, &jdxm);
5872: for (i = 0; i < numRows; ++i) {
5873: /* Skip unused dimensions (they are ordered k, j, i, c) */
5874: for (j = 0; j < 3-sdim; ++j) dxm++;
5875: /* Local index in X dir */
5876: tmp = *dxm++ - starts[0];
5877: /* Loop over remaining dimensions */
5878: for (j = 0; j < dim-1; ++j) {
5879: /* If nonlocal, set index to be negative */
5880: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5881: /* Update local index */
5882: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5883: }
5884: /* Skip component slot if necessary */
5885: if (mat->stencil.noc) dxm++;
5886: /* Local row number */
5887: if (tmp >= 0) {
5888: jdxm[numNewRows++] = tmp;
5889: }
5890: }
5891: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5892: PetscFree(jdxm);
5893: return(0);
5894: }
5898: /*@C
5899: MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5900: of a set of rows and columns of a matrix.
5902: Collective on Mat
5904: Input Parameters:
5905: + mat - the matrix
5906: . numRows - the number of rows/columns to remove
5907: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5908: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5909: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5910: - b - optional vector of right hand side, that will be adjusted by provided solution
5912: Notes:
5913: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5914: but does not release memory. For the dense and block diagonal
5915: formats this does not alter the nonzero structure.
5917: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5918: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5919: merely zeroed.
5921: The user can set a value in the diagonal entry (or for the AIJ and
5922: row formats can optionally remove the main diagonal entry from the
5923: nonzero structure as well, by passing 0.0 as the final argument).
5925: For the parallel case, all processes that share the matrix (i.e.,
5926: those in the communicator used for matrix creation) MUST call this
5927: routine, regardless of whether any rows being zeroed are owned by
5928: them.
5930: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5931: list only rows local to itself, but the row/column numbers are given in local numbering).
5933: The grid coordinates are across the entire grid, not just the local portion
5935: In Fortran idxm and idxn should be declared as
5936: $ MatStencil idxm(4,m)
5937: and the values inserted using
5938: $ idxm(MatStencil_i,1) = i
5939: $ idxm(MatStencil_j,1) = j
5940: $ idxm(MatStencil_k,1) = k
5941: $ idxm(MatStencil_c,1) = c
5942: etc
5944: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5945: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5946: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5947: DM_BOUNDARY_PERIODIC boundary type.
5949: 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
5950: a single value per point) you can skip filling those indices.
5952: Level: intermediate
5954: Concepts: matrices^zeroing rows
5956: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5957: @*/
5958: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5959: {
5960: PetscInt dim = mat->stencil.dim;
5961: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5962: PetscInt *dims = mat->stencil.dims+1;
5963: PetscInt *starts = mat->stencil.starts;
5964: PetscInt *dxm = (PetscInt*) rows;
5965: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5973: PetscMalloc1(numRows, &jdxm);
5974: for (i = 0; i < numRows; ++i) {
5975: /* Skip unused dimensions (they are ordered k, j, i, c) */
5976: for (j = 0; j < 3-sdim; ++j) dxm++;
5977: /* Local index in X dir */
5978: tmp = *dxm++ - starts[0];
5979: /* Loop over remaining dimensions */
5980: for (j = 0; j < dim-1; ++j) {
5981: /* If nonlocal, set index to be negative */
5982: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5983: /* Update local index */
5984: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5985: }
5986: /* Skip component slot if necessary */
5987: if (mat->stencil.noc) dxm++;
5988: /* Local row number */
5989: if (tmp >= 0) {
5990: jdxm[numNewRows++] = tmp;
5991: }
5992: }
5993: MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5994: PetscFree(jdxm);
5995: return(0);
5996: }
6000: /*@C
6001: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6002: of a set of rows of a matrix; using local numbering of rows.
6004: Collective on Mat
6006: Input Parameters:
6007: + mat - the matrix
6008: . numRows - the number of rows to remove
6009: . rows - the global row indices
6010: . diag - value put in all diagonals of eliminated rows
6011: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6012: - b - optional vector of right hand side, that will be adjusted by provided solution
6014: Notes:
6015: Before calling MatZeroRowsLocal(), the user must first set the
6016: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6018: For the AIJ matrix formats this removes the old nonzero structure,
6019: but does not release memory. For the dense and block diagonal
6020: formats this does not alter the nonzero structure.
6022: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6023: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6024: merely zeroed.
6026: The user can set a value in the diagonal entry (or for the AIJ and
6027: row formats can optionally remove the main diagonal entry from the
6028: nonzero structure as well, by passing 0.0 as the final argument).
6030: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6031: owns that are to be zeroed. This saves a global synchronization in the implementation.
6033: Level: intermediate
6035: Concepts: matrices^zeroing
6037: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6038: @*/
6039: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6040: {
6047: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6048: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6049: MatCheckPreallocated(mat,1);
6051: if (mat->ops->zerorowslocal) {
6052: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6053: } else {
6054: IS is, newis;
6055: const PetscInt *newRows;
6057: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6058: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6059: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6060: ISGetIndices(newis,&newRows);
6061: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6062: ISRestoreIndices(newis,&newRows);
6063: ISDestroy(&newis);
6064: ISDestroy(&is);
6065: }
6066: PetscObjectStateIncrease((PetscObject)mat);
6067: #if defined(PETSC_HAVE_CUSP)
6068: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6069: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6070: }
6071: #elif defined(PETSC_HAVE_VIENNACL)
6072: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6073: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6074: }
6075: #elif defined(PETSC_HAVE_VECCUDA)
6076: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6077: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6078: }
6079: #endif
6080: return(0);
6081: }
6085: /*@C
6086: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6087: of a set of rows of a matrix; using local numbering of rows.
6089: Collective on Mat
6091: Input Parameters:
6092: + mat - the matrix
6093: . is - index set of rows to remove
6094: . diag - value put in all diagonals of eliminated rows
6095: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6096: - b - optional vector of right hand side, that will be adjusted by provided solution
6098: Notes:
6099: Before calling MatZeroRowsLocalIS(), the user must first set the
6100: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6102: For the AIJ matrix formats this removes the old nonzero structure,
6103: but does not release memory. For the dense and block diagonal
6104: formats this does not alter the nonzero structure.
6106: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6107: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6108: merely zeroed.
6110: The user can set a value in the diagonal entry (or for the AIJ and
6111: row formats can optionally remove the main diagonal entry from the
6112: nonzero structure as well, by passing 0.0 as the final argument).
6114: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6115: owns that are to be zeroed. This saves a global synchronization in the implementation.
6117: Level: intermediate
6119: Concepts: matrices^zeroing
6121: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6122: @*/
6123: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6124: {
6126: PetscInt numRows;
6127: const PetscInt *rows;
6133: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6134: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6135: MatCheckPreallocated(mat,1);
6137: ISGetLocalSize(is,&numRows);
6138: ISGetIndices(is,&rows);
6139: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6140: ISRestoreIndices(is,&rows);
6141: return(0);
6142: }
6146: /*@C
6147: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6148: of a set of rows and columns of a matrix; using local numbering of rows.
6150: Collective on Mat
6152: Input Parameters:
6153: + mat - the matrix
6154: . numRows - the number of rows to remove
6155: . rows - the global row indices
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 MatZeroRowsColumnsLocal(), the user must first set the
6162: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6164: The user can set a value in the diagonal entry (or for the AIJ and
6165: row formats can optionally remove the main diagonal entry from the
6166: nonzero structure as well, by passing 0.0 as the final argument).
6168: Level: intermediate
6170: Concepts: matrices^zeroing
6172: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6173: @*/
6174: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6175: {
6177: IS is, newis;
6178: const PetscInt *newRows;
6184: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6185: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6186: MatCheckPreallocated(mat,1);
6188: if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6189: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6190: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6191: ISGetIndices(newis,&newRows);
6192: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6193: ISRestoreIndices(newis,&newRows);
6194: ISDestroy(&newis);
6195: ISDestroy(&is);
6196: PetscObjectStateIncrease((PetscObject)mat);
6197: #if defined(PETSC_HAVE_CUSP)
6198: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6199: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6200: }
6201: #elif defined(PETSC_HAVE_VIENNACL)
6202: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6203: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6204: }
6205: #elif defined(PETSC_HAVE_VECCUDA)
6206: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6207: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6208: }
6209: #endif
6210: return(0);
6211: }
6215: /*@C
6216: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6217: of a set of rows and columns of a matrix; using local numbering of rows.
6219: Collective on Mat
6221: Input Parameters:
6222: + mat - the matrix
6223: . is - index set of rows to remove
6224: . diag - value put in all diagonals of eliminated rows
6225: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6226: - b - optional vector of right hand side, that will be adjusted by provided solution
6228: Notes:
6229: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6230: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6232: The user can set a value in the diagonal entry (or for the AIJ and
6233: row formats can optionally remove the main diagonal entry from the
6234: nonzero structure as well, by passing 0.0 as the final argument).
6236: Level: intermediate
6238: Concepts: matrices^zeroing
6240: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6241: @*/
6242: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6243: {
6245: PetscInt numRows;
6246: const PetscInt *rows;
6252: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6253: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6254: MatCheckPreallocated(mat,1);
6256: ISGetLocalSize(is,&numRows);
6257: ISGetIndices(is,&rows);
6258: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6259: ISRestoreIndices(is,&rows);
6260: return(0);
6261: }
6265: /*@
6266: MatGetSize - Returns the numbers of rows and columns in a matrix.
6268: Not Collective
6270: Input Parameter:
6271: . mat - the matrix
6273: Output Parameters:
6274: + m - the number of global rows
6275: - n - the number of global columns
6277: Note: both output parameters can be NULL on input.
6279: Level: beginner
6281: Concepts: matrices^size
6283: .seealso: MatGetLocalSize()
6284: @*/
6285: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6286: {
6289: if (m) *m = mat->rmap->N;
6290: if (n) *n = mat->cmap->N;
6291: return(0);
6292: }
6296: /*@
6297: MatGetLocalSize - Returns the number of rows and columns in a matrix
6298: stored locally. This information may be implementation dependent, so
6299: use with care.
6301: Not Collective
6303: Input Parameters:
6304: . mat - the matrix
6306: Output Parameters:
6307: + m - the number of local rows
6308: - n - the number of local columns
6310: Note: both output parameters can be NULL on input.
6312: Level: beginner
6314: Concepts: matrices^local size
6316: .seealso: MatGetSize()
6317: @*/
6318: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6319: {
6324: if (m) *m = mat->rmap->n;
6325: if (n) *n = mat->cmap->n;
6326: return(0);
6327: }
6331: /*@
6332: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6333: this processor. (The columns of the "diagonal block")
6335: Not Collective, unless matrix has not been allocated, then collective on Mat
6337: Input Parameters:
6338: . mat - the matrix
6340: Output Parameters:
6341: + m - the global index of the first local column
6342: - n - one more than the global index of the last local column
6344: Notes: both output parameters can be NULL on input.
6346: Level: developer
6348: Concepts: matrices^column ownership
6350: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6352: @*/
6353: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6354: {
6360: MatCheckPreallocated(mat,1);
6361: if (m) *m = mat->cmap->rstart;
6362: if (n) *n = mat->cmap->rend;
6363: return(0);
6364: }
6368: /*@
6369: MatGetOwnershipRange - Returns the range of matrix rows owned by
6370: this processor, assuming that the matrix is laid out with the first
6371: n1 rows on the first processor, the next n2 rows on the second, etc.
6372: For certain parallel layouts this range may not be well defined.
6374: Not Collective
6376: Input Parameters:
6377: . mat - the matrix
6379: Output Parameters:
6380: + m - the global index of the first local row
6381: - n - one more than the global index of the last local row
6383: Note: Both output parameters can be NULL on input.
6384: $ This function requires that the matrix be preallocated. If you have not preallocated, consider using
6385: $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6386: $ and then MPI_Scan() to calculate prefix sums of the local sizes.
6388: Level: beginner
6390: Concepts: matrices^row ownership
6392: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6394: @*/
6395: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6396: {
6402: MatCheckPreallocated(mat,1);
6403: if (m) *m = mat->rmap->rstart;
6404: if (n) *n = mat->rmap->rend;
6405: return(0);
6406: }
6410: /*@C
6411: MatGetOwnershipRanges - Returns the range of matrix rows owned by
6412: each process
6414: Not Collective, unless matrix has not been allocated, then collective on Mat
6416: Input Parameters:
6417: . mat - the matrix
6419: Output Parameters:
6420: . ranges - start of each processors portion plus one more than the total length at the end
6422: Level: beginner
6424: Concepts: matrices^row ownership
6426: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6428: @*/
6429: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6430: {
6436: MatCheckPreallocated(mat,1);
6437: PetscLayoutGetRanges(mat->rmap,ranges);
6438: return(0);
6439: }
6443: /*@C
6444: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6445: this processor. (The columns of the "diagonal blocks" for each process)
6447: Not Collective, unless matrix has not been allocated, then collective on Mat
6449: Input Parameters:
6450: . mat - the matrix
6452: Output Parameters:
6453: . ranges - start of each processors portion plus one more then the total length at the end
6455: Level: beginner
6457: Concepts: matrices^column ownership
6459: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6461: @*/
6462: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6463: {
6469: MatCheckPreallocated(mat,1);
6470: PetscLayoutGetRanges(mat->cmap,ranges);
6471: return(0);
6472: }
6476: /*@C
6477: MatGetOwnershipIS - Get row and column ownership as index sets
6479: Not Collective
6481: Input Arguments:
6482: . A - matrix of type Elemental
6484: Output Arguments:
6485: + rows - rows in which this process owns elements
6486: . cols - columns in which this process owns elements
6488: Level: intermediate
6490: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6491: @*/
6492: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6493: {
6494: PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6497: MatCheckPreallocated(A,1);
6498: PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6499: if (f) {
6500: (*f)(A,rows,cols);
6501: } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6502: if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6503: if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6504: }
6505: return(0);
6506: }
6510: /*@C
6511: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6512: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6513: to complete the factorization.
6515: Collective on Mat
6517: Input Parameters:
6518: + mat - the matrix
6519: . row - row permutation
6520: . column - column permutation
6521: - info - structure containing
6522: $ levels - number of levels of fill.
6523: $ expected fill - as ratio of original fill.
6524: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6525: missing diagonal entries)
6527: Output Parameters:
6528: . fact - new matrix that has been symbolically factored
6530: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6532: Most users should employ the simplified KSP interface for linear solvers
6533: instead of working directly with matrix algebra routines such as this.
6534: See, e.g., KSPCreate().
6536: Level: developer
6538: Concepts: matrices^symbolic LU factorization
6539: Concepts: matrices^factorization
6540: Concepts: LU^symbolic factorization
6542: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6543: MatGetOrdering(), MatFactorInfo
6545: Developer Note: fortran interface is not autogenerated as the f90
6546: interface defintion cannot be generated correctly [due to MatFactorInfo]
6548: @*/
6549: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6550: {
6560: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6561: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6562: if (!(fact)->ops->ilufactorsymbolic) {
6563: const MatSolverPackage spackage;
6564: MatFactorGetSolverPackage(fact,&spackage);
6565: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6566: }
6567: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6568: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6569: MatCheckPreallocated(mat,2);
6571: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6572: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6573: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6574: return(0);
6575: }
6579: /*@C
6580: MatICCFactorSymbolic - Performs symbolic incomplete
6581: Cholesky factorization for a symmetric matrix. Use
6582: MatCholeskyFactorNumeric() to complete the factorization.
6584: Collective on Mat
6586: Input Parameters:
6587: + mat - the matrix
6588: . perm - row and column permutation
6589: - info - structure containing
6590: $ levels - number of levels of fill.
6591: $ expected fill - as ratio of original fill.
6593: Output Parameter:
6594: . fact - the factored matrix
6596: Notes:
6597: Most users should employ the KSP interface for linear solvers
6598: instead of working directly with matrix algebra routines such as this.
6599: See, e.g., KSPCreate().
6601: Level: developer
6603: Concepts: matrices^symbolic incomplete Cholesky factorization
6604: Concepts: matrices^factorization
6605: Concepts: Cholsky^symbolic factorization
6607: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6609: Developer Note: fortran interface is not autogenerated as the f90
6610: interface defintion cannot be generated correctly [due to MatFactorInfo]
6612: @*/
6613: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6614: {
6623: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6624: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6625: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6626: if (!(fact)->ops->iccfactorsymbolic) {
6627: const MatSolverPackage spackage;
6628: MatFactorGetSolverPackage(fact,&spackage);
6629: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6630: }
6631: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6632: MatCheckPreallocated(mat,2);
6634: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6635: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6636: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6637: return(0);
6638: }
6642: /*@C
6643: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6644: points to an array of valid matrices, they may be reused to store the new
6645: submatrices.
6647: Collective on Mat
6649: Input Parameters:
6650: + mat - the matrix
6651: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6652: . irow, icol - index sets of rows and columns to extract
6653: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6655: Output Parameter:
6656: . submat - the array of submatrices
6658: Notes:
6659: MatGetSubMatrices() can extract ONLY sequential submatrices
6660: (from both sequential and parallel matrices). Use MatGetSubMatrix()
6661: to extract a parallel submatrix.
6663: Some matrix types place restrictions on the row and column
6664: indices, such as that they be sorted or that they be equal to each other.
6666: The index sets may not have duplicate entries.
6668: When extracting submatrices from a parallel matrix, each processor can
6669: form a different submatrix by setting the rows and columns of its
6670: individual index sets according to the local submatrix desired.
6672: When finished using the submatrices, the user should destroy
6673: them with MatDestroyMatrices().
6675: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6676: original matrix has not changed from that last call to MatGetSubMatrices().
6678: This routine creates the matrices in submat; you should NOT create them before
6679: calling it. It also allocates the array of matrix pointers submat.
6681: For BAIJ matrices the index sets must respect the block structure, that is if they
6682: request one row/column in a block, they must request all rows/columns that are in
6683: that block. For example, if the block size is 2 you cannot request just row 0 and
6684: column 0.
6686: Fortran Note:
6687: The Fortran interface is slightly different from that given below; it
6688: requires one to pass in as submat a Mat (integer) array of size at least m.
6690: Level: advanced
6692: Concepts: matrices^accessing submatrices
6693: Concepts: submatrices
6695: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6696: @*/
6697: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6698: {
6700: PetscInt i;
6701: PetscBool eq;
6706: if (n) {
6711: }
6713: if (n && scall == MAT_REUSE_MATRIX) {
6716: }
6717: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6718: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6719: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6720: MatCheckPreallocated(mat,1);
6722: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6723: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6724: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6725: for (i=0; i<n; i++) {
6726: (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */
6727: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6728: ISEqual(irow[i],icol[i],&eq);
6729: if (eq) {
6730: if (mat->symmetric) {
6731: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6732: } else if (mat->hermitian) {
6733: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6734: } else if (mat->structurally_symmetric) {
6735: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6736: }
6737: }
6738: }
6739: }
6740: return(0);
6741: }
6745: PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6746: {
6748: PetscInt i;
6749: PetscBool eq;
6754: if (n) {
6759: }
6761: if (n && scall == MAT_REUSE_MATRIX) {
6764: }
6765: if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6766: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6767: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6768: MatCheckPreallocated(mat,1);
6770: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6771: (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6772: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6773: for (i=0; i<n; i++) {
6774: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6775: ISEqual(irow[i],icol[i],&eq);
6776: if (eq) {
6777: if (mat->symmetric) {
6778: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6779: } else if (mat->hermitian) {
6780: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6781: } else if (mat->structurally_symmetric) {
6782: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6783: }
6784: }
6785: }
6786: }
6787: return(0);
6788: }
6792: /*@C
6793: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6795: Collective on Mat
6797: Input Parameters:
6798: + n - the number of local matrices
6799: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6800: sequence of MatGetSubMatrices())
6802: Level: advanced
6804: Notes: Frees not only the matrices, but also the array that contains the matrices
6805: In Fortran will not free the array.
6807: .seealso: MatGetSubMatrices()
6808: @*/
6809: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6810: {
6812: PetscInt i;
6815: if (!*mat) return(0);
6816: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6818: for (i=0; i<n; i++) {
6819: MatDestroy(&(*mat)[i]);
6820: }
6821: /* memory is allocated even if n = 0 */
6822: PetscFree(*mat);
6823: *mat = NULL;
6824: return(0);
6825: }
6829: /*@C
6830: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6832: Collective on Mat
6834: Input Parameters:
6835: . mat - the matrix
6837: Output Parameter:
6838: . matstruct - the sequential matrix with the nonzero structure of mat
6840: Level: intermediate
6842: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6843: @*/
6844: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6845: {
6853: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6854: MatCheckPreallocated(mat,1);
6856: if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6857: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6858: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6859: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6860: return(0);
6861: }
6865: /*@C
6866: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6868: Collective on Mat
6870: Input Parameters:
6871: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6872: sequence of MatGetSequentialNonzeroStructure())
6874: Level: advanced
6876: Notes: Frees not only the matrices, but also the array that contains the matrices
6878: .seealso: MatGetSeqNonzeroStructure()
6879: @*/
6880: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6881: {
6886: MatDestroy(mat);
6887: return(0);
6888: }
6892: /*@
6893: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6894: replaces the index sets by larger ones that represent submatrices with
6895: additional overlap.
6897: Collective on Mat
6899: Input Parameters:
6900: + mat - the matrix
6901: . n - the number of index sets
6902: . is - the array of index sets (these index sets will changed during the call)
6903: - ov - the additional overlap requested
6905: Options Database:
6906: . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6908: Level: developer
6910: Concepts: overlap
6911: Concepts: ASM^computing overlap
6913: .seealso: MatGetSubMatrices()
6914: @*/
6915: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6916: {
6922: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6923: if (n) {
6926: }
6927: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6928: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6929: MatCheckPreallocated(mat,1);
6931: if (!ov) return(0);
6932: if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6933: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6934: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6935: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6936: return(0);
6937: }
6940: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6944: /*@
6945: MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6946: a sub communicator, replaces the index sets by larger ones that represent submatrices with
6947: additional overlap.
6949: Collective on Mat
6951: Input Parameters:
6952: + mat - the matrix
6953: . n - the number of index sets
6954: . is - the array of index sets (these index sets will changed during the call)
6955: - ov - the additional overlap requested
6957: Options Database:
6958: . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6960: Level: developer
6962: Concepts: overlap
6963: Concepts: ASM^computing overlap
6965: .seealso: MatGetSubMatrices()
6966: @*/
6967: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6968: {
6969: PetscInt i;
6975: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6976: if (n) {
6979: }
6980: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6981: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6982: MatCheckPreallocated(mat,1);
6983: if (!ov) return(0);
6984: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6985: for(i=0; i<n; i++){
6986: MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
6987: }
6988: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6989: return(0);
6990: }
6997: /*@
6998: MatGetBlockSize - Returns the matrix block size.
7000: Not Collective
7002: Input Parameter:
7003: . mat - the matrix
7005: Output Parameter:
7006: . bs - block size
7008: Notes:
7009: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7011: If the block size has not been set yet this routine returns 1.
7013: Level: intermediate
7015: Concepts: matrices^block size
7017: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7018: @*/
7019: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7020: {
7024: *bs = PetscAbs(mat->rmap->bs);
7025: return(0);
7026: }
7030: /*@
7031: MatGetBlockSizes - Returns the matrix block row and column sizes.
7033: Not Collective
7035: Input Parameter:
7036: . mat - the matrix
7038: Output Parameter:
7039: . rbs - row block size
7040: . cbs - coumn block size
7042: Notes:
7043: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7044: If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7046: If a block size has not been set yet this routine returns 1.
7048: Level: intermediate
7050: Concepts: matrices^block size
7052: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7053: @*/
7054: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7055: {
7060: if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7061: if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7062: return(0);
7063: }
7067: /*@
7068: MatSetBlockSize - Sets the matrix block size.
7070: Logically Collective on Mat
7072: Input Parameters:
7073: + mat - the matrix
7074: - bs - block size
7076: Notes:
7077: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7079: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7081: Level: intermediate
7083: Concepts: matrices^block size
7085: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7086: @*/
7087: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7088: {
7094: PetscLayoutSetBlockSize(mat->rmap,bs);
7095: PetscLayoutSetBlockSize(mat->cmap,bs);
7096: return(0);
7097: }
7101: /*@
7102: MatSetBlockSizes - Sets the matrix block row and column sizes.
7104: Logically Collective on Mat
7106: Input Parameters:
7107: + mat - the matrix
7108: - rbs - row block size
7109: - cbs - column block size
7111: Notes:
7112: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7113: If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7115: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7117: The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7119: Level: intermediate
7121: Concepts: matrices^block size
7123: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7124: @*/
7125: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7126: {
7133: PetscLayoutSetBlockSize(mat->rmap,rbs);
7134: PetscLayoutSetBlockSize(mat->cmap,cbs);
7135: return(0);
7136: }
7140: /*@
7141: MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7143: Logically Collective on Mat
7145: Input Parameters:
7146: + mat - the matrix
7147: . fromRow - matrix from which to copy row block size
7148: - fromCol - matrix from which to copy column block size (can be same as fromRow)
7150: Level: developer
7152: Concepts: matrices^block size
7154: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7155: @*/
7156: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7157: {
7164: if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7165: if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7166: return(0);
7167: }
7171: /*@
7172: MatResidual - Default routine to calculate the residual.
7174: Collective on Mat and Vec
7176: Input Parameters:
7177: + mat - the matrix
7178: . b - the right-hand-side
7179: - x - the approximate solution
7181: Output Parameter:
7182: . r - location to store the residual
7184: Level: developer
7186: .keywords: MG, default, multigrid, residual
7188: .seealso: PCMGSetResidual()
7189: @*/
7190: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7191: {
7200: MatCheckPreallocated(mat,1);
7201: PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7202: if (!mat->ops->residual) {
7203: MatMult(mat,x,r);
7204: VecAYPX(r,-1.0,b);
7205: } else {
7206: (*mat->ops->residual)(mat,b,x,r);
7207: }
7208: PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7209: return(0);
7210: }
7214: /*@C
7215: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7217: Collective on Mat
7219: Input Parameters:
7220: + mat - the matrix
7221: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
7222: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
7223: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7224: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7225: always used.
7227: Output Parameters:
7228: + n - number of rows in the (possibly compressed) matrix
7229: . ia - the row pointers [of length n+1]
7230: . ja - the column indices
7231: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7232: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7234: Level: developer
7236: Notes: You CANNOT change any of the ia[] or ja[] values.
7238: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
7240: Fortran Node
7242: In Fortran use
7243: $ PetscInt ia(1), ja(1)
7244: $ PetscOffset iia, jja
7245: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7246: $ Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7247: $
7248: $ or
7249: $
7250: $ PetscInt, pointer :: ia(:),ja(:)
7251: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7252: $ Acess the ith and jth entries via ia(i) and ja(j)
7256: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7257: @*/
7258: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7259: {
7269: MatCheckPreallocated(mat,1);
7270: if (!mat->ops->getrowij) *done = PETSC_FALSE;
7271: else {
7272: *done = PETSC_TRUE;
7273: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7274: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7275: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7276: }
7277: return(0);
7278: }
7282: /*@C
7283: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7285: Collective on Mat
7287: Input Parameters:
7288: + mat - the matrix
7289: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7290: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7291: symmetrized
7292: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7293: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7294: always used.
7295: . n - number of columns in the (possibly compressed) matrix
7296: . ia - the column pointers
7297: - ja - the row indices
7299: Output Parameters:
7300: . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7302: Note:
7303: This routine zeros out n, ia, and ja. This is to prevent accidental
7304: us of the array after it has been restored. If you pass NULL, it will
7305: not zero the pointers. Use of ia or ja after MatRestoreColumnIJ() is invalid.
7307: Level: developer
7309: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7310: @*/
7311: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7312: {
7322: MatCheckPreallocated(mat,1);
7323: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7324: else {
7325: *done = PETSC_TRUE;
7326: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7327: }
7328: return(0);
7329: }
7333: /*@C
7334: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7335: MatGetRowIJ().
7337: Collective on Mat
7339: Input Parameters:
7340: + mat - the matrix
7341: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7342: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7343: symmetrized
7344: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7345: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7346: always used.
7347: . n - size of (possibly compressed) matrix
7348: . ia - the row pointers
7349: - ja - the column indices
7351: Output Parameters:
7352: . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7354: Note:
7355: This routine zeros out n, ia, and ja. This is to prevent accidental
7356: us of the array after it has been restored. If you pass NULL, it will
7357: not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid.
7359: Level: developer
7361: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7362: @*/
7363: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7364: {
7373: MatCheckPreallocated(mat,1);
7375: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7376: else {
7377: *done = PETSC_TRUE;
7378: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7379: if (n) *n = 0;
7380: if (ia) *ia = NULL;
7381: if (ja) *ja = NULL;
7382: }
7383: return(0);
7384: }
7388: /*@C
7389: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7390: MatGetColumnIJ().
7392: Collective on Mat
7394: Input Parameters:
7395: + mat - the matrix
7396: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7397: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7398: symmetrized
7399: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7400: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7401: always used.
7403: Output Parameters:
7404: + n - size of (possibly compressed) matrix
7405: . ia - the column pointers
7406: . ja - the row indices
7407: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7409: Level: developer
7411: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7412: @*/
7413: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7414: {
7423: MatCheckPreallocated(mat,1);
7425: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7426: else {
7427: *done = PETSC_TRUE;
7428: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7429: if (n) *n = 0;
7430: if (ia) *ia = NULL;
7431: if (ja) *ja = NULL;
7432: }
7433: return(0);
7434: }
7438: /*@C
7439: MatColoringPatch -Used inside matrix coloring routines that
7440: use MatGetRowIJ() and/or MatGetColumnIJ().
7442: Collective on Mat
7444: Input Parameters:
7445: + mat - the matrix
7446: . ncolors - max color value
7447: . n - number of entries in colorarray
7448: - colorarray - array indicating color for each column
7450: Output Parameters:
7451: . iscoloring - coloring generated using colorarray information
7453: Level: developer
7455: .seealso: MatGetRowIJ(), MatGetColumnIJ()
7457: @*/
7458: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7459: {
7467: MatCheckPreallocated(mat,1);
7469: if (!mat->ops->coloringpatch) {
7470: ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7471: } else {
7472: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7473: }
7474: return(0);
7475: }
7480: /*@
7481: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7483: Logically Collective on Mat
7485: Input Parameter:
7486: . mat - the factored matrix to be reset
7488: Notes:
7489: This routine should be used only with factored matrices formed by in-place
7490: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7491: format). This option can save memory, for example, when solving nonlinear
7492: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7493: ILU(0) preconditioner.
7495: Note that one can specify in-place ILU(0) factorization by calling
7496: .vb
7497: PCType(pc,PCILU);
7498: PCFactorSeUseInPlace(pc);
7499: .ve
7500: or by using the options -pc_type ilu -pc_factor_in_place
7502: In-place factorization ILU(0) can also be used as a local
7503: solver for the blocks within the block Jacobi or additive Schwarz
7504: methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc
7505: for details on setting local solver options.
7507: Most users should employ the simplified KSP interface for linear solvers
7508: instead of working directly with matrix algebra routines such as this.
7509: See, e.g., KSPCreate().
7511: Level: developer
7513: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7515: Concepts: matrices^unfactored
7517: @*/
7518: PetscErrorCode MatSetUnfactored(Mat mat)
7519: {
7525: MatCheckPreallocated(mat,1);
7526: mat->factortype = MAT_FACTOR_NONE;
7527: if (!mat->ops->setunfactored) return(0);
7528: (*mat->ops->setunfactored)(mat);
7529: return(0);
7530: }
7532: /*MC
7533: MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7535: Synopsis:
7536: MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7538: Not collective
7540: Input Parameter:
7541: . x - matrix
7543: Output Parameters:
7544: + xx_v - the Fortran90 pointer to the array
7545: - ierr - error code
7547: Example of Usage:
7548: .vb
7549: PetscScalar, pointer xx_v(:,:)
7550: ....
7551: call MatDenseGetArrayF90(x,xx_v,ierr)
7552: a = xx_v(3)
7553: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7554: .ve
7556: Level: advanced
7558: .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7560: Concepts: matrices^accessing array
7562: M*/
7564: /*MC
7565: MatDenseRestoreArrayF90 - Restores a matrix array that has been
7566: accessed with MatDenseGetArrayF90().
7568: Synopsis:
7569: MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7571: Not collective
7573: Input Parameters:
7574: + x - matrix
7575: - xx_v - the Fortran90 pointer to the array
7577: Output Parameter:
7578: . ierr - error code
7580: Example of Usage:
7581: .vb
7582: PetscScalar, pointer xx_v(:,:)
7583: ....
7584: call MatDenseGetArrayF90(x,xx_v,ierr)
7585: a = xx_v(3)
7586: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7587: .ve
7589: Level: advanced
7591: .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7593: M*/
7596: /*MC
7597: MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7599: Synopsis:
7600: MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7602: Not collective
7604: Input Parameter:
7605: . x - matrix
7607: Output Parameters:
7608: + xx_v - the Fortran90 pointer to the array
7609: - ierr - error code
7611: Example of Usage:
7612: .vb
7613: PetscScalar, pointer xx_v(:)
7614: ....
7615: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7616: a = xx_v(3)
7617: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7618: .ve
7620: Level: advanced
7622: .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7624: Concepts: matrices^accessing array
7626: M*/
7628: /*MC
7629: MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7630: accessed with MatSeqAIJGetArrayF90().
7632: Synopsis:
7633: MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7635: Not collective
7637: Input Parameters:
7638: + x - matrix
7639: - xx_v - the Fortran90 pointer to the array
7641: Output Parameter:
7642: . ierr - error code
7644: Example of Usage:
7645: .vb
7646: PetscScalar, pointer xx_v(:)
7647: ....
7648: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7649: a = xx_v(3)
7650: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7651: .ve
7653: Level: advanced
7655: .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7657: M*/
7662: /*@
7663: MatGetSubMatrix - Gets a single submatrix on the same number of processors
7664: as the original matrix.
7666: Collective on Mat
7668: Input Parameters:
7669: + mat - the original matrix
7670: . isrow - parallel IS containing the rows this processor should obtain
7671: . 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.
7672: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7674: Output Parameter:
7675: . newmat - the new submatrix, of the same type as the old
7677: Level: advanced
7679: Notes:
7680: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7682: Some matrix types place restrictions on the row and column indices, such
7683: as that they be sorted or that they be equal to each other.
7685: The index sets may not have duplicate entries.
7687: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7688: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7689: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7690: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7691: you are finished using it.
7693: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7694: the input matrix.
7696: If iscol is NULL then all columns are obtained (not supported in Fortran).
7698: Example usage:
7699: Consider the following 8x8 matrix with 34 non-zero values, that is
7700: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7701: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7702: as follows:
7704: .vb
7705: 1 2 0 | 0 3 0 | 0 4
7706: Proc0 0 5 6 | 7 0 0 | 8 0
7707: 9 0 10 | 11 0 0 | 12 0
7708: -------------------------------------
7709: 13 0 14 | 15 16 17 | 0 0
7710: Proc1 0 18 0 | 19 20 21 | 0 0
7711: 0 0 0 | 22 23 0 | 24 0
7712: -------------------------------------
7713: Proc2 25 26 27 | 0 0 28 | 29 0
7714: 30 0 0 | 31 32 33 | 0 34
7715: .ve
7717: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7719: .vb
7720: 2 0 | 0 3 0 | 0
7721: Proc0 5 6 | 7 0 0 | 8
7722: -------------------------------
7723: Proc1 18 0 | 19 20 21 | 0
7724: -------------------------------
7725: Proc2 26 27 | 0 0 28 | 29
7726: 0 0 | 31 32 33 | 0
7727: .ve
7730: Concepts: matrices^submatrices
7732: .seealso: MatGetSubMatrices()
7733: @*/
7734: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7735: {
7737: PetscMPIInt size;
7738: Mat *local;
7739: IS iscoltmp;
7748: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7749: if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7751: MatCheckPreallocated(mat,1);
7752: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7754: if (!iscol || isrow == iscol) {
7755: PetscBool stride;
7756: PetscMPIInt grabentirematrix = 0,grab;
7757: PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7758: if (stride) {
7759: PetscInt first,step,n,rstart,rend;
7760: ISStrideGetInfo(isrow,&first,&step);
7761: if (step == 1) {
7762: MatGetOwnershipRange(mat,&rstart,&rend);
7763: if (rstart == first) {
7764: ISGetLocalSize(isrow,&n);
7765: if (n == rend-rstart) {
7766: grabentirematrix = 1;
7767: }
7768: }
7769: }
7770: }
7771: MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7772: if (grab) {
7773: PetscInfo(mat,"Getting entire matrix as submatrix\n");
7774: if (cll == MAT_INITIAL_MATRIX) {
7775: *newmat = mat;
7776: PetscObjectReference((PetscObject)mat);
7777: }
7778: return(0);
7779: }
7780: }
7782: if (!iscol) {
7783: ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7784: } else {
7785: iscoltmp = iscol;
7786: }
7788: /* if original matrix is on just one processor then use submatrix generated */
7789: if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7790: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7791: if (!iscol) {ISDestroy(&iscoltmp);}
7792: return(0);
7793: } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7794: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7795: *newmat = *local;
7796: PetscFree(local);
7797: if (!iscol) {ISDestroy(&iscoltmp);}
7798: return(0);
7799: } else if (!mat->ops->getsubmatrix) {
7800: /* Create a new matrix type that implements the operation using the full matrix */
7801: PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7802: switch (cll) {
7803: case MAT_INITIAL_MATRIX:
7804: MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7805: break;
7806: case MAT_REUSE_MATRIX:
7807: MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7808: break;
7809: default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7810: }
7811: PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7812: if (!iscol) {ISDestroy(&iscoltmp);}
7813: return(0);
7814: }
7816: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7817: PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7818: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7819: PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7820: if (!iscol) {ISDestroy(&iscoltmp);}
7821: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7822: return(0);
7823: }
7827: /*@
7828: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7829: used during the assembly process to store values that belong to
7830: other processors.
7832: Not Collective
7834: Input Parameters:
7835: + mat - the matrix
7836: . size - the initial size of the stash.
7837: - bsize - the initial size of the block-stash(if used).
7839: Options Database Keys:
7840: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7841: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7843: Level: intermediate
7845: Notes:
7846: The block-stash is used for values set with MatSetValuesBlocked() while
7847: the stash is used for values set with MatSetValues()
7849: Run with the option -info and look for output of the form
7850: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7851: to determine the appropriate value, MM, to use for size and
7852: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7853: to determine the value, BMM to use for bsize
7855: Concepts: stash^setting matrix size
7856: Concepts: matrices^stash
7858: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7860: @*/
7861: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7862: {
7868: MatStashSetInitialSize_Private(&mat->stash,size);
7869: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7870: return(0);
7871: }
7875: /*@
7876: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7877: the matrix
7879: Neighbor-wise Collective on Mat
7881: Input Parameters:
7882: + mat - the matrix
7883: . x,y - the vectors
7884: - w - where the result is stored
7886: Level: intermediate
7888: Notes:
7889: w may be the same vector as y.
7891: This allows one to use either the restriction or interpolation (its transpose)
7892: matrix to do the interpolation
7894: Concepts: interpolation
7896: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7898: @*/
7899: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7900: {
7902: PetscInt M,N,Ny;
7910: MatCheckPreallocated(A,1);
7911: MatGetSize(A,&M,&N);
7912: VecGetSize(y,&Ny);
7913: if (M == Ny) {
7914: MatMultAdd(A,x,y,w);
7915: } else {
7916: MatMultTransposeAdd(A,x,y,w);
7917: }
7918: return(0);
7919: }
7923: /*@
7924: MatInterpolate - y = A*x or A'*x depending on the shape of
7925: the matrix
7927: Neighbor-wise Collective on Mat
7929: Input Parameters:
7930: + mat - the matrix
7931: - x,y - the vectors
7933: Level: intermediate
7935: Notes:
7936: This allows one to use either the restriction or interpolation (its transpose)
7937: matrix to do the interpolation
7939: Concepts: matrices^interpolation
7941: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7943: @*/
7944: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7945: {
7947: PetscInt M,N,Ny;
7954: MatCheckPreallocated(A,1);
7955: MatGetSize(A,&M,&N);
7956: VecGetSize(y,&Ny);
7957: if (M == Ny) {
7958: MatMult(A,x,y);
7959: } else {
7960: MatMultTranspose(A,x,y);
7961: }
7962: return(0);
7963: }
7967: /*@
7968: MatRestrict - y = A*x or A'*x
7970: Neighbor-wise Collective on Mat
7972: Input Parameters:
7973: + mat - the matrix
7974: - x,y - the vectors
7976: Level: intermediate
7978: Notes:
7979: This allows one to use either the restriction or interpolation (its transpose)
7980: matrix to do the restriction
7982: Concepts: matrices^restriction
7984: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7986: @*/
7987: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7988: {
7990: PetscInt M,N,Ny;
7997: MatCheckPreallocated(A,1);
7999: MatGetSize(A,&M,&N);
8000: VecGetSize(y,&Ny);
8001: if (M == Ny) {
8002: MatMult(A,x,y);
8003: } else {
8004: MatMultTranspose(A,x,y);
8005: }
8006: return(0);
8007: }
8011: /*@
8012: MatGetNullSpace - retrieves the null space to a matrix.
8014: Logically Collective on Mat and MatNullSpace
8016: Input Parameters:
8017: + mat - the matrix
8018: - nullsp - the null space object
8020: Level: developer
8022: Concepts: null space^attaching to matrix
8024: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8025: @*/
8026: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8027: {
8032: *nullsp = mat->nullsp;
8033: return(0);
8034: }
8038: /*@
8039: MatSetNullSpace - attaches a null space to a matrix.
8041: Logically Collective on Mat and MatNullSpace
8043: Input Parameters:
8044: + mat - the matrix
8045: - nullsp - the null space object
8047: Level: advanced
8049: Notes:
8050: This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8052: For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8053: call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8055: You can remove the null space by calling this routine with an nullsp of NULL
8058: The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8059: 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).
8060: 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
8061: 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
8062: 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).
8064: Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8066: Concepts: null space^attaching to matrix
8068: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8069: @*/
8070: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8071: {
8078: MatCheckPreallocated(mat,1);
8079: if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8080: MatNullSpaceDestroy(&mat->nullsp);
8081: mat->nullsp = nullsp;
8082: return(0);
8083: }
8087: /*@
8088: MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8090: Logically Collective on Mat and MatNullSpace
8092: Input Parameters:
8093: + mat - the matrix
8094: - nullsp - the null space object
8096: Level: developer
8098: Concepts: null space^attaching to matrix
8100: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8101: @*/
8102: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8103: {
8108: *nullsp = mat->transnullsp;
8109: return(0);
8110: }
8114: /*@
8115: MatSetTransposeNullSpace - attaches a null space to a matrix.
8117: Logically Collective on Mat and MatNullSpace
8119: Input Parameters:
8120: + mat - the matrix
8121: - nullsp - the null space object
8123: Level: advanced
8125: Notes:
8126: 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.
8127: You must also call MatSetNullSpace()
8130: The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8131: 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).
8132: 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
8133: 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
8134: 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).
8136: Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8138: Concepts: null space^attaching to matrix
8140: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8141: @*/
8142: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8143: {
8150: MatCheckPreallocated(mat,1);
8151: PetscObjectReference((PetscObject)nullsp);
8152: MatNullSpaceDestroy(&mat->transnullsp);
8153: mat->transnullsp = nullsp;
8154: return(0);
8155: }
8159: /*@
8160: MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8161: This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8163: Logically Collective on Mat and MatNullSpace
8165: Input Parameters:
8166: + mat - the matrix
8167: - nullsp - the null space object
8169: Level: advanced
8171: Notes:
8172: Overwrites any previous near null space that may have been attached
8174: You can remove the null space by calling this routine with an nullsp of NULL
8176: Concepts: null space^attaching to matrix
8178: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8179: @*/
8180: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8181: {
8188: MatCheckPreallocated(mat,1);
8189: if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8190: MatNullSpaceDestroy(&mat->nearnullsp);
8191: mat->nearnullsp = nullsp;
8192: return(0);
8193: }
8197: /*@
8198: MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8200: Not Collective
8202: Input Parameters:
8203: . mat - the matrix
8205: Output Parameters:
8206: . nullsp - the null space object, NULL if not set
8208: Level: developer
8210: Concepts: null space^attaching to matrix
8212: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8213: @*/
8214: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8215: {
8220: MatCheckPreallocated(mat,1);
8221: *nullsp = mat->nearnullsp;
8222: return(0);
8223: }
8227: /*@C
8228: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8230: Collective on Mat
8232: Input Parameters:
8233: + mat - the matrix
8234: . row - row/column permutation
8235: . fill - expected fill factor >= 1.0
8236: - level - level of fill, for ICC(k)
8238: Notes:
8239: Probably really in-place only when level of fill is zero, otherwise allocates
8240: new space to store factored matrix and deletes previous memory.
8242: Most users should employ the simplified KSP interface for linear solvers
8243: instead of working directly with matrix algebra routines such as this.
8244: See, e.g., KSPCreate().
8246: Level: developer
8248: Concepts: matrices^incomplete Cholesky factorization
8249: Concepts: Cholesky factorization
8251: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8253: Developer Note: fortran interface is not autogenerated as the f90
8254: interface defintion cannot be generated correctly [due to MatFactorInfo]
8256: @*/
8257: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8258: {
8266: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8267: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8268: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8269: if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8270: MatCheckPreallocated(mat,1);
8271: (*mat->ops->iccfactor)(mat,row,info);
8272: PetscObjectStateIncrease((PetscObject)mat);
8273: return(0);
8274: }
8278: /*@
8279: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
8281: Not Collective
8283: Input Parameters:
8284: + mat - the matrix
8285: . nl - leading dimension of v
8286: - v - the values compute with ADIFOR
8288: Level: developer
8290: Notes:
8291: Must call MatSetColoring() before using this routine. Also this matrix must already
8292: have its nonzero pattern determined.
8294: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8295: MatSetValues(), MatSetColoring()
8296: @*/
8297: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8298: {
8306: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8307: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
8308: if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8309: (*mat->ops->setvaluesadifor)(mat,nl,v);
8310: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
8311: PetscObjectStateIncrease((PetscObject)mat);
8312: return(0);
8313: }
8317: /*@
8318: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8319: ghosted ones.
8321: Not Collective
8323: Input Parameters:
8324: + mat - the matrix
8325: - diag = the diagonal values, including ghost ones
8327: Level: developer
8329: Notes: Works only for MPIAIJ and MPIBAIJ matrices
8331: .seealso: MatDiagonalScale()
8332: @*/
8333: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8334: {
8336: PetscMPIInt size;
8343: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8344: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8345: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8346: if (size == 1) {
8347: PetscInt n,m;
8348: VecGetSize(diag,&n);
8349: MatGetSize(mat,0,&m);
8350: if (m == n) {
8351: MatDiagonalScale(mat,0,diag);
8352: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8353: } else {
8354: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8355: }
8356: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8357: PetscObjectStateIncrease((PetscObject)mat);
8358: return(0);
8359: }
8363: /*@
8364: MatGetInertia - Gets the inertia from a factored matrix
8366: Collective on Mat
8368: Input Parameter:
8369: . mat - the matrix
8371: Output Parameters:
8372: + nneg - number of negative eigenvalues
8373: . nzero - number of zero eigenvalues
8374: - npos - number of positive eigenvalues
8376: Level: advanced
8378: Notes: Matrix must have been factored by MatCholeskyFactor()
8381: @*/
8382: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8383: {
8389: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8390: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8391: if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8392: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8393: return(0);
8394: }
8396: /* ----------------------------------------------------------------*/
8399: /*@C
8400: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8402: Neighbor-wise Collective on Mat and Vecs
8404: Input Parameters:
8405: + mat - the factored matrix
8406: - b - the right-hand-side vectors
8408: Output Parameter:
8409: . x - the result vectors
8411: Notes:
8412: The vectors b and x cannot be the same. I.e., one cannot
8413: call MatSolves(A,x,x).
8415: Notes:
8416: Most users should employ the simplified KSP interface for linear solvers
8417: instead of working directly with matrix algebra routines such as this.
8418: See, e.g., KSPCreate().
8420: Level: developer
8422: Concepts: matrices^triangular solves
8424: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8425: @*/
8426: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8427: {
8433: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8434: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8435: if (!mat->rmap->N && !mat->cmap->N) return(0);
8437: if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8438: MatCheckPreallocated(mat,1);
8439: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8440: (*mat->ops->solves)(mat,b,x);
8441: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8442: return(0);
8443: }
8447: /*@
8448: MatIsSymmetric - Test whether a matrix is symmetric
8450: Collective on Mat
8452: Input Parameter:
8453: + A - the matrix to test
8454: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8456: Output Parameters:
8457: . flg - the result
8459: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8461: Level: intermediate
8463: Concepts: matrix^symmetry
8465: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8466: @*/
8467: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
8468: {
8475: if (!A->symmetric_set) {
8476: if (!A->ops->issymmetric) {
8477: MatType mattype;
8478: MatGetType(A,&mattype);
8479: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8480: }
8481: (*A->ops->issymmetric)(A,tol,flg);
8482: if (!tol) {
8483: A->symmetric_set = PETSC_TRUE;
8484: A->symmetric = *flg;
8485: if (A->symmetric) {
8486: A->structurally_symmetric_set = PETSC_TRUE;
8487: A->structurally_symmetric = PETSC_TRUE;
8488: }
8489: }
8490: } else if (A->symmetric) {
8491: *flg = PETSC_TRUE;
8492: } else if (!tol) {
8493: *flg = PETSC_FALSE;
8494: } else {
8495: if (!A->ops->issymmetric) {
8496: MatType mattype;
8497: MatGetType(A,&mattype);
8498: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8499: }
8500: (*A->ops->issymmetric)(A,tol,flg);
8501: }
8502: return(0);
8503: }
8507: /*@
8508: MatIsHermitian - Test whether a matrix is Hermitian
8510: Collective on Mat
8512: Input Parameter:
8513: + A - the matrix to test
8514: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8516: Output Parameters:
8517: . flg - the result
8519: Level: intermediate
8521: Concepts: matrix^symmetry
8523: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8524: MatIsSymmetricKnown(), MatIsSymmetric()
8525: @*/
8526: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
8527: {
8534: if (!A->hermitian_set) {
8535: if (!A->ops->ishermitian) {
8536: MatType mattype;
8537: MatGetType(A,&mattype);
8538: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8539: }
8540: (*A->ops->ishermitian)(A,tol,flg);
8541: if (!tol) {
8542: A->hermitian_set = PETSC_TRUE;
8543: A->hermitian = *flg;
8544: if (A->hermitian) {
8545: A->structurally_symmetric_set = PETSC_TRUE;
8546: A->structurally_symmetric = PETSC_TRUE;
8547: }
8548: }
8549: } else if (A->hermitian) {
8550: *flg = PETSC_TRUE;
8551: } else if (!tol) {
8552: *flg = PETSC_FALSE;
8553: } else {
8554: if (!A->ops->ishermitian) {
8555: MatType mattype;
8556: MatGetType(A,&mattype);
8557: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8558: }
8559: (*A->ops->ishermitian)(A,tol,flg);
8560: }
8561: return(0);
8562: }
8566: /*@
8567: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8569: Not Collective
8571: Input Parameter:
8572: . A - the matrix to check
8574: Output Parameters:
8575: + set - if the symmetric flag is set (this tells you if the next flag is valid)
8576: - flg - the result
8578: Level: advanced
8580: Concepts: matrix^symmetry
8582: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8583: if you want it explicitly checked
8585: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8586: @*/
8587: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
8588: {
8593: if (A->symmetric_set) {
8594: *set = PETSC_TRUE;
8595: *flg = A->symmetric;
8596: } else {
8597: *set = PETSC_FALSE;
8598: }
8599: return(0);
8600: }
8604: /*@
8605: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8607: Not Collective
8609: Input Parameter:
8610: . A - the matrix to check
8612: Output Parameters:
8613: + set - if the hermitian flag is set (this tells you if the next flag is valid)
8614: - flg - the result
8616: Level: advanced
8618: Concepts: matrix^symmetry
8620: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8621: if you want it explicitly checked
8623: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8624: @*/
8625: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8626: {
8631: if (A->hermitian_set) {
8632: *set = PETSC_TRUE;
8633: *flg = A->hermitian;
8634: } else {
8635: *set = PETSC_FALSE;
8636: }
8637: return(0);
8638: }
8642: /*@
8643: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8645: Collective on Mat
8647: Input Parameter:
8648: . A - the matrix to test
8650: Output Parameters:
8651: . flg - the result
8653: Level: intermediate
8655: Concepts: matrix^symmetry
8657: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8658: @*/
8659: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8660: {
8666: if (!A->structurally_symmetric_set) {
8667: if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8668: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8670: A->structurally_symmetric_set = PETSC_TRUE;
8671: }
8672: *flg = A->structurally_symmetric;
8673: return(0);
8674: }
8678: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8679: /*@
8680: MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8681: to be communicated to other processors during the MatAssemblyBegin/End() process
8683: Not collective
8685: Input Parameter:
8686: . vec - the vector
8688: Output Parameters:
8689: + nstash - the size of the stash
8690: . reallocs - the number of additional mallocs incurred.
8691: . bnstash - the size of the block stash
8692: - breallocs - the number of additional mallocs incurred.in the block stash
8694: Level: advanced
8696: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8698: @*/
8699: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8700: {
8704: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8705: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8706: return(0);
8707: }
8711: /*@C
8712: MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8713: parallel layout
8715: Collective on Mat
8717: Input Parameter:
8718: . mat - the matrix
8720: Output Parameter:
8721: + right - (optional) vector that the matrix can be multiplied against
8722: - left - (optional) vector that the matrix vector product can be stored in
8724: Notes:
8725: 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().
8727: Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8729: Level: advanced
8731: .seealso: MatCreate(), VecDestroy()
8732: @*/
8733: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8734: {
8740: if (mat->ops->getvecs) {
8741: (*mat->ops->getvecs)(mat,right,left);
8742: } else {
8743: PetscInt rbs,cbs;
8744: MatGetBlockSizes(mat,&rbs,&cbs);
8745: if (right) {
8746: if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8747: VecCreate(PetscObjectComm((PetscObject)mat),right);
8748: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8749: VecSetBlockSize(*right,cbs);
8750: VecSetType(*right,VECSTANDARD);
8751: PetscLayoutReference(mat->cmap,&(*right)->map);
8752: }
8753: if (left) {
8754: if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8755: VecCreate(PetscObjectComm((PetscObject)mat),left);
8756: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8757: VecSetBlockSize(*left,rbs);
8758: VecSetType(*left,VECSTANDARD);
8759: PetscLayoutReference(mat->rmap,&(*left)->map);
8760: }
8761: }
8762: return(0);
8763: }
8767: /*@C
8768: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8769: with default values.
8771: Not Collective
8773: Input Parameters:
8774: . info - the MatFactorInfo data structure
8777: Notes: The solvers are generally used through the KSP and PC objects, for example
8778: PCLU, PCILU, PCCHOLESKY, PCICC
8780: Level: developer
8782: .seealso: MatFactorInfo
8784: Developer Note: fortran interface is not autogenerated as the f90
8785: interface defintion cannot be generated correctly [due to MatFactorInfo]
8787: @*/
8789: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8790: {
8794: PetscMemzero(info,sizeof(MatFactorInfo));
8795: return(0);
8796: }
8800: /*@
8801: MatFactorSetSchurIS - Set indices corresponding to the Schur complement
8803: Collective on Mat
8805: Input Parameters:
8806: + mat - the factored matrix
8807: - is - the index set defining the Schur indices (0-based)
8809: Notes:
8811: Level: developer
8813: Concepts:
8815: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8817: @*/
8818: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8819: {
8820: PetscErrorCode ierr,(*f)(Mat,IS);
8828: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8829: PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8830: 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");
8831: (*f)(mat,is);
8832: return(0);
8833: }
8837: /*@
8838: MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8840: Logically Collective on Mat
8842: Input Parameters:
8843: + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8844: . *S - location where to return the Schur complement (MATDENSE)
8846: Notes:
8847: The routine provides a copy of the Schur data stored within solver's data strutures. The caller must destroy the object when it is no longer needed.
8848: If MatFactorInvertSchurComplement has been called, the routine gets back the inverse
8850: Level: advanced
8852: References:
8854: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement()
8855: @*/
8856: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S)
8857: {
8862: PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));
8863: return(0);
8864: }
8868: /*@
8869: MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data
8871: Logically Collective on Mat
8873: Input Parameters:
8874: + F - the factored matrix obtained by calling MatGetFactor()
8875: . *S - location where to return the Schur complement (in MATDENSE format)
8877: Notes:
8878: Schur complement mode is currently implemented for sequential matrices.
8879: The routine returns a dense matrix pointing to the raw data of the Schur Complement stored within the data strutures of the solver; e.g. if MatFactorInvertSchurComplement has been called, the returned matrix is actually the inverse of the Schur complement.
8880: The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.
8882: Level: advanced
8884: References:
8886: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8887: @*/
8888: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S)
8889: {
8894: PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));
8895: return(0);
8896: }
8900: /*@
8901: MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8903: Logically Collective on Mat
8905: Input Parameters:
8906: + F - the factored matrix obtained by calling MatGetFactor()
8907: . *S - location where the Schur complement is stored
8909: Notes:
8911: Level: advanced
8913: References:
8915: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8916: @*/
8917: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S)
8918: {
8924: MatDestroy(S);
8925: return(0);
8926: }
8930: /*@
8931: MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8933: Logically Collective on Mat
8935: Input Parameters:
8936: + F - the factored matrix obtained by calling MatGetFactor()
8937: . rhs - location where the right hand side of the Schur complement system is stored
8938: - sol - location where the solution of the Schur complement system has to be returned
8940: Notes:
8941: The sizes of the vectors should match the size of the Schur complement
8943: Level: advanced
8945: References:
8947: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8948: @*/
8949: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8950: {
8959: PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));
8960: return(0);
8961: }
8965: /*@
8966: MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8968: Logically Collective on Mat
8970: Input Parameters:
8971: + F - the factored matrix obtained by calling MatGetFactor()
8972: . rhs - location where the right hand side of the Schur complement system is stored
8973: - sol - location where the solution of the Schur complement system has to be returned
8975: Notes:
8976: The sizes of the vectors should match the size of the Schur complement
8978: Level: advanced
8980: References:
8982: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8983: @*/
8984: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8985: {
8994: PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));
8995: return(0);
8996: }
9000: /*@
9001: MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step
9003: Logically Collective on Mat
9005: Input Parameters:
9006: + F - the factored matrix obtained by calling MatGetFactor()
9008: Notes:
9010: Level: advanced
9012: References:
9014: .seealso: MatGetFactor(), MatFactorSetSchurIS()
9015: @*/
9016: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9017: {
9022: PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));
9023: return(0);
9024: }
9029: /*@
9030: MatPtAP - Creates the matrix product C = P^T * A * P
9032: Neighbor-wise Collective on Mat
9034: Input Parameters:
9035: + A - the matrix
9036: . P - the projection matrix
9037: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9038: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9039: if the result is a dense matrix this is irrelevent
9041: Output Parameters:
9042: . C - the product matrix
9044: Notes:
9045: C will be created and must be destroyed by the user with MatDestroy().
9047: This routine is currently only implemented for pairs of AIJ matrices and classes
9048: which inherit from AIJ.
9050: Level: intermediate
9052: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9053: @*/
9054: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9055: {
9057: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9058: PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9059: PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9060: PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
9063: PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
9064: PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);
9068: MatCheckPreallocated(A,1);
9069: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9070: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9073: MatCheckPreallocated(P,2);
9074: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9075: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9077: 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);
9078: 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);
9079: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9080: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9082: if (scall == MAT_REUSE_MATRIX) {
9085: if (viatranspose || viamatmatmatmult) {
9086: Mat Pt;
9087: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9088: if (viamatmatmatmult) {
9089: MatMatMatMult(Pt,A,P,scall,fill,C);
9090: } else {
9091: Mat AP;
9092: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9093: MatMatMult(Pt,AP,scall,fill,C);
9094: MatDestroy(&AP);
9095: }
9096: MatDestroy(&Pt);
9097: } else {
9098: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9099: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9100: (*(*C)->ops->ptapnumeric)(A,P,*C);
9101: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9102: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9103: }
9104: return(0);
9105: }
9107: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9108: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9110: fA = A->ops->ptap;
9111: fP = P->ops->ptap;
9112: if (fP == fA) {
9113: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9114: ptap = fA;
9115: } else {
9116: /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9117: char ptapname[256];
9118: PetscStrcpy(ptapname,"MatPtAP_");
9119: PetscStrcat(ptapname,((PetscObject)A)->type_name);
9120: PetscStrcat(ptapname,"_");
9121: PetscStrcat(ptapname,((PetscObject)P)->type_name);
9122: PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9123: PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9124: if (!ptap) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s",((PetscObject)A)->type_name,((PetscObject)P)->type_name);
9125: }
9127: if (viatranspose || viamatmatmatmult) {
9128: Mat Pt;
9129: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9130: if (viamatmatmatmult) {
9131: MatMatMatMult(Pt,A,P,scall,fill,C);
9132: PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
9133: } else {
9134: Mat AP;
9135: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9136: MatMatMult(Pt,AP,scall,fill,C);
9137: MatDestroy(&AP);
9138: PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
9139: }
9140: MatDestroy(&Pt);
9141: } else {
9142: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9143: (*ptap)(A,P,scall,fill,C);
9144: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9145: }
9146: return(0);
9147: }
9151: /*@
9152: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9154: Neighbor-wise Collective on Mat
9156: Input Parameters:
9157: + A - the matrix
9158: - P - the projection matrix
9160: Output Parameters:
9161: . C - the product matrix
9163: Notes:
9164: C must have been created by calling MatPtAPSymbolic and must be destroyed by
9165: the user using MatDeatroy().
9167: This routine is currently only implemented for pairs of AIJ matrices and classes
9168: which inherit from AIJ. C will be of type MATAIJ.
9170: Level: intermediate
9172: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9173: @*/
9174: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9175: {
9181: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9182: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9185: MatCheckPreallocated(P,2);
9186: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9187: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9190: MatCheckPreallocated(C,3);
9191: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9192: 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);
9193: 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);
9194: 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);
9195: 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);
9196: MatCheckPreallocated(A,1);
9198: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9199: (*C->ops->ptapnumeric)(A,P,C);
9200: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9201: return(0);
9202: }
9206: /*@
9207: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9209: Neighbor-wise Collective on Mat
9211: Input Parameters:
9212: + A - the matrix
9213: - P - the projection matrix
9215: Output Parameters:
9216: . C - the (i,j) structure of the product matrix
9218: Notes:
9219: C will be created and must be destroyed by the user with MatDestroy().
9221: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9222: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
9223: this (i,j) structure by calling MatPtAPNumeric().
9225: Level: intermediate
9227: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9228: @*/
9229: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9230: {
9236: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9237: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9238: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9241: MatCheckPreallocated(P,2);
9242: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9243: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9246: 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);
9247: 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);
9248: MatCheckPreallocated(A,1);
9249: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9250: (*A->ops->ptapsymbolic)(A,P,fill,C);
9251: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
9253: /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
9254: return(0);
9255: }
9259: /*@
9260: MatRARt - Creates the matrix product C = R * A * R^T
9262: Neighbor-wise Collective on Mat
9264: Input Parameters:
9265: + A - the matrix
9266: . R - the projection matrix
9267: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9268: - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9269: if the result is a dense matrix this is irrelevent
9271: Output Parameters:
9272: . C - the product matrix
9274: Notes:
9275: C will be created and must be destroyed by the user with MatDestroy().
9277: This routine is currently only implemented for pairs of AIJ matrices and classes
9278: which inherit from AIJ.
9280: Level: intermediate
9282: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9283: @*/
9284: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9285: {
9291: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9292: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9295: MatCheckPreallocated(R,2);
9296: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9297: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9299: 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);
9301: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9302: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9303: MatCheckPreallocated(A,1);
9305: if (!A->ops->rart) {
9306: MatType mattype;
9307: MatGetType(A,&mattype);
9308: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
9309: }
9310: PetscLogEventBegin(MAT_RARt,A,R,0,0);
9311: (*A->ops->rart)(A,R,scall,fill,C);
9312: PetscLogEventEnd(MAT_RARt,A,R,0,0);
9313: return(0);
9314: }
9318: /*@
9319: MatRARtNumeric - Computes the matrix product C = R * A * R^T
9321: Neighbor-wise Collective on Mat
9323: Input Parameters:
9324: + A - the matrix
9325: - R - the projection matrix
9327: Output Parameters:
9328: . C - the product matrix
9330: Notes:
9331: C must have been created by calling MatRARtSymbolic and must be destroyed by
9332: the user using MatDestroy().
9334: This routine is currently only implemented for pairs of AIJ matrices and classes
9335: which inherit from AIJ. C will be of type MATAIJ.
9337: Level: intermediate
9339: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9340: @*/
9341: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9342: {
9348: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9349: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9352: MatCheckPreallocated(R,2);
9353: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9354: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9357: MatCheckPreallocated(C,3);
9358: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9359: 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);
9360: 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);
9361: 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);
9362: 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);
9363: MatCheckPreallocated(A,1);
9365: PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
9366: (*A->ops->rartnumeric)(A,R,C);
9367: PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
9368: return(0);
9369: }
9373: /*@
9374: MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9376: Neighbor-wise Collective on Mat
9378: Input Parameters:
9379: + A - the matrix
9380: - R - the projection matrix
9382: Output Parameters:
9383: . C - the (i,j) structure of the product matrix
9385: Notes:
9386: C will be created and must be destroyed by the user with MatDestroy().
9388: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9389: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
9390: this (i,j) structure by calling MatRARtNumeric().
9392: Level: intermediate
9394: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9395: @*/
9396: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9397: {
9403: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9404: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9405: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9408: MatCheckPreallocated(R,2);
9409: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9410: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9413: 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);
9414: 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);
9415: MatCheckPreallocated(A,1);
9416: PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9417: (*A->ops->rartsymbolic)(A,R,fill,C);
9418: PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
9420: MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9421: return(0);
9422: }
9426: /*@
9427: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9429: Neighbor-wise Collective on Mat
9431: Input Parameters:
9432: + A - the left matrix
9433: . B - the right matrix
9434: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9435: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9436: if the result is a dense matrix this is irrelevent
9438: Output Parameters:
9439: . C - the product matrix
9441: Notes:
9442: Unless scall is MAT_REUSE_MATRIX C will be created.
9444: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9446: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9447: actually needed.
9449: If you have many matrices with the same non-zero structure to multiply, you
9450: should either
9451: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
9452: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9453: 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
9454: with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9456: Level: intermediate
9458: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
9459: @*/
9460: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9461: {
9463: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9464: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9465: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9470: MatCheckPreallocated(A,1);
9471: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9472: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9475: MatCheckPreallocated(B,2);
9476: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9477: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9479: 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);
9480: if (scall == MAT_REUSE_MATRIX) {
9483: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9484: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9485: (*(*C)->ops->matmultnumeric)(A,B,*C);
9486: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9487: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9488: return(0);
9489: }
9490: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9491: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9493: fA = A->ops->matmult;
9494: fB = B->ops->matmult;
9495: if (fB == fA) {
9496: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9497: mult = fB;
9498: } else {
9499: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9500: char multname[256];
9501: PetscStrcpy(multname,"MatMatMult_");
9502: PetscStrcat(multname,((PetscObject)A)->type_name);
9503: PetscStrcat(multname,"_");
9504: PetscStrcat(multname,((PetscObject)B)->type_name);
9505: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9506: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9507: 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);
9508: }
9509: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9510: (*mult)(A,B,scall,fill,C);
9511: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9512: return(0);
9513: }
9517: /*@
9518: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9519: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
9521: Neighbor-wise Collective on Mat
9523: Input Parameters:
9524: + A - the left matrix
9525: . B - the right matrix
9526: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9527: if C is a dense matrix this is irrelevent
9529: Output Parameters:
9530: . C - the product matrix
9532: Notes:
9533: Unless scall is MAT_REUSE_MATRIX C will be created.
9535: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9536: actually needed.
9538: This routine is currently implemented for
9539: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9540: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9541: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9543: Level: intermediate
9545: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9546: We should incorporate them into PETSc.
9548: .seealso: MatMatMult(), MatMatMultNumeric()
9549: @*/
9550: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9551: {
9553: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9554: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9555: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9560: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9561: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9565: MatCheckPreallocated(B,2);
9566: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9567: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9570: 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);
9571: if (fill == PETSC_DEFAULT) fill = 2.0;
9572: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9573: MatCheckPreallocated(A,1);
9575: Asymbolic = A->ops->matmultsymbolic;
9576: Bsymbolic = B->ops->matmultsymbolic;
9577: if (Asymbolic == Bsymbolic) {
9578: if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9579: symbolic = Bsymbolic;
9580: } else { /* dispatch based on the type of A and B */
9581: char symbolicname[256];
9582: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9583: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9584: PetscStrcat(symbolicname,"_");
9585: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9586: PetscStrcat(symbolicname,"_C");
9587: PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9588: 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);
9589: }
9590: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9591: (*symbolic)(A,B,fill,C);
9592: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9593: return(0);
9594: }
9598: /*@
9599: MatMatMultNumeric - Performs the numeric matrix-matrix product.
9600: Call this routine after first calling MatMatMultSymbolic().
9602: Neighbor-wise Collective on Mat
9604: Input Parameters:
9605: + A - the left matrix
9606: - B - the right matrix
9608: Output Parameters:
9609: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9611: Notes:
9612: C must have been created with MatMatMultSymbolic().
9614: This routine is currently implemented for
9615: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9616: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9617: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9619: Level: intermediate
9621: .seealso: MatMatMult(), MatMatMultSymbolic()
9622: @*/
9623: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9624: {
9628: MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9629: return(0);
9630: }
9634: /*@
9635: MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9637: Neighbor-wise Collective on Mat
9639: Input Parameters:
9640: + A - the left matrix
9641: . B - the right matrix
9642: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9643: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9645: Output Parameters:
9646: . C - the product matrix
9648: Notes:
9649: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9651: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9653: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9654: actually needed.
9656: This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ.
9658: Level: intermediate
9660: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9661: @*/
9662: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9663: {
9665: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9666: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9671: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9672: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9675: MatCheckPreallocated(B,2);
9676: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9677: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9679: 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);
9680: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9681: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9682: MatCheckPreallocated(A,1);
9684: fA = A->ops->mattransposemult;
9685: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9686: fB = B->ops->mattransposemult;
9687: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9688: 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);
9690: PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9691: if (scall == MAT_INITIAL_MATRIX) {
9692: PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9693: (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9694: PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9695: }
9696: PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9697: (*A->ops->mattransposemultnumeric)(A,B,*C);
9698: PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9699: PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9700: return(0);
9701: }
9705: /*@
9706: MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9708: Neighbor-wise Collective on Mat
9710: Input Parameters:
9711: + A - the left matrix
9712: . B - the right matrix
9713: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9714: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9716: Output Parameters:
9717: . C - the product matrix
9719: Notes:
9720: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9722: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9724: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9725: actually needed.
9727: This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9728: which inherit from SeqAIJ. C will be of same type as the input matrices.
9730: Level: intermediate
9732: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9733: @*/
9734: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9735: {
9737: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9738: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9739: PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9744: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9745: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9748: MatCheckPreallocated(B,2);
9749: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9750: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9752: 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);
9753: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9754: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9755: MatCheckPreallocated(A,1);
9757: fA = A->ops->transposematmult;
9758: fB = B->ops->transposematmult;
9759: if (fB==fA) {
9760: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9761: transposematmult = fA;
9762: } else {
9763: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9764: char multname[256];
9765: PetscStrcpy(multname,"MatTransposeMatMult_");
9766: PetscStrcat(multname,((PetscObject)A)->type_name);
9767: PetscStrcat(multname,"_");
9768: PetscStrcat(multname,((PetscObject)B)->type_name);
9769: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9770: PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9771: 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);
9772: }
9773: PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9774: (*transposematmult)(A,B,scall,fill,C);
9775: PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9776: return(0);
9777: }
9781: /*@
9782: MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9784: Neighbor-wise Collective on Mat
9786: Input Parameters:
9787: + A - the left matrix
9788: . B - the middle matrix
9789: . C - the right matrix
9790: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9791: - 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
9792: if the result is a dense matrix this is irrelevent
9794: Output Parameters:
9795: . D - the product matrix
9797: Notes:
9798: Unless scall is MAT_REUSE_MATRIX D will be created.
9800: MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9802: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9803: actually needed.
9805: If you have many matrices with the same non-zero structure to multiply, you
9806: should use MAT_REUSE_MATRIX in all calls but the first or
9808: Level: intermediate
9810: .seealso: MatMatMult, MatPtAP()
9811: @*/
9812: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9813: {
9815: PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9816: PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9817: PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9818: PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9823: MatCheckPreallocated(A,1);
9824: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9825: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9828: MatCheckPreallocated(B,2);
9829: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9830: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9833: MatCheckPreallocated(C,3);
9834: if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9835: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9836: 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);
9837: 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);
9838: if (scall == MAT_REUSE_MATRIX) {
9841: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9842: (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9843: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9844: return(0);
9845: }
9846: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9847: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9849: fA = A->ops->matmatmult;
9850: fB = B->ops->matmatmult;
9851: fC = C->ops->matmatmult;
9852: if (fA == fB && fA == fC) {
9853: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9854: mult = fA;
9855: } else {
9856: /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9857: char multname[256];
9858: PetscStrcpy(multname,"MatMatMatMult_");
9859: PetscStrcat(multname,((PetscObject)A)->type_name);
9860: PetscStrcat(multname,"_");
9861: PetscStrcat(multname,((PetscObject)B)->type_name);
9862: PetscStrcat(multname,"_");
9863: PetscStrcat(multname,((PetscObject)C)->type_name);
9864: PetscStrcat(multname,"_C");
9865: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9866: 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);
9867: }
9868: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9869: (*mult)(A,B,C,scall,fill,D);
9870: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9871: return(0);
9872: }
9876: /*@C
9877: MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9879: Collective on Mat
9881: Input Parameters:
9882: + mat - the matrix
9883: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9884: . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9885: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9887: Output Parameter:
9888: . matredundant - redundant matrix
9890: Notes:
9891: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9892: original matrix has not changed from that last call to MatCreateRedundantMatrix().
9894: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9895: calling it.
9897: Level: advanced
9899: Concepts: subcommunicator
9900: Concepts: duplicate matrix
9902: .seealso: MatDestroy()
9903: @*/
9904: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9905: {
9907: MPI_Comm comm;
9908: PetscMPIInt size;
9909: PetscInt mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9910: Mat_Redundant *redund=NULL;
9911: PetscSubcomm psubcomm=NULL;
9912: MPI_Comm subcomm_in=subcomm;
9913: Mat *matseq;
9914: IS isrow,iscol;
9915: PetscBool newsubcomm=PETSC_FALSE;
9918: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
9919: if (size == 1 || nsubcomm == 1) {
9920: if (reuse == MAT_INITIAL_MATRIX) {
9921: MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
9922: } else {
9923: MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
9924: }
9925: return(0);
9926: }
9929: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9932: }
9933: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9934: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9935: MatCheckPreallocated(mat,1);
9937: PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
9938: if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9939: /* create psubcomm, then get subcomm */
9940: PetscObjectGetComm((PetscObject)mat,&comm);
9941: MPI_Comm_size(comm,&size);
9942: if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9944: PetscSubcommCreate(comm,&psubcomm);
9945: PetscSubcommSetNumber(psubcomm,nsubcomm);
9946: PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
9947: PetscSubcommSetFromOptions(psubcomm);
9948: PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);
9949: newsubcomm = PETSC_TRUE;
9950: PetscSubcommDestroy(&psubcomm);
9951: }
9953: /* get isrow, iscol and a local sequential matrix matseq[0] */
9954: if (reuse == MAT_INITIAL_MATRIX) {
9955: mloc_sub = PETSC_DECIDE;
9956: if (bs < 1) {
9957: PetscSplitOwnership(subcomm,&mloc_sub,&M);
9958: } else {
9959: PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
9960: }
9961: MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
9962: rstart = rend - mloc_sub;
9963: ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
9964: ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
9965: } else { /* reuse == MAT_REUSE_MATRIX */
9966: /* retrieve subcomm */
9967: PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
9968: redund = (*matredundant)->redundant;
9969: isrow = redund->isrow;
9970: iscol = redund->iscol;
9971: matseq = redund->matseq;
9972: }
9973: MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);
9975: /* get matredundant over subcomm */
9976: if (reuse == MAT_INITIAL_MATRIX) {
9977: MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);
9979: /* create a supporting struct and attach it to C for reuse */
9980: PetscNewLog(*matredundant,&redund);
9981: (*matredundant)->redundant = redund;
9982: redund->isrow = isrow;
9983: redund->iscol = iscol;
9984: redund->matseq = matseq;
9985: if (newsubcomm) {
9986: redund->subcomm = subcomm;
9987: } else {
9988: redund->subcomm = MPI_COMM_NULL;
9989: }
9990: } else {
9991: MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
9992: }
9993: PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
9994: return(0);
9995: }
9999: /*@C
10000: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10001: a given 'mat' object. Each submatrix can span multiple procs.
10003: Collective on Mat
10005: Input Parameters:
10006: + mat - the matrix
10007: . subcomm - the subcommunicator obtained by com_split(comm)
10008: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10010: Output Parameter:
10011: . subMat - 'parallel submatrices each spans a given subcomm
10013: Notes:
10014: The submatrix partition across processors is dictated by 'subComm' a
10015: communicator obtained by com_split(comm). The comm_split
10016: is not restriced to be grouped with consecutive original ranks.
10018: Due the comm_split() usage, the parallel layout of the submatrices
10019: map directly to the layout of the original matrix [wrt the local
10020: row,col partitioning]. So the original 'DiagonalMat' naturally maps
10021: into the 'DiagonalMat' of the subMat, hence it is used directly from
10022: the subMat. However the offDiagMat looses some columns - and this is
10023: reconstructed with MatSetValues()
10025: Level: advanced
10027: Concepts: subcommunicator
10028: Concepts: submatrices
10030: .seealso: MatGetSubMatrices()
10031: @*/
10032: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10033: {
10035: PetscMPIInt commsize,subCommSize;
10038: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
10039: MPI_Comm_size(subComm,&subCommSize);
10040: if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10042: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
10043: (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
10044: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
10045: return(0);
10046: }
10050: /*@
10051: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10053: Not Collective
10055: Input Arguments:
10056: mat - matrix to extract local submatrix from
10057: isrow - local row indices for submatrix
10058: iscol - local column indices for submatrix
10060: Output Arguments:
10061: submat - the submatrix
10063: Level: intermediate
10065: Notes:
10066: The submat should be returned with MatRestoreLocalSubMatrix().
10068: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
10069: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10071: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
10072: MatSetValuesBlockedLocal() will also be implemented.
10074: The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10075: matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10077: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10078: @*/
10079: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10080: {
10089: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10090:
10091: if (mat->ops->getlocalsubmatrix) {
10092: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
10093: } else {
10094: MatCreateLocalRef(mat,isrow,iscol,submat);
10095: }
10096: return(0);
10097: }
10101: /*@
10102: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10104: Not Collective
10106: Input Arguments:
10107: mat - matrix to extract local submatrix from
10108: isrow - local row indices for submatrix
10109: iscol - local column indices for submatrix
10110: submat - the submatrix
10112: Level: intermediate
10114: .seealso: MatGetLocalSubMatrix()
10115: @*/
10116: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10117: {
10126: if (*submat) {
10128: }
10130: if (mat->ops->restorelocalsubmatrix) {
10131: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
10132: } else {
10133: MatDestroy(submat);
10134: }
10135: *submat = NULL;
10136: return(0);
10137: }
10139: /* --------------------------------------------------------*/
10142: /*@
10143: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
10145: Collective on Mat
10147: Input Parameter:
10148: . mat - the matrix
10150: Output Parameter:
10151: . is - if any rows have zero diagonals this contains the list of them
10153: Level: developer
10155: Concepts: matrix-vector product
10157: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10158: @*/
10159: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10160: {
10166: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10167: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10169: if (!mat->ops->findzerodiagonals) {
10170: Vec diag;
10171: const PetscScalar *a;
10172: PetscInt *rows;
10173: PetscInt rStart, rEnd, r, nrow = 0;
10175: MatCreateVecs(mat, &diag, NULL);
10176: MatGetDiagonal(mat, diag);
10177: MatGetOwnershipRange(mat, &rStart, &rEnd);
10178: VecGetArrayRead(diag, &a);
10179: for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10180: PetscMalloc1(nrow, &rows);
10181: nrow = 0;
10182: for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10183: VecRestoreArrayRead(diag, &a);
10184: VecDestroy(&diag);
10185: ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);
10186: } else {
10187: (*mat->ops->findzerodiagonals)(mat, is);
10188: }
10189: return(0);
10190: }
10194: /*@
10195: MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10197: Collective on Mat
10199: Input Parameter:
10200: . mat - the matrix
10202: Output Parameter:
10203: . is - contains the list of rows with off block diagonal entries
10205: Level: developer
10207: Concepts: matrix-vector product
10209: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10210: @*/
10211: PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10212: {
10218: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10219: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10221: if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10222: (*mat->ops->findoffblockdiagonalentries)(mat,is);
10223: return(0);
10224: }
10228: /*@C
10229: MatInvertBlockDiagonal - Inverts the block diagonal entries.
10231: Collective on Mat
10233: Input Parameters:
10234: . mat - the matrix
10236: Output Parameters:
10237: . values - the block inverses in column major order (FORTRAN-like)
10239: Note:
10240: This routine is not available from Fortran.
10242: Level: advanced
10243: @*/
10244: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10245: {
10250: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10251: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10252: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10253: (*mat->ops->invertblockdiagonal)(mat,values);
10254: return(0);
10255: }
10259: /*@C
10260: MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10261: via MatTransposeColoringCreate().
10263: Collective on MatTransposeColoring
10265: Input Parameter:
10266: . c - coloring context
10268: Level: intermediate
10270: .seealso: MatTransposeColoringCreate()
10271: @*/
10272: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10273: {
10274: PetscErrorCode ierr;
10275: MatTransposeColoring matcolor=*c;
10278: if (!matcolor) return(0);
10279: if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
10281: PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
10282: PetscFree(matcolor->rows);
10283: PetscFree(matcolor->den2sp);
10284: PetscFree(matcolor->colorforcol);
10285: PetscFree(matcolor->columns);
10286: if (matcolor->brows>0) {
10287: PetscFree(matcolor->lstart);
10288: }
10289: PetscHeaderDestroy(c);
10290: return(0);
10291: }
10295: /*@C
10296: MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10297: a MatTransposeColoring context has been created, computes a dense B^T by Apply
10298: MatTransposeColoring to sparse B.
10300: Collective on MatTransposeColoring
10302: Input Parameters:
10303: + B - sparse matrix B
10304: . Btdense - symbolic dense matrix B^T
10305: - coloring - coloring context created with MatTransposeColoringCreate()
10307: Output Parameter:
10308: . Btdense - dense matrix B^T
10310: Options Database Keys:
10311: + -mat_transpose_coloring_view - Activates basic viewing or coloring
10312: . -mat_transpose_coloring_view_draw - Activates drawing of coloring
10313: - -mat_transpose_coloring_view_info - Activates viewing of coloring info
10315: Level: intermediate
10317: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
10319: .keywords: coloring
10320: @*/
10321: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10322: {
10330: if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10331: (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
10332: return(0);
10333: }
10337: /*@C
10338: MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10339: a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10340: in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10341: Csp from Cden.
10343: Collective on MatTransposeColoring
10345: Input Parameters:
10346: + coloring - coloring context created with MatTransposeColoringCreate()
10347: - Cden - matrix product of a sparse matrix and a dense matrix Btdense
10349: Output Parameter:
10350: . Csp - sparse matrix
10352: Options Database Keys:
10353: + -mat_multtranspose_coloring_view - Activates basic viewing or coloring
10354: . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
10355: - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
10357: Level: intermediate
10359: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10361: .keywords: coloring
10362: @*/
10363: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10364: {
10372: if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10373: (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
10374: return(0);
10375: }
10379: /*@C
10380: MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10382: Collective on Mat
10384: Input Parameters:
10385: + mat - the matrix product C
10386: - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10388: Output Parameter:
10389: . color - the new coloring context
10391: Level: intermediate
10393: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
10394: MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
10395: @*/
10396: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10397: {
10398: MatTransposeColoring c;
10399: MPI_Comm comm;
10400: PetscErrorCode ierr;
10403: PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
10404: PetscObjectGetComm((PetscObject)mat,&comm);
10405: PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);
10407: c->ctype = iscoloring->ctype;
10408: if (mat->ops->transposecoloringcreate) {
10409: (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
10410: } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10412: *color = c;
10413: PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
10414: return(0);
10415: }
10419: /*@
10420: MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10421: matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10422: same, otherwise it will be larger
10424: Not Collective
10426: Input Parameter:
10427: . A - the matrix
10429: Output Parameter:
10430: . state - the current state
10432: Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10433: different matrices
10435: Level: intermediate
10437: @*/
10438: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10439: {
10442: *state = mat->nonzerostate;
10443: return(0);
10444: }
10448: /*@
10449: MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10450: matrices from each processor
10452: Collective on MPI_Comm
10454: Input Parameters:
10455: + comm - the communicators the parallel matrix will live on
10456: . seqmat - the input sequential matrices
10457: . n - number of local columns (or PETSC_DECIDE)
10458: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10460: Output Parameter:
10461: . mpimat - the parallel matrix generated
10463: Level: advanced
10465: Notes: The number of columns of the matrix in EACH processor MUST be the same.
10467: @*/
10468: PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10469: {
10471: PetscMPIInt size;
10474: MPI_Comm_size(comm,&size);
10475: if (size == 1) {
10476: if (reuse == MAT_INITIAL_MATRIX) {
10477: MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);
10478: } else {
10479: MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);
10480: }
10481: return(0);
10482: }
10484: if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10485: PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);
10486: (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);
10487: PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);
10488: return(0);
10489: }
10493: /*@
10494: MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10495: ranks' ownership ranges.
10497: Collective on A
10499: Input Parameters:
10500: + A - the matrix to create subdomains from
10501: - N - requested number of subdomains
10504: Output Parameters:
10505: + n - number of subdomains resulting on this rank
10506: - iss - IS list with indices of subdomains on this rank
10508: Level: advanced
10510: Notes: number of subdomains must be smaller than the communicator size
10511: @*/
10512: PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10513: {
10514: MPI_Comm comm,subcomm;
10515: PetscMPIInt size,rank,color;
10516: PetscInt rstart,rend,k;
10517: PetscErrorCode ierr;
10520: PetscObjectGetComm((PetscObject)A,&comm);
10521: MPI_Comm_size(comm,&size);
10522: MPI_Comm_rank(comm,&rank);
10523: 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);
10524: *n = 1;
10525: k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10526: color = rank/k;
10527: MPI_Comm_split(comm,color,rank,&subcomm);
10528: PetscMalloc1(1,iss);
10529: MatGetOwnershipRange(A,&rstart,&rend);
10530: ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);
10531: MPI_Comm_free(&subcomm);
10532: return(0);
10533: }