1 /*
2 This is where the abstract matrix operations are defined
3 */
4
5 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/
6 #include <petsc/private/isimpl.h>
7 #include <petsc/private/vecimpl.h>
8
9 /* Logging support */
10 PetscClassId MAT_CLASSID;
11 PetscClassId MAT_COLORING_CLASSID;
12 PetscClassId MAT_FDCOLORING_CLASSID;
13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
14
15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
16 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
20 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
21 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
22 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
23 PetscLogEvent MAT_TransposeColoringCreate;
24 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
25 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
26 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
27 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
28 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
29 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
30 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols;
31 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
32 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
33 PetscLogEvent MAT_GetMultiProcBlock;
34 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_CUSPARSEGenerateTranspose, MAT_SetValuesBatch;
35 PetscLogEvent MAT_ViennaCLCopyToGPU;
36 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS;
39 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
40
41 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",NULL};
42
43 /*@
44 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations,
45 for sparse matrices that already have locations it fills the locations with random numbers
46
47 Logically Collective on Mat
48
49 Input Parameters:
50 + x - the matrix
51 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and
52 it will create one internally.
53
54 Output Parameter:
55 . x - the matrix
56
57 Example of Usage:
58 .vb
59 PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
60 MatSetRandom(x,rctx);
61 PetscRandomDestroy(rctx);
62 .ve
63
64 Level: intermediate
65
66
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
MatSetRandom(Mat x,PetscRandom rctx)69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71 PetscErrorCode ierr;
72 PetscRandom randObj = NULL;
73
74 PetscFunctionBegin;
75 PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77 PetscValidType(x,1);
78
79 if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80
81 if (!rctx) {
82 MPI_Comm comm;
83 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86 rctx = randObj;
87 }
88
89 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92
93 ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94 ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96 PetscFunctionReturn(0);
97 }
98
99 /*@
100 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101
102 Logically Collective on Mat
103
104 Input Parameters:
105 . mat - the factored matrix
106
107 Output Parameter:
108 + pivot - the pivot value computed
109 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110 the share the matrix
111
112 Level: advanced
113
114 Notes:
115 This routine does not work for factorizations done with external packages.
116
117 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
118
119 This can be called on non-factored matrices that come from, for example, matrices used in SOR.
120
121 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
122 @*/
MatFactorGetErrorZeroPivot(Mat mat,PetscReal * pivot,PetscInt * row)123 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
124 {
125 PetscFunctionBegin;
126 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
127 *pivot = mat->factorerror_zeropivot_value;
128 *row = mat->factorerror_zeropivot_row;
129 PetscFunctionReturn(0);
130 }
131
132 /*@
133 MatFactorGetError - gets the error code from a factorization
134
135 Logically Collective on Mat
136
137 Input Parameters:
138 . mat - the factored matrix
139
140 Output Parameter:
141 . err - the error code
142
143 Level: advanced
144
145 Notes:
146 This can be called on non-factored matrices that come from, for example, matrices used in SOR.
147
148 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
149 @*/
MatFactorGetError(Mat mat,MatFactorError * err)150 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
151 {
152 PetscFunctionBegin;
153 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
154 *err = mat->factorerrortype;
155 PetscFunctionReturn(0);
156 }
157
158 /*@
159 MatFactorClearError - clears the error code in a factorization
160
161 Logically Collective on Mat
162
163 Input Parameter:
164 . mat - the factored matrix
165
166 Level: developer
167
168 Notes:
169 This can be called on non-factored matrices that come from, for example, matrices used in SOR.
170
171 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
172 @*/
MatFactorClearError(Mat mat)173 PetscErrorCode MatFactorClearError(Mat mat)
174 {
175 PetscFunctionBegin;
176 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
177 mat->factorerrortype = MAT_FACTOR_NOERROR;
178 mat->factorerror_zeropivot_value = 0.0;
179 mat->factorerror_zeropivot_row = 0;
180 PetscFunctionReturn(0);
181 }
182
MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS * nonzero)183 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
184 {
185 PetscErrorCode ierr;
186 Vec r,l;
187 const PetscScalar *al;
188 PetscInt i,nz,gnz,N,n;
189
190 PetscFunctionBegin;
191 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
192 if (!cols) { /* nonzero rows */
193 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
194 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
195 ierr = VecSet(l,0.0);CHKERRQ(ierr);
196 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
197 ierr = MatMult(mat,r,l);CHKERRQ(ierr);
198 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
199 } else { /* nonzero columns */
200 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
201 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
202 ierr = VecSet(r,0.0);CHKERRQ(ierr);
203 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
204 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
205 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
206 }
207 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
208 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
209 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
210 if (gnz != N) {
211 PetscInt *nzr;
212 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
213 if (nz) {
214 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
215 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
216 }
217 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
218 } else *nonzero = NULL;
219 if (!cols) { /* nonzero rows */
220 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
221 } else {
222 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
223 }
224 ierr = VecDestroy(&l);CHKERRQ(ierr);
225 ierr = VecDestroy(&r);CHKERRQ(ierr);
226 PetscFunctionReturn(0);
227 }
228
229 /*@
230 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
231
232 Input Parameter:
233 . A - the matrix
234
235 Output Parameter:
236 . keptrows - the rows that are not completely zero
237
238 Notes:
239 keptrows is set to NULL if all rows are nonzero.
240
241 Level: intermediate
242
243 @*/
MatFindNonzeroRows(Mat mat,IS * keptrows)244 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
245 {
246 PetscErrorCode ierr;
247
248 PetscFunctionBegin;
249 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
250 PetscValidType(mat,1);
251 PetscValidPointer(keptrows,2);
252 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
253 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
254 if (!mat->ops->findnonzerorows) {
255 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
256 } else {
257 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
258 }
259 PetscFunctionReturn(0);
260 }
261
262 /*@
263 MatFindZeroRows - Locate all rows that are completely zero in the matrix
264
265 Input Parameter:
266 . A - the matrix
267
268 Output Parameter:
269 . zerorows - the rows that are completely zero
270
271 Notes:
272 zerorows is set to NULL if no rows are zero.
273
274 Level: intermediate
275
276 @*/
MatFindZeroRows(Mat mat,IS * zerorows)277 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
278 {
279 PetscErrorCode ierr;
280 IS keptrows;
281 PetscInt m, n;
282
283 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
284 PetscValidType(mat,1);
285
286 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
287 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
288 In keeping with this convention, we set zerorows to NULL if there are no zero
289 rows. */
290 if (keptrows == NULL) {
291 *zerorows = NULL;
292 } else {
293 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
294 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
295 ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
296 }
297 PetscFunctionReturn(0);
298 }
299
300 /*@
301 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
302
303 Not Collective
304
305 Input Parameters:
306 . A - the matrix
307
308 Output Parameters:
309 . a - the diagonal part (which is a SEQUENTIAL matrix)
310
311 Notes:
312 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
313 Use caution, as the reference count on the returned matrix is not incremented and it is used as
314 part of the containing MPI Mat's normal operation.
315
316 Level: advanced
317
318 @*/
MatGetDiagonalBlock(Mat A,Mat * a)319 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
320 {
321 PetscErrorCode ierr;
322
323 PetscFunctionBegin;
324 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
325 PetscValidType(A,1);
326 PetscValidPointer(a,3);
327 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
328 if (!A->ops->getdiagonalblock) {
329 PetscMPIInt size;
330 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
331 if (size == 1) {
332 *a = A;
333 PetscFunctionReturn(0);
334 } else SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for matrix type %s",((PetscObject)A)->type_name);
335 }
336 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
337 PetscFunctionReturn(0);
338 }
339
340 /*@
341 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
342
343 Collective on Mat
344
345 Input Parameters:
346 . mat - the matrix
347
348 Output Parameter:
349 . trace - the sum of the diagonal entries
350
351 Level: advanced
352
353 @*/
MatGetTrace(Mat mat,PetscScalar * trace)354 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
355 {
356 PetscErrorCode ierr;
357 Vec diag;
358
359 PetscFunctionBegin;
360 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
361 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
362 ierr = VecSum(diag,trace);CHKERRQ(ierr);
363 ierr = VecDestroy(&diag);CHKERRQ(ierr);
364 PetscFunctionReturn(0);
365 }
366
367 /*@
368 MatRealPart - Zeros out the imaginary part of the matrix
369
370 Logically Collective on Mat
371
372 Input Parameters:
373 . mat - the matrix
374
375 Level: advanced
376
377
378 .seealso: MatImaginaryPart()
379 @*/
MatRealPart(Mat mat)380 PetscErrorCode MatRealPart(Mat mat)
381 {
382 PetscErrorCode ierr;
383
384 PetscFunctionBegin;
385 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
386 PetscValidType(mat,1);
387 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
388 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
389 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
390 MatCheckPreallocated(mat,1);
391 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
392 PetscFunctionReturn(0);
393 }
394
395 /*@C
396 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
397
398 Collective on Mat
399
400 Input Parameter:
401 . mat - the matrix
402
403 Output Parameters:
404 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
405 - ghosts - the global indices of the ghost points
406
407 Notes:
408 the nghosts and ghosts are suitable to pass into VecCreateGhost()
409
410 Level: advanced
411
412 @*/
MatGetGhosts(Mat mat,PetscInt * nghosts,const PetscInt * ghosts[])413 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
414 {
415 PetscErrorCode ierr;
416
417 PetscFunctionBegin;
418 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
419 PetscValidType(mat,1);
420 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
421 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
422 if (!mat->ops->getghosts) {
423 if (nghosts) *nghosts = 0;
424 if (ghosts) *ghosts = NULL;
425 } else {
426 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
427 }
428 PetscFunctionReturn(0);
429 }
430
431
432 /*@
433 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
434
435 Logically Collective on Mat
436
437 Input Parameters:
438 . mat - the matrix
439
440 Level: advanced
441
442
443 .seealso: MatRealPart()
444 @*/
MatImaginaryPart(Mat mat)445 PetscErrorCode MatImaginaryPart(Mat mat)
446 {
447 PetscErrorCode ierr;
448
449 PetscFunctionBegin;
450 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
451 PetscValidType(mat,1);
452 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
453 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
454 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
455 MatCheckPreallocated(mat,1);
456 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
457 PetscFunctionReturn(0);
458 }
459
460 /*@
461 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
462
463 Not Collective
464
465 Input Parameter:
466 . mat - the matrix
467
468 Output Parameters:
469 + missing - is any diagonal missing
470 - dd - first diagonal entry that is missing (optional) on this process
471
472 Level: advanced
473
474
475 .seealso: MatRealPart()
476 @*/
MatMissingDiagonal(Mat mat,PetscBool * missing,PetscInt * dd)477 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
478 {
479 PetscErrorCode ierr;
480
481 PetscFunctionBegin;
482 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
483 PetscValidType(mat,1);
484 PetscValidPointer(missing,2);
485 if (!mat->assembled) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name);
486 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
487 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
488 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
489 PetscFunctionReturn(0);
490 }
491
492 /*@C
493 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
494 for each row that you get to ensure that your application does
495 not bleed memory.
496
497 Not Collective
498
499 Input Parameters:
500 + mat - the matrix
501 - row - the row to get
502
503 Output Parameters:
504 + ncols - if not NULL, the number of nonzeros in the row
505 . cols - if not NULL, the column numbers
506 - vals - if not NULL, the values
507
508 Notes:
509 This routine is provided for people who need to have direct access
510 to the structure of a matrix. We hope that we provide enough
511 high-level matrix routines that few users will need it.
512
513 MatGetRow() always returns 0-based column indices, regardless of
514 whether the internal representation is 0-based (default) or 1-based.
515
516 For better efficiency, set cols and/or vals to NULL if you do
517 not wish to extract these quantities.
518
519 The user can only examine the values extracted with MatGetRow();
520 the values cannot be altered. To change the matrix entries, one
521 must use MatSetValues().
522
523 You can only have one call to MatGetRow() outstanding for a particular
524 matrix at a time, per processor. MatGetRow() can only obtain rows
525 associated with the given processor, it cannot get rows from the
526 other processors; for that we suggest using MatCreateSubMatrices(), then
527 MatGetRow() on the submatrix. The row index passed to MatGetRow()
528 is in the global number of rows.
529
530 Fortran Notes:
531 The calling sequence from Fortran is
532 .vb
533 MatGetRow(matrix,row,ncols,cols,values,ierr)
534 Mat matrix (input)
535 integer row (input)
536 integer ncols (output)
537 integer cols(maxcols) (output)
538 double precision (or double complex) values(maxcols) output
539 .ve
540 where maxcols >= maximum nonzeros in any row of the matrix.
541
542
543 Caution:
544 Do not try to change the contents of the output arrays (cols and vals).
545 In some cases, this may corrupt the matrix.
546
547 Level: advanced
548
549 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
550 @*/
MatGetRow(Mat mat,PetscInt row,PetscInt * ncols,const PetscInt * cols[],const PetscScalar * vals[])551 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
552 {
553 PetscErrorCode ierr;
554 PetscInt incols;
555
556 PetscFunctionBegin;
557 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
558 PetscValidType(mat,1);
559 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
560 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
561 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
562 MatCheckPreallocated(mat,1);
563 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
564 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
565 if (ncols) *ncols = incols;
566 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
567 PetscFunctionReturn(0);
568 }
569
570 /*@
571 MatConjugate - replaces the matrix values with their complex conjugates
572
573 Logically Collective on Mat
574
575 Input Parameters:
576 . mat - the matrix
577
578 Level: advanced
579
580 .seealso: VecConjugate()
581 @*/
MatConjugate(Mat mat)582 PetscErrorCode MatConjugate(Mat mat)
583 {
584 #if defined(PETSC_USE_COMPLEX)
585 PetscErrorCode ierr;
586
587 PetscFunctionBegin;
588 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
589 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
590 if (!mat->ops->conjugate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name);
591 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
592 #else
593 PetscFunctionBegin;
594 #endif
595 PetscFunctionReturn(0);
596 }
597
598 /*@C
599 MatRestoreRow - Frees any temporary space allocated by MatGetRow().
600
601 Not Collective
602
603 Input Parameters:
604 + mat - the matrix
605 . row - the row to get
606 . ncols, cols - the number of nonzeros and their columns
607 - vals - if nonzero the column values
608
609 Notes:
610 This routine should be called after you have finished examining the entries.
611
612 This routine zeros out ncols, cols, and vals. This is to prevent accidental
613 us of the array after it has been restored. If you pass NULL, it will
614 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid.
615
616 Fortran Notes:
617 The calling sequence from Fortran is
618 .vb
619 MatRestoreRow(matrix,row,ncols,cols,values,ierr)
620 Mat matrix (input)
621 integer row (input)
622 integer ncols (output)
623 integer cols(maxcols) (output)
624 double precision (or double complex) values(maxcols) output
625 .ve
626 Where maxcols >= maximum nonzeros in any row of the matrix.
627
628 In Fortran MatRestoreRow() MUST be called after MatGetRow()
629 before another call to MatGetRow() can be made.
630
631 Level: advanced
632
633 .seealso: MatGetRow()
634 @*/
MatRestoreRow(Mat mat,PetscInt row,PetscInt * ncols,const PetscInt * cols[],const PetscScalar * vals[])635 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
636 {
637 PetscErrorCode ierr;
638
639 PetscFunctionBegin;
640 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
641 if (ncols) PetscValidIntPointer(ncols,3);
642 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
643 if (!mat->ops->restorerow) PetscFunctionReturn(0);
644 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
645 if (ncols) *ncols = 0;
646 if (cols) *cols = NULL;
647 if (vals) *vals = NULL;
648 PetscFunctionReturn(0);
649 }
650
651 /*@
652 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
653 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
654
655 Not Collective
656
657 Input Parameters:
658 . mat - the matrix
659
660 Notes:
661 The flag is to ensure that users are aware of MatGetRow() only provides the upper triangular part of the row for the matrices in MATSBAIJ format.
662
663 Level: advanced
664
665 .seealso: MatRestoreRowUpperTriangular()
666 @*/
MatGetRowUpperTriangular(Mat mat)667 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
668 {
669 PetscErrorCode ierr;
670
671 PetscFunctionBegin;
672 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
673 PetscValidType(mat,1);
674 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
675 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
676 MatCheckPreallocated(mat,1);
677 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0);
678 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
679 PetscFunctionReturn(0);
680 }
681
682 /*@
683 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
684
685 Not Collective
686
687 Input Parameters:
688 . mat - the matrix
689
690 Notes:
691 This routine should be called after you have finished MatGetRow/MatRestoreRow().
692
693
694 Level: advanced
695
696 .seealso: MatGetRowUpperTriangular()
697 @*/
MatRestoreRowUpperTriangular(Mat mat)698 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
699 {
700 PetscErrorCode ierr;
701
702 PetscFunctionBegin;
703 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
704 PetscValidType(mat,1);
705 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
706 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
707 MatCheckPreallocated(mat,1);
708 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
709 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
710 PetscFunctionReturn(0);
711 }
712
713 /*@C
714 MatSetOptionsPrefix - Sets the prefix used for searching for all
715 Mat options in the database.
716
717 Logically Collective on Mat
718
719 Input Parameter:
720 + A - the Mat context
721 - prefix - the prefix to prepend to all option names
722
723 Notes:
724 A hyphen (-) must NOT be given at the beginning of the prefix name.
725 The first character of all runtime options is AUTOMATICALLY the hyphen.
726
727 Level: advanced
728
729 .seealso: MatSetFromOptions()
730 @*/
MatSetOptionsPrefix(Mat A,const char prefix[])731 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
732 {
733 PetscErrorCode ierr;
734
735 PetscFunctionBegin;
736 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
737 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
738 PetscFunctionReturn(0);
739 }
740
741 /*@C
742 MatAppendOptionsPrefix - Appends to the prefix used for searching for all
743 Mat options in the database.
744
745 Logically Collective on Mat
746
747 Input Parameters:
748 + A - the Mat context
749 - prefix - the prefix to prepend to all option names
750
751 Notes:
752 A hyphen (-) must NOT be given at the beginning of the prefix name.
753 The first character of all runtime options is AUTOMATICALLY the hyphen.
754
755 Level: advanced
756
757 .seealso: MatGetOptionsPrefix()
758 @*/
MatAppendOptionsPrefix(Mat A,const char prefix[])759 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
760 {
761 PetscErrorCode ierr;
762
763 PetscFunctionBegin;
764 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
765 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
766 PetscFunctionReturn(0);
767 }
768
769 /*@C
770 MatGetOptionsPrefix - Gets the prefix used for searching for all
771 Mat options in the database.
772
773 Not Collective
774
775 Input Parameter:
776 . A - the Mat context
777
778 Output Parameter:
779 . prefix - pointer to the prefix string used
780
781 Notes:
782 On the fortran side, the user should pass in a string 'prefix' of
783 sufficient length to hold the prefix.
784
785 Level: advanced
786
787 .seealso: MatAppendOptionsPrefix()
788 @*/
MatGetOptionsPrefix(Mat A,const char * prefix[])789 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
790 {
791 PetscErrorCode ierr;
792
793 PetscFunctionBegin;
794 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
795 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
796 PetscFunctionReturn(0);
797 }
798
799 /*@
800 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
801
802 Collective on Mat
803
804 Input Parameters:
805 . A - the Mat context
806
807 Notes:
808 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
809 Currently support MPIAIJ and SEQAIJ.
810
811 Level: beginner
812
813 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
814 @*/
MatResetPreallocation(Mat A)815 PetscErrorCode MatResetPreallocation(Mat A)
816 {
817 PetscErrorCode ierr;
818
819 PetscFunctionBegin;
820 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
821 PetscValidType(A,1);
822 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
823 PetscFunctionReturn(0);
824 }
825
826
827 /*@
828 MatSetUp - Sets up the internal matrix data structures for later use.
829
830 Collective on Mat
831
832 Input Parameters:
833 . A - the Mat context
834
835 Notes:
836 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
837
838 If a suitable preallocation routine is used, this function does not need to be called.
839
840 See the Performance chapter of the PETSc users manual for how to preallocate matrices
841
842 Level: beginner
843
844 .seealso: MatCreate(), MatDestroy()
845 @*/
MatSetUp(Mat A)846 PetscErrorCode MatSetUp(Mat A)
847 {
848 PetscMPIInt size;
849 PetscErrorCode ierr;
850
851 PetscFunctionBegin;
852 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
853 if (!((PetscObject)A)->type_name) {
854 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
855 if (size == 1) {
856 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
857 } else {
858 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
859 }
860 }
861 if (!A->preallocated && A->ops->setup) {
862 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
863 ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
864 }
865 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
866 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
867 A->preallocated = PETSC_TRUE;
868 PetscFunctionReturn(0);
869 }
870
871 #if defined(PETSC_HAVE_SAWS)
872 #include <petscviewersaws.h>
873 #endif
874
875 /*@C
876 MatViewFromOptions - View from Options
877
878 Collective on Mat
879
880 Input Parameters:
881 + A - the Mat context
882 . obj - Optional object
883 - name - command line option
884
885 Level: intermediate
886 .seealso: Mat, MatView, PetscObjectViewFromOptions(), MatCreate()
887 @*/
MatViewFromOptions(Mat A,PetscObject obj,const char name[])888 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[])
889 {
890 PetscErrorCode ierr;
891
892 PetscFunctionBegin;
893 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
894 ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr);
895 PetscFunctionReturn(0);
896 }
897
898 /*@C
899 MatView - Visualizes a matrix object.
900
901 Collective on Mat
902
903 Input Parameters:
904 + mat - the matrix
905 - viewer - visualization context
906
907 Notes:
908 The available visualization contexts include
909 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices
910 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
911 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
912 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
913
914 The user can open alternative visualization contexts with
915 + PetscViewerASCIIOpen() - Outputs matrix to a specified file
916 . PetscViewerBinaryOpen() - Outputs matrix in binary to a
917 specified file; corresponding input uses MatLoad()
918 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
919 an X window display
920 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
921 Currently only the sequential dense and AIJ
922 matrix types support the Socket viewer.
923
924 The user can call PetscViewerPushFormat() to specify the output
925 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
926 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
927 + PETSC_VIEWER_DEFAULT - default, prints matrix contents
928 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
929 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
930 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
931 format common among all matrix types
932 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
933 format (which is in many cases the same as the default)
934 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
935 size and structure (not the matrix entries)
936 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
937 the matrix structure
938
939 Options Database Keys:
940 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
941 . -mat_view ::ascii_info_detail - Prints more detailed info
942 . -mat_view - Prints matrix in ASCII format
943 . -mat_view ::ascii_matlab - Prints matrix in Matlab format
944 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
945 . -display <name> - Sets display name (default is host)
946 . -draw_pause <sec> - Sets number of seconds to pause after display
947 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
948 . -viewer_socket_machine <machine> -
949 . -viewer_socket_port <port> -
950 . -mat_view binary - save matrix to file in binary format
951 - -viewer_binary_filename <name> -
952 Level: beginner
953
954 Notes:
955 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
956 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
957
958 See the manual page for MatLoad() for the exact format of the binary file when the binary
959 viewer is used.
960
961 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
962 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python.
963
964 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
965 and then use the following mouse functions.
966 + left mouse: zoom in
967 . middle mouse: zoom out
968 - right mouse: continue with the simulation
969
970 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
971 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
972 @*/
MatView(Mat mat,PetscViewer viewer)973 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
974 {
975 PetscErrorCode ierr;
976 PetscInt rows,cols,rbs,cbs;
977 PetscBool isascii,isstring,issaws;
978 PetscViewerFormat format;
979 PetscMPIInt size;
980
981 PetscFunctionBegin;
982 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
983 PetscValidType(mat,1);
984 if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);}
985 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
986 PetscCheckSameComm(mat,1,viewer,2);
987 MatCheckPreallocated(mat,1);
988
989 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
990 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
991 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
992
993 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
994 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
995 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
996 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
997 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail");
998 }
999
1000 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1001 if (isascii) {
1002 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1003 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1004 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1005 MatNullSpace nullsp,transnullsp;
1006
1007 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1008 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1009 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1010 if (rbs != 1 || cbs != 1) {
1011 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs=%D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1012 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1013 } else {
1014 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1015 }
1016 if (mat->factortype) {
1017 MatSolverType solver;
1018 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1019 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1020 }
1021 if (mat->ops->getinfo) {
1022 MatInfo info;
1023 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1024 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1025 if (!mat->factortype) {
1026 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1027 }
1028 }
1029 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1030 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1031 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);}
1032 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);}
1033 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1034 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);}
1035 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1036 ierr = MatProductView(mat,viewer);CHKERRQ(ierr);
1037 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1038 }
1039 } else if (issaws) {
1040 #if defined(PETSC_HAVE_SAWS)
1041 PetscMPIInt rank;
1042
1043 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1044 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1045 if (!((PetscObject)mat)->amsmem && !rank) {
1046 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1047 }
1048 #endif
1049 } else if (isstring) {
1050 const char *type;
1051 ierr = MatGetType(mat,&type);CHKERRQ(ierr);
1052 ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr);
1053 if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);}
1054 }
1055 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1056 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1057 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1058 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1059 } else if (mat->ops->view) {
1060 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1061 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1062 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1063 }
1064 if (isascii) {
1065 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1066 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1067 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1068 }
1069 }
1070 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1071 PetscFunctionReturn(0);
1072 }
1073
1074 #if defined(PETSC_USE_DEBUG)
1075 #include <../src/sys/totalview/tv_data_display.h>
TV_display_type(const struct _p_Mat * mat)1076 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1077 {
1078 TV_add_row("Local rows", "int", &mat->rmap->n);
1079 TV_add_row("Local columns", "int", &mat->cmap->n);
1080 TV_add_row("Global rows", "int", &mat->rmap->N);
1081 TV_add_row("Global columns", "int", &mat->cmap->N);
1082 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1083 return TV_format_OK;
1084 }
1085 #endif
1086
1087 /*@C
1088 MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1089 with MatView(). The matrix format is determined from the options database.
1090 Generates a parallel MPI matrix if the communicator has more than one
1091 processor. The default matrix type is AIJ.
1092
1093 Collective on PetscViewer
1094
1095 Input Parameters:
1096 + mat - the newly loaded matrix, this needs to have been created with MatCreate()
1097 or some related function before a call to MatLoad()
1098 - viewer - binary/HDF5 file viewer
1099
1100 Options Database Keys:
1101 Used with block matrix formats (MATSEQBAIJ, ...) to specify
1102 block size
1103 . -matload_block_size <bs>
1104
1105 Level: beginner
1106
1107 Notes:
1108 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1109 Mat before calling this routine if you wish to set it from the options database.
1110
1111 MatLoad() automatically loads into the options database any options
1112 given in the file filename.info where filename is the name of the file
1113 that was passed to the PetscViewerBinaryOpen(). The options in the info
1114 file will be ignored if you use the -viewer_binary_skip_info option.
1115
1116 If the type or size of mat is not set before a call to MatLoad, PETSc
1117 sets the default matrix type AIJ and sets the local and global sizes.
1118 If type and/or size is already set, then the same are used.
1119
1120 In parallel, each processor can load a subset of rows (or the
1121 entire matrix). This routine is especially useful when a large
1122 matrix is stored on disk and only part of it is desired on each
1123 processor. For example, a parallel solver may access only some of
1124 the rows from each processor. The algorithm used here reads
1125 relatively small blocks of data rather than reading the entire
1126 matrix and then subsetting it.
1127
1128 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1129 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1130 or the sequence like
1131 $ PetscViewer v;
1132 $ PetscViewerCreate(PETSC_COMM_WORLD,&v);
1133 $ PetscViewerSetType(v,PETSCVIEWERBINARY);
1134 $ PetscViewerSetFromOptions(v);
1135 $ PetscViewerFileSetMode(v,FILE_MODE_READ);
1136 $ PetscViewerFileSetName(v,"datafile");
1137 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1138 $ -viewer_type {binary,hdf5}
1139
1140 See the example src/ksp/ksp/tutorials/ex27.c with the first approach,
1141 and src/mat/tutorials/ex10.c with the second approach.
1142
1143 Notes about the PETSc binary format:
1144 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1145 is read onto rank 0 and then shipped to its destination rank, one after another.
1146 Multiple objects, both matrices and vectors, can be stored within the same file.
1147 Their PetscObject name is ignored; they are loaded in the order of their storage.
1148
1149 Most users should not need to know the details of the binary storage
1150 format, since MatLoad() and MatView() completely hide these details.
1151 But for anyone who's interested, the standard binary matrix storage
1152 format is
1153
1154 $ PetscInt MAT_FILE_CLASSID
1155 $ PetscInt number of rows
1156 $ PetscInt number of columns
1157 $ PetscInt total number of nonzeros
1158 $ PetscInt *number nonzeros in each row
1159 $ PetscInt *column indices of all nonzeros (starting index is zero)
1160 $ PetscScalar *values of all nonzeros
1161
1162 PETSc automatically does the byte swapping for
1163 machines that store the bytes reversed, e.g. DEC alpha, freebsd,
1164 linux, Windows and the paragon; thus if you write your own binary
1165 read/write routines you have to swap the bytes; see PetscBinaryRead()
1166 and PetscBinaryWrite() to see how this may be done.
1167
1168 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1169 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1170 Each processor's chunk is loaded independently by its owning rank.
1171 Multiple objects, both matrices and vectors, can be stored within the same file.
1172 They are looked up by their PetscObject name.
1173
1174 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1175 by default the same structure and naming of the AIJ arrays and column count
1176 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1177 $ save example.mat A b -v7.3
1178 can be directly read by this routine (see Reference 1 for details).
1179 Note that depending on your MATLAB version, this format might be a default,
1180 otherwise you can set it as default in Preferences.
1181
1182 Unless -nocompression flag is used to save the file in MATLAB,
1183 PETSc must be configured with ZLIB package.
1184
1185 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c
1186
1187 Current HDF5 (MAT-File) limitations:
1188 This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices.
1189
1190 Corresponding MatView() is not yet implemented.
1191
1192 The loaded matrix is actually a transpose of the original one in MATLAB,
1193 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1194 With this format, matrix is automatically transposed by PETSc,
1195 unless the matrix is marked as SPD or symmetric
1196 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1197
1198 References:
1199 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1200
1201 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad()
1202
1203 @*/
MatLoad(Mat mat,PetscViewer viewer)1204 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer)
1205 {
1206 PetscErrorCode ierr;
1207 PetscBool flg;
1208
1209 PetscFunctionBegin;
1210 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1211 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1212
1213 if (!((PetscObject)mat)->type_name) {
1214 ierr = MatSetType(mat,MATAIJ);CHKERRQ(ierr);
1215 }
1216
1217 flg = PETSC_FALSE;
1218 ierr = PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1219 if (flg) {
1220 ierr = MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1221 ierr = MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1222 }
1223 flg = PETSC_FALSE;
1224 ierr = PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1225 if (flg) {
1226 ierr = MatSetOption(mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1227 }
1228
1229 if (!mat->ops->load) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name);
1230 ierr = PetscLogEventBegin(MAT_Load,mat,viewer,0,0);CHKERRQ(ierr);
1231 ierr = (*mat->ops->load)(mat,viewer);CHKERRQ(ierr);
1232 ierr = PetscLogEventEnd(MAT_Load,mat,viewer,0,0);CHKERRQ(ierr);
1233 PetscFunctionReturn(0);
1234 }
1235
MatDestroy_Redundant(Mat_Redundant ** redundant)1236 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1237 {
1238 PetscErrorCode ierr;
1239 Mat_Redundant *redund = *redundant;
1240 PetscInt i;
1241
1242 PetscFunctionBegin;
1243 if (redund){
1244 if (redund->matseq) { /* via MatCreateSubMatrices() */
1245 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1246 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1247 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1248 } else {
1249 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1250 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1251 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1252 for (i=0; i<redund->nrecvs; i++) {
1253 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1254 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1255 }
1256 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1257 }
1258
1259 if (redund->subcomm) {
1260 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1261 }
1262 ierr = PetscFree(redund);CHKERRQ(ierr);
1263 }
1264 PetscFunctionReturn(0);
1265 }
1266
1267 /*@
1268 MatDestroy - Frees space taken by a matrix.
1269
1270 Collective on Mat
1271
1272 Input Parameter:
1273 . A - the matrix
1274
1275 Level: beginner
1276
1277 @*/
MatDestroy(Mat * A)1278 PetscErrorCode MatDestroy(Mat *A)
1279 {
1280 PetscErrorCode ierr;
1281
1282 PetscFunctionBegin;
1283 if (!*A) PetscFunctionReturn(0);
1284 PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1285 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1286
1287 /* if memory was published with SAWs then destroy it */
1288 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1289 if ((*A)->ops->destroy) {
1290 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1291 }
1292
1293 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1294 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1295 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1296 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1297 ierr = MatProductClear(*A);CHKERRQ(ierr);
1298 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1299 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1300 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1301 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1302 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1303 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1304 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1305 PetscFunctionReturn(0);
1306 }
1307
1308 /*@C
1309 MatSetValues - Inserts or adds a block of values into a matrix.
1310 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1311 MUST be called after all calls to MatSetValues() have been completed.
1312
1313 Not Collective
1314
1315 Input Parameters:
1316 + mat - the matrix
1317 . v - a logically two-dimensional array of values
1318 . m, idxm - the number of rows and their global indices
1319 . n, idxn - the number of columns and their global indices
1320 - addv - either ADD_VALUES or INSERT_VALUES, where
1321 ADD_VALUES adds values to any existing entries, and
1322 INSERT_VALUES replaces existing entries with new values
1323
1324 Notes:
1325 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1326 MatSetUp() before using this routine
1327
1328 By default the values, v, are row-oriented. See MatSetOption() for other options.
1329
1330 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1331 options cannot be mixed without intervening calls to the assembly
1332 routines.
1333
1334 MatSetValues() uses 0-based row and column numbers in Fortran
1335 as well as in C.
1336
1337 Negative indices may be passed in idxm and idxn, these rows and columns are
1338 simply ignored. This allows easily inserting element stiffness matrices
1339 with homogeneous Dirchlet boundary conditions that you don't want represented
1340 in the matrix.
1341
1342 Efficiency Alert:
1343 The routine MatSetValuesBlocked() may offer much better efficiency
1344 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1345
1346 Level: beginner
1347
1348 Developer Notes:
1349 This is labeled with C so does not automatically generate Fortran stubs and interfaces
1350 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1351
1352 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1353 InsertMode, INSERT_VALUES, ADD_VALUES
1354 @*/
MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)1355 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1356 {
1357 PetscErrorCode ierr;
1358
1359 PetscFunctionBeginHot;
1360 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1361 PetscValidType(mat,1);
1362 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1363 PetscValidIntPointer(idxm,3);
1364 PetscValidIntPointer(idxn,5);
1365 MatCheckPreallocated(mat,1);
1366
1367 if (mat->insertmode == NOT_SET_VALUES) {
1368 mat->insertmode = addv;
1369 } else if (PetscUnlikely(mat->insertmode != addv)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1370 if (PetscDefined(USE_DEBUG)) {
1371 PetscInt i,j;
1372
1373 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1374 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1375
1376 for (i=0; i<m; i++) {
1377 for (j=0; j<n; j++) {
1378 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1379 #if defined(PETSC_USE_COMPLEX)
1380 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]);
1381 #else
1382 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1383 #endif
1384 }
1385 }
1386 }
1387
1388 if (mat->assembled) {
1389 mat->was_assembled = PETSC_TRUE;
1390 mat->assembled = PETSC_FALSE;
1391 }
1392 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1393 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1394 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1395 PetscFunctionReturn(0);
1396 }
1397
1398
1399 /*@
1400 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1401 values into a matrix
1402
1403 Not Collective
1404
1405 Input Parameters:
1406 + mat - the matrix
1407 . row - the (block) row to set
1408 - v - a logically two-dimensional array of values
1409
1410 Notes:
1411 By the values, v, are column-oriented (for the block version) and sorted
1412
1413 All the nonzeros in the row must be provided
1414
1415 The matrix must have previously had its column indices set
1416
1417 The row must belong to this process
1418
1419 Level: intermediate
1420
1421 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1422 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1423 @*/
MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])1424 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1425 {
1426 PetscErrorCode ierr;
1427 PetscInt globalrow;
1428
1429 PetscFunctionBegin;
1430 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1431 PetscValidType(mat,1);
1432 PetscValidScalarPointer(v,2);
1433 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1434 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1435 PetscFunctionReturn(0);
1436 }
1437
1438 /*@
1439 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1440 values into a matrix
1441
1442 Not Collective
1443
1444 Input Parameters:
1445 + mat - the matrix
1446 . row - the (block) row to set
1447 - v - a logically two-dimensional (column major) array of values for block matrices with blocksize larger than one, otherwise a one dimensional array of values
1448
1449 Notes:
1450 The values, v, are column-oriented for the block version.
1451
1452 All the nonzeros in the row must be provided
1453
1454 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1455
1456 The row must belong to this process
1457
1458 Level: advanced
1459
1460 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1461 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1462 @*/
MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])1463 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1464 {
1465 PetscErrorCode ierr;
1466
1467 PetscFunctionBeginHot;
1468 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1469 PetscValidType(mat,1);
1470 MatCheckPreallocated(mat,1);
1471 PetscValidScalarPointer(v,2);
1472 if (PetscUnlikely(mat->insertmode == ADD_VALUES)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1473 if (PetscUnlikely(mat->factortype)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1474 mat->insertmode = INSERT_VALUES;
1475
1476 if (mat->assembled) {
1477 mat->was_assembled = PETSC_TRUE;
1478 mat->assembled = PETSC_FALSE;
1479 }
1480 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1481 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1482 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1483 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1484 PetscFunctionReturn(0);
1485 }
1486
1487 /*@
1488 MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1489 Using structured grid indexing
1490
1491 Not Collective
1492
1493 Input Parameters:
1494 + mat - the matrix
1495 . m - number of rows being entered
1496 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1497 . n - number of columns being entered
1498 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1499 . v - a logically two-dimensional array of values
1500 - addv - either ADD_VALUES or INSERT_VALUES, where
1501 ADD_VALUES adds values to any existing entries, and
1502 INSERT_VALUES replaces existing entries with new values
1503
1504 Notes:
1505 By default the values, v, are row-oriented. See MatSetOption() for other options.
1506
1507 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1508 options cannot be mixed without intervening calls to the assembly
1509 routines.
1510
1511 The grid coordinates are across the entire grid, not just the local portion
1512
1513 MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1514 as well as in C.
1515
1516 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1517
1518 In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1519 or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1520
1521 The columns and rows in the stencil passed in MUST be contained within the
1522 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1523 if you create a DMDA with an overlap of one grid level and on a particular process its first
1524 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1525 first i index you can use in your column and row indices in MatSetStencil() is 5.
1526
1527 In Fortran idxm and idxn should be declared as
1528 $ MatStencil idxm(4,m),idxn(4,n)
1529 and the values inserted using
1530 $ idxm(MatStencil_i,1) = i
1531 $ idxm(MatStencil_j,1) = j
1532 $ idxm(MatStencil_k,1) = k
1533 $ idxm(MatStencil_c,1) = c
1534 etc
1535
1536 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1537 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1538 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1539 DM_BOUNDARY_PERIODIC boundary type.
1540
1541 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
1542 a single value per point) you can skip filling those indices.
1543
1544 Inspired by the structured grid interface to the HYPRE package
1545 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1546
1547 Efficiency Alert:
1548 The routine MatSetValuesBlockedStencil() may offer much better efficiency
1549 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1550
1551 Level: beginner
1552
1553 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1554 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1555 @*/
MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)1556 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1557 {
1558 PetscErrorCode ierr;
1559 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn;
1560 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1561 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1562
1563 PetscFunctionBegin;
1564 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1565 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1566 PetscValidType(mat,1);
1567 PetscValidIntPointer(idxm,3);
1568 PetscValidIntPointer(idxn,5);
1569
1570 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1571 jdxm = buf; jdxn = buf+m;
1572 } else {
1573 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1574 jdxm = bufm; jdxn = bufn;
1575 }
1576 for (i=0; i<m; i++) {
1577 for (j=0; j<3-sdim; j++) dxm++;
1578 tmp = *dxm++ - starts[0];
1579 for (j=0; j<dim-1; j++) {
1580 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1581 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1582 }
1583 if (mat->stencil.noc) dxm++;
1584 jdxm[i] = tmp;
1585 }
1586 for (i=0; i<n; i++) {
1587 for (j=0; j<3-sdim; j++) dxn++;
1588 tmp = *dxn++ - starts[0];
1589 for (j=0; j<dim-1; j++) {
1590 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1591 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1592 }
1593 if (mat->stencil.noc) dxn++;
1594 jdxn[i] = tmp;
1595 }
1596 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1597 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1598 PetscFunctionReturn(0);
1599 }
1600
1601 /*@
1602 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1603 Using structured grid indexing
1604
1605 Not Collective
1606
1607 Input Parameters:
1608 + mat - the matrix
1609 . m - number of rows being entered
1610 . idxm - grid coordinates for matrix rows being entered
1611 . n - number of columns being entered
1612 . idxn - grid coordinates for matrix columns being entered
1613 . v - a logically two-dimensional array of values
1614 - addv - either ADD_VALUES or INSERT_VALUES, where
1615 ADD_VALUES adds values to any existing entries, and
1616 INSERT_VALUES replaces existing entries with new values
1617
1618 Notes:
1619 By default the values, v, are row-oriented and unsorted.
1620 See MatSetOption() for other options.
1621
1622 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1623 options cannot be mixed without intervening calls to the assembly
1624 routines.
1625
1626 The grid coordinates are across the entire grid, not just the local portion
1627
1628 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1629 as well as in C.
1630
1631 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1632
1633 In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1634 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1635
1636 The columns and rows in the stencil passed in MUST be contained within the
1637 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1638 if you create a DMDA with an overlap of one grid level and on a particular process its first
1639 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1640 first i index you can use in your column and row indices in MatSetStencil() is 5.
1641
1642 In Fortran idxm and idxn should be declared as
1643 $ MatStencil idxm(4,m),idxn(4,n)
1644 and the values inserted using
1645 $ idxm(MatStencil_i,1) = i
1646 $ idxm(MatStencil_j,1) = j
1647 $ idxm(MatStencil_k,1) = k
1648 etc
1649
1650 Negative indices may be passed in idxm and idxn, these rows and columns are
1651 simply ignored. This allows easily inserting element stiffness matrices
1652 with homogeneous Dirchlet boundary conditions that you don't want represented
1653 in the matrix.
1654
1655 Inspired by the structured grid interface to the HYPRE package
1656 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1657
1658 Level: beginner
1659
1660 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1661 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1662 MatSetBlockSize(), MatSetLocalToGlobalMapping()
1663 @*/
MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)1664 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1665 {
1666 PetscErrorCode ierr;
1667 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn;
1668 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1669 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1670
1671 PetscFunctionBegin;
1672 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1673 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1674 PetscValidType(mat,1);
1675 PetscValidIntPointer(idxm,3);
1676 PetscValidIntPointer(idxn,5);
1677 PetscValidScalarPointer(v,6);
1678
1679 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1680 jdxm = buf; jdxn = buf+m;
1681 } else {
1682 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1683 jdxm = bufm; jdxn = bufn;
1684 }
1685 for (i=0; i<m; i++) {
1686 for (j=0; j<3-sdim; j++) dxm++;
1687 tmp = *dxm++ - starts[0];
1688 for (j=0; j<sdim-1; j++) {
1689 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1690 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1691 }
1692 dxm++;
1693 jdxm[i] = tmp;
1694 }
1695 for (i=0; i<n; i++) {
1696 for (j=0; j<3-sdim; j++) dxn++;
1697 tmp = *dxn++ - starts[0];
1698 for (j=0; j<sdim-1; j++) {
1699 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1700 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1701 }
1702 dxn++;
1703 jdxn[i] = tmp;
1704 }
1705 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1706 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1707 PetscFunctionReturn(0);
1708 }
1709
1710 /*@
1711 MatSetStencil - Sets the grid information for setting values into a matrix via
1712 MatSetValuesStencil()
1713
1714 Not Collective
1715
1716 Input Parameters:
1717 + mat - the matrix
1718 . dim - dimension of the grid 1, 2, or 3
1719 . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1720 . starts - starting point of ghost nodes on your processor in x, y, and z direction
1721 - dof - number of degrees of freedom per node
1722
1723
1724 Inspired by the structured grid interface to the HYPRE package
1725 (www.llnl.gov/CASC/hyper)
1726
1727 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1728 user.
1729
1730 Level: beginner
1731
1732 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1733 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1734 @*/
MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)1735 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1736 {
1737 PetscInt i;
1738
1739 PetscFunctionBegin;
1740 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1741 PetscValidIntPointer(dims,3);
1742 PetscValidIntPointer(starts,4);
1743
1744 mat->stencil.dim = dim + (dof > 1);
1745 for (i=0; i<dim; i++) {
1746 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1747 mat->stencil.starts[i] = starts[dim-i-1];
1748 }
1749 mat->stencil.dims[dim] = dof;
1750 mat->stencil.starts[dim] = 0;
1751 mat->stencil.noc = (PetscBool)(dof == 1);
1752 PetscFunctionReturn(0);
1753 }
1754
1755 /*@C
1756 MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1757
1758 Not Collective
1759
1760 Input Parameters:
1761 + mat - the matrix
1762 . v - a logically two-dimensional array of values
1763 . m, idxm - the number of block rows and their global block indices
1764 . n, idxn - the number of block columns and their global block indices
1765 - addv - either ADD_VALUES or INSERT_VALUES, where
1766 ADD_VALUES adds values to any existing entries, and
1767 INSERT_VALUES replaces existing entries with new values
1768
1769 Notes:
1770 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1771 MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1772
1773 The m and n count the NUMBER of blocks in the row direction and column direction,
1774 NOT the total number of rows/columns; for example, if the block size is 2 and
1775 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1776 The values in idxm would be 1 2; that is the first index for each block divided by
1777 the block size.
1778
1779 Note that you must call MatSetBlockSize() when constructing this matrix (before
1780 preallocating it).
1781
1782 By default the values, v, are row-oriented, so the layout of
1783 v is the same as for MatSetValues(). See MatSetOption() for other options.
1784
1785 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1786 options cannot be mixed without intervening calls to the assembly
1787 routines.
1788
1789 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1790 as well as in C.
1791
1792 Negative indices may be passed in idxm and idxn, these rows and columns are
1793 simply ignored. This allows easily inserting element stiffness matrices
1794 with homogeneous Dirchlet boundary conditions that you don't want represented
1795 in the matrix.
1796
1797 Each time an entry is set within a sparse matrix via MatSetValues(),
1798 internal searching must be done to determine where to place the
1799 data in the matrix storage space. By instead inserting blocks of
1800 entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1801 reduced.
1802
1803 Example:
1804 $ Suppose m=n=2 and block size(bs) = 2 The array is
1805 $
1806 $ 1 2 | 3 4
1807 $ 5 6 | 7 8
1808 $ - - - | - - -
1809 $ 9 10 | 11 12
1810 $ 13 14 | 15 16
1811 $
1812 $ v[] should be passed in like
1813 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1814 $
1815 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1816 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1817
1818 Level: intermediate
1819
1820 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1821 @*/
MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)1822 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1823 {
1824 PetscErrorCode ierr;
1825
1826 PetscFunctionBeginHot;
1827 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1828 PetscValidType(mat,1);
1829 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1830 PetscValidIntPointer(idxm,3);
1831 PetscValidIntPointer(idxn,5);
1832 PetscValidScalarPointer(v,6);
1833 MatCheckPreallocated(mat,1);
1834 if (mat->insertmode == NOT_SET_VALUES) {
1835 mat->insertmode = addv;
1836 } else if (PetscUnlikely(mat->insertmode != addv)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1837 if (PetscDefined(USE_DEBUG)) {
1838 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1839 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1840 }
1841
1842 if (mat->assembled) {
1843 mat->was_assembled = PETSC_TRUE;
1844 mat->assembled = PETSC_FALSE;
1845 }
1846 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1847 if (mat->ops->setvaluesblocked) {
1848 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1849 } else {
1850 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn;
1851 PetscInt i,j,bs,cbs;
1852 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1853 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1854 iidxm = buf; iidxn = buf + m*bs;
1855 } else {
1856 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1857 iidxm = bufr; iidxn = bufc;
1858 }
1859 for (i=0; i<m; i++) {
1860 for (j=0; j<bs; j++) {
1861 iidxm[i*bs+j] = bs*idxm[i] + j;
1862 }
1863 }
1864 for (i=0; i<n; i++) {
1865 for (j=0; j<cbs; j++) {
1866 iidxn[i*cbs+j] = cbs*idxn[i] + j;
1867 }
1868 }
1869 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1870 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1871 }
1872 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1873 PetscFunctionReturn(0);
1874 }
1875
1876 /*@C
1877 MatGetValues - Gets a block of values from a matrix.
1878
1879 Not Collective; currently only returns a local block
1880
1881 Input Parameters:
1882 + mat - the matrix
1883 . v - a logically two-dimensional array for storing the values
1884 . m, idxm - the number of rows and their global indices
1885 - n, idxn - the number of columns and their global indices
1886
1887 Notes:
1888 The user must allocate space (m*n PetscScalars) for the values, v.
1889 The values, v, are then returned in a row-oriented format,
1890 analogous to that used by default in MatSetValues().
1891
1892 MatGetValues() uses 0-based row and column numbers in
1893 Fortran as well as in C.
1894
1895 MatGetValues() requires that the matrix has been assembled
1896 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1897 MatSetValues() and MatGetValues() CANNOT be made in succession
1898 without intermediate matrix assembly.
1899
1900 Negative row or column indices will be ignored and those locations in v[] will be
1901 left unchanged.
1902
1903 Level: advanced
1904
1905 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1906 @*/
MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])1907 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1908 {
1909 PetscErrorCode ierr;
1910
1911 PetscFunctionBegin;
1912 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1913 PetscValidType(mat,1);
1914 if (!m || !n) PetscFunctionReturn(0);
1915 PetscValidIntPointer(idxm,3);
1916 PetscValidIntPointer(idxn,5);
1917 PetscValidScalarPointer(v,6);
1918 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1919 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1920 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1921 MatCheckPreallocated(mat,1);
1922
1923 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1924 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1925 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1926 PetscFunctionReturn(0);
1927 }
1928
1929 /*@C
1930 MatGetValuesLocal - retrieves values into certain locations of a matrix,
1931 using a local numbering of the nodes.
1932
1933 Not Collective
1934
1935 Input Parameters:
1936 + mat - the matrix
1937 . nrow, irow - number of rows and their local indices
1938 - ncol, icol - number of columns and their local indices
1939
1940 Output Parameter:
1941 . y - a logically two-dimensional array of values
1942
1943 Notes:
1944 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
1945
1946 Level: advanced
1947
1948 Developer Notes:
1949 This is labelled with C so does not automatically generate Fortran stubs and interfaces
1950 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1951
1952 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1953 MatSetValuesLocal()
1954 @*/
MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[])1955 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[])
1956 {
1957 PetscErrorCode ierr;
1958
1959 PetscFunctionBeginHot;
1960 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1961 PetscValidType(mat,1);
1962 MatCheckPreallocated(mat,1);
1963 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */
1964 PetscValidIntPointer(irow,3);
1965 PetscValidIntPointer(icol,5);
1966 if (PetscDefined(USE_DEBUG)) {
1967 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1968 if (!mat->ops->getvalueslocal && !mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1969 }
1970 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1971 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1972 if (mat->ops->getvalueslocal) {
1973 ierr = (*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y);CHKERRQ(ierr);
1974 } else {
1975 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm;
1976 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1977 irowm = buf; icolm = buf+nrow;
1978 } else {
1979 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
1980 irowm = bufr; icolm = bufc;
1981 }
1982 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping()).");
1983 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping()).");
1984 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
1985 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
1986 ierr = MatGetValues(mat,nrow,irowm,ncol,icolm,y);CHKERRQ(ierr);
1987 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1988 }
1989 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1990 PetscFunctionReturn(0);
1991 }
1992
1993 /*@
1994 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1995 the same size. Currently, this can only be called once and creates the given matrix.
1996
1997 Not Collective
1998
1999 Input Parameters:
2000 + mat - the matrix
2001 . nb - the number of blocks
2002 . bs - the number of rows (and columns) in each block
2003 . rows - a concatenation of the rows for each block
2004 - v - a concatenation of logically two-dimensional arrays of values
2005
2006 Notes:
2007 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
2008
2009 Level: advanced
2010
2011 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2012 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2013 @*/
MatSetValuesBatch(Mat mat,PetscInt nb,PetscInt bs,PetscInt rows[],const PetscScalar v[])2014 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2015 {
2016 PetscErrorCode ierr;
2017
2018 PetscFunctionBegin;
2019 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2020 PetscValidType(mat,1);
2021 PetscValidScalarPointer(rows,4);
2022 PetscValidScalarPointer(v,5);
2023 if (PetscUnlikelyDebug(mat->factortype)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2024
2025 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2026 if (mat->ops->setvaluesbatch) {
2027 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2028 } else {
2029 PetscInt b;
2030 for (b = 0; b < nb; ++b) {
2031 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2032 }
2033 }
2034 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2035 PetscFunctionReturn(0);
2036 }
2037
2038 /*@
2039 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2040 the routine MatSetValuesLocal() to allow users to insert matrix entries
2041 using a local (per-processor) numbering.
2042
2043 Not Collective
2044
2045 Input Parameters:
2046 + x - the matrix
2047 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS()
2048 - cmapping - column mapping
2049
2050 Level: intermediate
2051
2052
2053 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2054 @*/
MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)2055 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2056 {
2057 PetscErrorCode ierr;
2058
2059 PetscFunctionBegin;
2060 PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2061 PetscValidType(x,1);
2062 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2063 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2064
2065 if (x->ops->setlocaltoglobalmapping) {
2066 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2067 } else {
2068 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2069 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2070 }
2071 PetscFunctionReturn(0);
2072 }
2073
2074
2075 /*@
2076 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2077
2078 Not Collective
2079
2080 Input Parameters:
2081 . A - the matrix
2082
2083 Output Parameters:
2084 + rmapping - row mapping
2085 - cmapping - column mapping
2086
2087 Level: advanced
2088
2089
2090 .seealso: MatSetValuesLocal()
2091 @*/
MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping * rmapping,ISLocalToGlobalMapping * cmapping)2092 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2093 {
2094 PetscFunctionBegin;
2095 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2096 PetscValidType(A,1);
2097 if (rmapping) PetscValidPointer(rmapping,2);
2098 if (cmapping) PetscValidPointer(cmapping,3);
2099 if (rmapping) *rmapping = A->rmap->mapping;
2100 if (cmapping) *cmapping = A->cmap->mapping;
2101 PetscFunctionReturn(0);
2102 }
2103
2104 /*@
2105 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix
2106
2107 Logically Collective on A
2108
2109 Input Parameters:
2110 + A - the matrix
2111 . rmap - row layout
2112 - cmap - column layout
2113
2114 Level: advanced
2115
2116 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping(), MatGetLayouts()
2117 @*/
MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap)2118 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap)
2119 {
2120 PetscErrorCode ierr;
2121
2122 PetscFunctionBegin;
2123 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2124
2125 ierr = PetscLayoutReference(rmap,&A->rmap);CHKERRQ(ierr);
2126 ierr = PetscLayoutReference(cmap,&A->cmap);CHKERRQ(ierr);
2127 PetscFunctionReturn(0);
2128 }
2129
2130 /*@
2131 MatGetLayouts - Gets the PetscLayout objects for rows and columns
2132
2133 Not Collective
2134
2135 Input Parameters:
2136 . A - the matrix
2137
2138 Output Parameters:
2139 + rmap - row layout
2140 - cmap - column layout
2141
2142 Level: advanced
2143
2144 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping(), MatSetLayouts()
2145 @*/
MatGetLayouts(Mat A,PetscLayout * rmap,PetscLayout * cmap)2146 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2147 {
2148 PetscFunctionBegin;
2149 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2150 PetscValidType(A,1);
2151 if (rmap) PetscValidPointer(rmap,2);
2152 if (cmap) PetscValidPointer(cmap,3);
2153 if (rmap) *rmap = A->rmap;
2154 if (cmap) *cmap = A->cmap;
2155 PetscFunctionReturn(0);
2156 }
2157
2158 /*@C
2159 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2160 using a local numbering of the nodes.
2161
2162 Not Collective
2163
2164 Input Parameters:
2165 + mat - the matrix
2166 . nrow, irow - number of rows and their local indices
2167 . ncol, icol - number of columns and their local indices
2168 . y - a logically two-dimensional array of values
2169 - addv - either INSERT_VALUES or ADD_VALUES, where
2170 ADD_VALUES adds values to any existing entries, and
2171 INSERT_VALUES replaces existing entries with new values
2172
2173 Notes:
2174 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2175 MatSetUp() before using this routine
2176
2177 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2178
2179 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2180 options cannot be mixed without intervening calls to the assembly
2181 routines.
2182
2183 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2184 MUST be called after all calls to MatSetValuesLocal() have been completed.
2185
2186 Level: intermediate
2187
2188 Developer Notes:
2189 This is labeled with C so does not automatically generate Fortran stubs and interfaces
2190 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2191
2192 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2193 MatSetValueLocal(), MatGetValuesLocal()
2194 @*/
MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)2195 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2196 {
2197 PetscErrorCode ierr;
2198
2199 PetscFunctionBeginHot;
2200 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2201 PetscValidType(mat,1);
2202 MatCheckPreallocated(mat,1);
2203 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2204 PetscValidIntPointer(irow,3);
2205 PetscValidIntPointer(icol,5);
2206 if (mat->insertmode == NOT_SET_VALUES) {
2207 mat->insertmode = addv;
2208 }
2209 else if (PetscUnlikely(mat->insertmode != addv)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2210 if (PetscDefined(USE_DEBUG)) {
2211 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2212 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2213 }
2214
2215 if (mat->assembled) {
2216 mat->was_assembled = PETSC_TRUE;
2217 mat->assembled = PETSC_FALSE;
2218 }
2219 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2220 if (mat->ops->setvalueslocal) {
2221 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2222 } else {
2223 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm;
2224 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2225 irowm = buf; icolm = buf+nrow;
2226 } else {
2227 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2228 irowm = bufr; icolm = bufc;
2229 }
2230 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatSetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping()).");
2231 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatSetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping()).");
2232 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2233 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2234 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2235 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2236 }
2237 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2238 PetscFunctionReturn(0);
2239 }
2240
2241 /*@C
2242 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2243 using a local ordering of the nodes a block at a time.
2244
2245 Not Collective
2246
2247 Input Parameters:
2248 + x - the matrix
2249 . nrow, irow - number of rows and their local indices
2250 . ncol, icol - number of columns and their local indices
2251 . y - a logically two-dimensional array of values
2252 - addv - either INSERT_VALUES or ADD_VALUES, where
2253 ADD_VALUES adds values to any existing entries, and
2254 INSERT_VALUES replaces existing entries with new values
2255
2256 Notes:
2257 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2258 MatSetUp() before using this routine
2259
2260 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2261 before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2262
2263 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2264 options cannot be mixed without intervening calls to the assembly
2265 routines.
2266
2267 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2268 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2269
2270 Level: intermediate
2271
2272 Developer Notes:
2273 This is labeled with C so does not automatically generate Fortran stubs and interfaces
2274 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2275
2276 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2277 MatSetValuesLocal(), MatSetValuesBlocked()
2278 @*/
MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)2279 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2280 {
2281 PetscErrorCode ierr;
2282
2283 PetscFunctionBeginHot;
2284 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2285 PetscValidType(mat,1);
2286 MatCheckPreallocated(mat,1);
2287 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2288 PetscValidIntPointer(irow,3);
2289 PetscValidIntPointer(icol,5);
2290 PetscValidScalarPointer(y,6);
2291 if (mat->insertmode == NOT_SET_VALUES) {
2292 mat->insertmode = addv;
2293 } else if (PetscUnlikely(mat->insertmode != addv)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2294 if (PetscDefined(USE_DEBUG)) {
2295 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2296 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);
2297 }
2298
2299 if (mat->assembled) {
2300 mat->was_assembled = PETSC_TRUE;
2301 mat->assembled = PETSC_FALSE;
2302 }
2303 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2304 PetscInt irbs, rbs;
2305 ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2306 ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2307 if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2308 }
2309 if (PetscUnlikelyDebug(mat->cmap->mapping)) {
2310 PetscInt icbs, cbs;
2311 ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2312 ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2313 if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2314 }
2315 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2316 if (mat->ops->setvaluesblockedlocal) {
2317 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2318 } else {
2319 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm;
2320 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2321 irowm = buf; icolm = buf + nrow;
2322 } else {
2323 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2324 irowm = bufr; icolm = bufc;
2325 }
2326 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2327 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2328 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2329 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2330 }
2331 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2332 PetscFunctionReturn(0);
2333 }
2334
2335 /*@
2336 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2337
2338 Collective on Mat
2339
2340 Input Parameters:
2341 + mat - the matrix
2342 - x - the vector to be multiplied
2343
2344 Output Parameters:
2345 . y - the result
2346
2347 Notes:
2348 The vectors x and y cannot be the same. I.e., one cannot
2349 call MatMult(A,y,y).
2350
2351 Level: developer
2352
2353 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2354 @*/
MatMultDiagonalBlock(Mat mat,Vec x,Vec y)2355 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2356 {
2357 PetscErrorCode ierr;
2358
2359 PetscFunctionBegin;
2360 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2361 PetscValidType(mat,1);
2362 PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2363 PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2364
2365 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2366 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2367 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2368 MatCheckPreallocated(mat,1);
2369
2370 if (!mat->ops->multdiagonalblock) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name);
2371 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2372 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2373 PetscFunctionReturn(0);
2374 }
2375
2376 /* --------------------------------------------------------*/
2377 /*@
2378 MatMult - Computes the matrix-vector product, y = Ax.
2379
2380 Neighbor-wise Collective on Mat
2381
2382 Input Parameters:
2383 + mat - the matrix
2384 - x - the vector to be multiplied
2385
2386 Output Parameters:
2387 . y - the result
2388
2389 Notes:
2390 The vectors x and y cannot be the same. I.e., one cannot
2391 call MatMult(A,y,y).
2392
2393 Level: beginner
2394
2395 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2396 @*/
MatMult(Mat mat,Vec x,Vec y)2397 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2398 {
2399 PetscErrorCode ierr;
2400
2401 PetscFunctionBegin;
2402 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2403 PetscValidType(mat,1);
2404 PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2405 PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2406 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2407 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2408 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2409 #if !defined(PETSC_HAVE_CONSTRAINTS)
2410 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);
2411 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);
2412 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);
2413 #endif
2414 ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2415 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2416 MatCheckPreallocated(mat,1);
2417
2418 ierr = VecLockReadPush(x);CHKERRQ(ierr);
2419 if (!mat->ops->mult) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name);
2420 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2421 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2422 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2423 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2424 ierr = VecLockReadPop(x);CHKERRQ(ierr);
2425 PetscFunctionReturn(0);
2426 }
2427
2428 /*@
2429 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2430
2431 Neighbor-wise Collective on Mat
2432
2433 Input Parameters:
2434 + mat - the matrix
2435 - x - the vector to be multiplied
2436
2437 Output Parameters:
2438 . y - the result
2439
2440 Notes:
2441 The vectors x and y cannot be the same. I.e., one cannot
2442 call MatMultTranspose(A,y,y).
2443
2444 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2445 use MatMultHermitianTranspose()
2446
2447 Level: beginner
2448
2449 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2450 @*/
MatMultTranspose(Mat mat,Vec x,Vec y)2451 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2452 {
2453 PetscErrorCode (*op)(Mat,Vec,Vec)=NULL,ierr;
2454
2455 PetscFunctionBegin;
2456 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2457 PetscValidType(mat,1);
2458 PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2459 PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2460
2461 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2462 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2463 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2464 #if !defined(PETSC_HAVE_CONSTRAINTS)
2465 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);
2466 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);
2467 #endif
2468 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2469 MatCheckPreallocated(mat,1);
2470
2471 if (!mat->ops->multtranspose) {
2472 if (mat->symmetric && mat->ops->mult) op = mat->ops->mult;
2473 if (!op) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply transpose defined or is symmetric and does not have a multiply defined",((PetscObject)mat)->type_name);
2474 } else op = mat->ops->multtranspose;
2475 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2476 ierr = VecLockReadPush(x);CHKERRQ(ierr);
2477 ierr = (*op)(mat,x,y);CHKERRQ(ierr);
2478 ierr = VecLockReadPop(x);CHKERRQ(ierr);
2479 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2480 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2481 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2482 PetscFunctionReturn(0);
2483 }
2484
2485 /*@
2486 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2487
2488 Neighbor-wise Collective on Mat
2489
2490 Input Parameters:
2491 + mat - the matrix
2492 - x - the vector to be multilplied
2493
2494 Output Parameters:
2495 . y - the result
2496
2497 Notes:
2498 The vectors x and y cannot be the same. I.e., one cannot
2499 call MatMultHermitianTranspose(A,y,y).
2500
2501 Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2502
2503 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2504
2505 Level: beginner
2506
2507 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2508 @*/
MatMultHermitianTranspose(Mat mat,Vec x,Vec y)2509 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2510 {
2511 PetscErrorCode ierr;
2512
2513 PetscFunctionBegin;
2514 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2515 PetscValidType(mat,1);
2516 PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2517 PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2518
2519 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2520 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2521 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2522 #if !defined(PETSC_HAVE_CONSTRAINTS)
2523 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);
2524 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);
2525 #endif
2526 MatCheckPreallocated(mat,1);
2527
2528 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2529 #if defined(PETSC_USE_COMPLEX)
2530 if (mat->ops->multhermitiantranspose || (mat->hermitian && mat->ops->mult)) {
2531 ierr = VecLockReadPush(x);CHKERRQ(ierr);
2532 if (mat->ops->multhermitiantranspose) {
2533 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2534 } else {
2535 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2536 }
2537 ierr = VecLockReadPop(x);CHKERRQ(ierr);
2538 } else {
2539 Vec w;
2540 ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2541 ierr = VecCopy(x,w);CHKERRQ(ierr);
2542 ierr = VecConjugate(w);CHKERRQ(ierr);
2543 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2544 ierr = VecDestroy(&w);CHKERRQ(ierr);
2545 ierr = VecConjugate(y);CHKERRQ(ierr);
2546 }
2547 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2548 #else
2549 ierr = MatMultTranspose(mat,x,y);CHKERRQ(ierr);
2550 #endif
2551 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2552 PetscFunctionReturn(0);
2553 }
2554
2555 /*@
2556 MatMultAdd - Computes v3 = v2 + A * v1.
2557
2558 Neighbor-wise Collective on Mat
2559
2560 Input Parameters:
2561 + mat - the matrix
2562 - v1, v2 - the vectors
2563
2564 Output Parameters:
2565 . v3 - the result
2566
2567 Notes:
2568 The vectors v1 and v3 cannot be the same. I.e., one cannot
2569 call MatMultAdd(A,v1,v2,v1).
2570
2571 Level: beginner
2572
2573 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2574 @*/
MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)2575 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2576 {
2577 PetscErrorCode ierr;
2578
2579 PetscFunctionBegin;
2580 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2581 PetscValidType(mat,1);
2582 PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2583 PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2584 PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2585
2586 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2587 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2588 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);
2589 /* 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);
2590 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); */
2591 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);
2592 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);
2593 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2594 MatCheckPreallocated(mat,1);
2595
2596 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name);
2597 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2598 ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2599 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2600 ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2601 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2602 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2603 PetscFunctionReturn(0);
2604 }
2605
2606 /*@
2607 MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2608
2609 Neighbor-wise Collective on Mat
2610
2611 Input Parameters:
2612 + mat - the matrix
2613 - v1, v2 - the vectors
2614
2615 Output Parameters:
2616 . v3 - the result
2617
2618 Notes:
2619 The vectors v1 and v3 cannot be the same. I.e., one cannot
2620 call MatMultTransposeAdd(A,v1,v2,v1).
2621
2622 Level: beginner
2623
2624 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2625 @*/
MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)2626 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2627 {
2628 PetscErrorCode ierr;
2629
2630 PetscFunctionBegin;
2631 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2632 PetscValidType(mat,1);
2633 PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2634 PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2635 PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2636
2637 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2638 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2639 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2640 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2641 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);
2642 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);
2643 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);
2644 MatCheckPreallocated(mat,1);
2645
2646 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2647 ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2648 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2649 ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2650 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2651 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2652 PetscFunctionReturn(0);
2653 }
2654
2655 /*@
2656 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2657
2658 Neighbor-wise Collective on Mat
2659
2660 Input Parameters:
2661 + mat - the matrix
2662 - v1, v2 - the vectors
2663
2664 Output Parameters:
2665 . v3 - the result
2666
2667 Notes:
2668 The vectors v1 and v3 cannot be the same. I.e., one cannot
2669 call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2670
2671 Level: beginner
2672
2673 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2674 @*/
MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)2675 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2676 {
2677 PetscErrorCode ierr;
2678
2679 PetscFunctionBegin;
2680 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2681 PetscValidType(mat,1);
2682 PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2683 PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2684 PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2685
2686 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2687 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2688 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2689 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);
2690 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);
2691 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);
2692 MatCheckPreallocated(mat,1);
2693
2694 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2695 ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2696 if (mat->ops->multhermitiantransposeadd) {
2697 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2698 } else {
2699 Vec w,z;
2700 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2701 ierr = VecCopy(v1,w);CHKERRQ(ierr);
2702 ierr = VecConjugate(w);CHKERRQ(ierr);
2703 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2704 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2705 ierr = VecDestroy(&w);CHKERRQ(ierr);
2706 ierr = VecConjugate(z);CHKERRQ(ierr);
2707 if (v2 != v3) {
2708 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2709 } else {
2710 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2711 }
2712 ierr = VecDestroy(&z);CHKERRQ(ierr);
2713 }
2714 ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2715 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2716 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2717 PetscFunctionReturn(0);
2718 }
2719
2720 /*@
2721 MatMultConstrained - The inner multiplication routine for a
2722 constrained matrix P^T A P.
2723
2724 Neighbor-wise Collective on Mat
2725
2726 Input Parameters:
2727 + mat - the matrix
2728 - x - the vector to be multilplied
2729
2730 Output Parameters:
2731 . y - the result
2732
2733 Notes:
2734 The vectors x and y cannot be the same. I.e., one cannot
2735 call MatMult(A,y,y).
2736
2737 Level: beginner
2738
2739 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2740 @*/
MatMultConstrained(Mat mat,Vec x,Vec y)2741 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2742 {
2743 PetscErrorCode ierr;
2744
2745 PetscFunctionBegin;
2746 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2747 PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2748 PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2749 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2750 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2751 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2752 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);
2753 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);
2754 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);
2755
2756 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2757 ierr = VecLockReadPush(x);CHKERRQ(ierr);
2758 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2759 ierr = VecLockReadPop(x);CHKERRQ(ierr);
2760 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2761 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2762 PetscFunctionReturn(0);
2763 }
2764
2765 /*@
2766 MatMultTransposeConstrained - The inner multiplication routine for a
2767 constrained matrix P^T A^T P.
2768
2769 Neighbor-wise Collective on Mat
2770
2771 Input Parameters:
2772 + mat - the matrix
2773 - x - the vector to be multilplied
2774
2775 Output Parameters:
2776 . y - the result
2777
2778 Notes:
2779 The vectors x and y cannot be the same. I.e., one cannot
2780 call MatMult(A,y,y).
2781
2782 Level: beginner
2783
2784 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2785 @*/
MatMultTransposeConstrained(Mat mat,Vec x,Vec y)2786 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2787 {
2788 PetscErrorCode ierr;
2789
2790 PetscFunctionBegin;
2791 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2792 PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2793 PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2794 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2795 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2796 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2797 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);
2798 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);
2799
2800 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2801 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2802 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2803 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2804 PetscFunctionReturn(0);
2805 }
2806
2807 /*@C
2808 MatGetFactorType - gets the type of factorization it is
2809
2810 Not Collective
2811
2812 Input Parameters:
2813 . mat - the matrix
2814
2815 Output Parameters:
2816 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2817
2818 Level: intermediate
2819
2820 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2821 @*/
MatGetFactorType(Mat mat,MatFactorType * t)2822 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2823 {
2824 PetscFunctionBegin;
2825 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2826 PetscValidType(mat,1);
2827 PetscValidPointer(t,2);
2828 *t = mat->factortype;
2829 PetscFunctionReturn(0);
2830 }
2831
2832 /*@C
2833 MatSetFactorType - sets the type of factorization it is
2834
2835 Logically Collective on Mat
2836
2837 Input Parameters:
2838 + mat - the matrix
2839 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2840
2841 Level: intermediate
2842
2843 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2844 @*/
MatSetFactorType(Mat mat,MatFactorType t)2845 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2846 {
2847 PetscFunctionBegin;
2848 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2849 PetscValidType(mat,1);
2850 mat->factortype = t;
2851 PetscFunctionReturn(0);
2852 }
2853
2854 /* ------------------------------------------------------------*/
2855 /*@C
2856 MatGetInfo - Returns information about matrix storage (number of
2857 nonzeros, memory, etc.).
2858
2859 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2860
2861 Input Parameters:
2862 . mat - the matrix
2863
2864 Output Parameters:
2865 + flag - flag indicating the type of parameters to be returned
2866 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2867 MAT_GLOBAL_SUM - sum over all processors)
2868 - info - matrix information context
2869
2870 Notes:
2871 The MatInfo context contains a variety of matrix data, including
2872 number of nonzeros allocated and used, number of mallocs during
2873 matrix assembly, etc. Additional information for factored matrices
2874 is provided (such as the fill ratio, number of mallocs during
2875 factorization, etc.). Much of this info is printed to PETSC_STDOUT
2876 when using the runtime options
2877 $ -info -mat_view ::ascii_info
2878
2879 Example for C/C++ Users:
2880 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2881 data within the MatInfo context. For example,
2882 .vb
2883 MatInfo info;
2884 Mat A;
2885 double mal, nz_a, nz_u;
2886
2887 MatGetInfo(A,MAT_LOCAL,&info);
2888 mal = info.mallocs;
2889 nz_a = info.nz_allocated;
2890 .ve
2891
2892 Example for Fortran Users:
2893 Fortran users should declare info as a double precision
2894 array of dimension MAT_INFO_SIZE, and then extract the parameters
2895 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2896 a complete list of parameter names.
2897 .vb
2898 double precision info(MAT_INFO_SIZE)
2899 double precision mal, nz_a
2900 Mat A
2901 integer ierr
2902
2903 call MatGetInfo(A,MAT_LOCAL,info,ierr)
2904 mal = info(MAT_INFO_MALLOCS)
2905 nz_a = info(MAT_INFO_NZ_ALLOCATED)
2906 .ve
2907
2908 Level: intermediate
2909
2910 Developer Note: fortran interface is not autogenerated as the f90
2911 interface defintion cannot be generated correctly [due to MatInfo]
2912
2913 .seealso: MatStashGetInfo()
2914
2915 @*/
MatGetInfo(Mat mat,MatInfoType flag,MatInfo * info)2916 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2917 {
2918 PetscErrorCode ierr;
2919
2920 PetscFunctionBegin;
2921 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2922 PetscValidType(mat,1);
2923 PetscValidPointer(info,3);
2924 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2925 MatCheckPreallocated(mat,1);
2926 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2927 PetscFunctionReturn(0);
2928 }
2929
2930 /*
2931 This is used by external packages where it is not easy to get the info from the actual
2932 matrix factorization.
2933 */
MatGetInfo_External(Mat A,MatInfoType flag,MatInfo * info)2934 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2935 {
2936 PetscErrorCode ierr;
2937
2938 PetscFunctionBegin;
2939 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2940 PetscFunctionReturn(0);
2941 }
2942
2943 /* ----------------------------------------------------------*/
2944
2945 /*@C
2946 MatLUFactor - Performs in-place LU factorization of matrix.
2947
2948 Collective on Mat
2949
2950 Input Parameters:
2951 + mat - the matrix
2952 . row - row permutation
2953 . col - column permutation
2954 - info - options for factorization, includes
2955 $ fill - expected fill as ratio of original fill.
2956 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2957 $ Run with the option -info to determine an optimal value to use
2958
2959 Notes:
2960 Most users should employ the simplified KSP interface for linear solvers
2961 instead of working directly with matrix algebra routines such as this.
2962 See, e.g., KSPCreate().
2963
2964 This changes the state of the matrix to a factored matrix; it cannot be used
2965 for example with MatSetValues() unless one first calls MatSetUnfactored().
2966
2967 Level: developer
2968
2969 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2970 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2971
2972 Developer Note: fortran interface is not autogenerated as the f90
2973 interface defintion cannot be generated correctly [due to MatFactorInfo]
2974
2975 @*/
MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo * info)2976 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2977 {
2978 PetscErrorCode ierr;
2979 MatFactorInfo tinfo;
2980
2981 PetscFunctionBegin;
2982 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2983 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2984 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2985 if (info) PetscValidPointer(info,4);
2986 PetscValidType(mat,1);
2987 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2988 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2989 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2990 MatCheckPreallocated(mat,1);
2991 if (!info) {
2992 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2993 info = &tinfo;
2994 }
2995
2996 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2997 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2998 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2999 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3000 PetscFunctionReturn(0);
3001 }
3002
3003 /*@C
3004 MatILUFactor - Performs in-place ILU factorization of matrix.
3005
3006 Collective on Mat
3007
3008 Input Parameters:
3009 + mat - the matrix
3010 . row - row permutation
3011 . col - column permutation
3012 - info - structure containing
3013 $ levels - number of levels of fill.
3014 $ expected fill - as ratio of original fill.
3015 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3016 missing diagonal entries)
3017
3018 Notes:
3019 Probably really in-place only when level of fill is zero, otherwise allocates
3020 new space to store factored matrix and deletes previous memory.
3021
3022 Most users should employ the simplified KSP interface for linear solvers
3023 instead of working directly with matrix algebra routines such as this.
3024 See, e.g., KSPCreate().
3025
3026 Level: developer
3027
3028 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3029
3030 Developer Note: fortran interface is not autogenerated as the f90
3031 interface defintion cannot be generated correctly [due to MatFactorInfo]
3032
3033 @*/
MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo * info)3034 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3035 {
3036 PetscErrorCode ierr;
3037
3038 PetscFunctionBegin;
3039 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3040 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3041 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3042 PetscValidPointer(info,4);
3043 PetscValidType(mat,1);
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->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3048 MatCheckPreallocated(mat,1);
3049
3050 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3051 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3052 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3053 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3054 PetscFunctionReturn(0);
3055 }
3056
3057 /*@C
3058 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3059 Call this routine before calling MatLUFactorNumeric().
3060
3061 Collective on Mat
3062
3063 Input Parameters:
3064 + fact - the factor matrix obtained with MatGetFactor()
3065 . mat - the matrix
3066 . row, col - row and column permutations
3067 - info - options for factorization, includes
3068 $ fill - expected fill as ratio of original fill.
3069 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3070 $ Run with the option -info to determine an optimal value to use
3071
3072
3073 Notes:
3074 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3075
3076 Most users should employ the simplified KSP interface for linear solvers
3077 instead of working directly with matrix algebra routines such as this.
3078 See, e.g., KSPCreate().
3079
3080 Level: developer
3081
3082 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3083
3084 Developer Note: fortran interface is not autogenerated as the f90
3085 interface defintion cannot be generated correctly [due to MatFactorInfo]
3086
3087 @*/
MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo * info)3088 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3089 {
3090 PetscErrorCode ierr;
3091 MatFactorInfo tinfo;
3092
3093 PetscFunctionBegin;
3094 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3095 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3096 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3097 if (info) PetscValidPointer(info,4);
3098 PetscValidType(mat,1);
3099 PetscValidPointer(fact,5);
3100 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3101 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3102 if (!(fact)->ops->lufactorsymbolic) {
3103 MatSolverType stype;
3104 ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
3105 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype);
3106 }
3107 MatCheckPreallocated(mat,2);
3108 if (!info) {
3109 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3110 info = &tinfo;
3111 }
3112
3113 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3114 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3115 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3116 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3117 PetscFunctionReturn(0);
3118 }
3119
3120 /*@C
3121 MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3122 Call this routine after first calling MatLUFactorSymbolic().
3123
3124 Collective on Mat
3125
3126 Input Parameters:
3127 + fact - the factor matrix obtained with MatGetFactor()
3128 . mat - the matrix
3129 - info - options for factorization
3130
3131 Notes:
3132 See MatLUFactor() for in-place factorization. See
3133 MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3134
3135 Most users should employ the simplified KSP interface for linear solvers
3136 instead of working directly with matrix algebra routines such as this.
3137 See, e.g., KSPCreate().
3138
3139 Level: developer
3140
3141 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3142
3143 Developer Note: fortran interface is not autogenerated as the f90
3144 interface defintion cannot be generated correctly [due to MatFactorInfo]
3145
3146 @*/
MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo * info)3147 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3148 {
3149 MatFactorInfo tinfo;
3150 PetscErrorCode ierr;
3151
3152 PetscFunctionBegin;
3153 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3154 PetscValidType(mat,1);
3155 PetscValidPointer(fact,2);
3156 PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3157 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3158 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);
3159
3160 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3161 MatCheckPreallocated(mat,2);
3162 if (!info) {
3163 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3164 info = &tinfo;
3165 }
3166
3167 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3168 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3169 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3170 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3171 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3172 PetscFunctionReturn(0);
3173 }
3174
3175 /*@C
3176 MatCholeskyFactor - Performs in-place Cholesky factorization of a
3177 symmetric matrix.
3178
3179 Collective on Mat
3180
3181 Input Parameters:
3182 + mat - the matrix
3183 . perm - row and column permutations
3184 - f - expected fill as ratio of original fill
3185
3186 Notes:
3187 See MatLUFactor() for the nonsymmetric case. See also
3188 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3189
3190 Most users should employ the simplified KSP interface for linear solvers
3191 instead of working directly with matrix algebra routines such as this.
3192 See, e.g., KSPCreate().
3193
3194 Level: developer
3195
3196 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3197 MatGetOrdering()
3198
3199 Developer Note: fortran interface is not autogenerated as the f90
3200 interface defintion cannot be generated correctly [due to MatFactorInfo]
3201
3202 @*/
MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo * info)3203 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3204 {
3205 PetscErrorCode ierr;
3206 MatFactorInfo tinfo;
3207
3208 PetscFunctionBegin;
3209 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3210 PetscValidType(mat,1);
3211 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3212 if (info) PetscValidPointer(info,3);
3213 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3214 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3215 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3216 if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3217 MatCheckPreallocated(mat,1);
3218 if (!info) {
3219 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3220 info = &tinfo;
3221 }
3222
3223 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3224 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3225 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3226 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3227 PetscFunctionReturn(0);
3228 }
3229
3230 /*@C
3231 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3232 of a symmetric matrix.
3233
3234 Collective on Mat
3235
3236 Input Parameters:
3237 + fact - the factor matrix obtained with MatGetFactor()
3238 . mat - the matrix
3239 . perm - row and column permutations
3240 - info - options for factorization, includes
3241 $ fill - expected fill as ratio of original fill.
3242 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3243 $ Run with the option -info to determine an optimal value to use
3244
3245 Notes:
3246 See MatLUFactorSymbolic() for the nonsymmetric case. See also
3247 MatCholeskyFactor() and MatCholeskyFactorNumeric().
3248
3249 Most users should employ the simplified KSP interface for linear solvers
3250 instead of working directly with matrix algebra routines such as this.
3251 See, e.g., KSPCreate().
3252
3253 Level: developer
3254
3255 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3256 MatGetOrdering()
3257
3258 Developer Note: fortran interface is not autogenerated as the f90
3259 interface defintion cannot be generated correctly [due to MatFactorInfo]
3260
3261 @*/
MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo * info)3262 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3263 {
3264 PetscErrorCode ierr;
3265 MatFactorInfo tinfo;
3266
3267 PetscFunctionBegin;
3268 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3269 PetscValidType(mat,1);
3270 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3271 if (info) PetscValidPointer(info,3);
3272 PetscValidPointer(fact,4);
3273 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3274 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3275 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3276 if (!(fact)->ops->choleskyfactorsymbolic) {
3277 MatSolverType stype;
3278 ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
3279 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype);
3280 }
3281 MatCheckPreallocated(mat,2);
3282 if (!info) {
3283 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3284 info = &tinfo;
3285 }
3286
3287 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3288 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3289 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3290 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3291 PetscFunctionReturn(0);
3292 }
3293
3294 /*@C
3295 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3296 of a symmetric matrix. Call this routine after first calling
3297 MatCholeskyFactorSymbolic().
3298
3299 Collective on Mat
3300
3301 Input Parameters:
3302 + fact - the factor matrix obtained with MatGetFactor()
3303 . mat - the initial matrix
3304 . info - options for factorization
3305 - fact - the symbolic factor of mat
3306
3307
3308 Notes:
3309 Most users should employ the simplified KSP interface for linear solvers
3310 instead of working directly with matrix algebra routines such as this.
3311 See, e.g., KSPCreate().
3312
3313 Level: developer
3314
3315 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3316
3317 Developer Note: fortran interface is not autogenerated as the f90
3318 interface defintion cannot be generated correctly [due to MatFactorInfo]
3319
3320 @*/
MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo * info)3321 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3322 {
3323 MatFactorInfo tinfo;
3324 PetscErrorCode ierr;
3325
3326 PetscFunctionBegin;
3327 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3328 PetscValidType(mat,1);
3329 PetscValidPointer(fact,2);
3330 PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3331 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3332 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3333 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);
3334 MatCheckPreallocated(mat,2);
3335 if (!info) {
3336 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3337 info = &tinfo;
3338 }
3339
3340 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3341 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3342 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3343 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3344 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3345 PetscFunctionReturn(0);
3346 }
3347
3348 /* ----------------------------------------------------------------*/
3349 /*@
3350 MatSolve - Solves A x = b, given a factored matrix.
3351
3352 Neighbor-wise Collective on Mat
3353
3354 Input Parameters:
3355 + mat - the factored matrix
3356 - b - the right-hand-side vector
3357
3358 Output Parameter:
3359 . x - the result vector
3360
3361 Notes:
3362 The vectors b and x cannot be the same. I.e., one cannot
3363 call MatSolve(A,x,x).
3364
3365 Notes:
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().
3369
3370 Level: developer
3371
3372 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3373 @*/
MatSolve(Mat mat,Vec b,Vec x)3374 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3375 {
3376 PetscErrorCode ierr;
3377
3378 PetscFunctionBegin;
3379 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3380 PetscValidType(mat,1);
3381 PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3382 PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3383 PetscCheckSameComm(mat,1,b,2);
3384 PetscCheckSameComm(mat,1,x,3);
3385 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3386 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);
3387 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);
3388 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);
3389 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3390 MatCheckPreallocated(mat,1);
3391
3392 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3393 if (mat->factorerrortype) {
3394 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3395 ierr = VecSetInf(x);CHKERRQ(ierr);
3396 } else {
3397 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3398 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3399 }
3400 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3401 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3402 PetscFunctionReturn(0);
3403 }
3404
MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans)3405 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans)
3406 {
3407 PetscErrorCode ierr;
3408 Vec b,x;
3409 PetscInt m,N,i;
3410 PetscScalar *bb,*xx;
3411
3412 PetscFunctionBegin;
3413 ierr = MatDenseGetArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3414 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3415 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */
3416 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */
3417 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3418 for (i=0; i<N; i++) {
3419 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3420 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3421 if (trans) {
3422 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3423 } else {
3424 ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3425 }
3426 ierr = VecResetArray(x);CHKERRQ(ierr);
3427 ierr = VecResetArray(b);CHKERRQ(ierr);
3428 }
3429 ierr = VecDestroy(&b);CHKERRQ(ierr);
3430 ierr = VecDestroy(&x);CHKERRQ(ierr);
3431 ierr = MatDenseRestoreArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3432 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3433 PetscFunctionReturn(0);
3434 }
3435
3436 /*@
3437 MatMatSolve - Solves A X = B, given a factored matrix.
3438
3439 Neighbor-wise Collective on Mat
3440
3441 Input Parameters:
3442 + A - the factored matrix
3443 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS)
3444
3445 Output Parameter:
3446 . X - the result matrix (dense matrix)
3447
3448 Notes:
3449 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO;
3450 otherwise, B and X cannot be the same.
3451
3452 Notes:
3453 Most users should usually employ the simplified KSP interface for linear solvers
3454 instead of working directly with matrix algebra routines such as this.
3455 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3456 at a time.
3457
3458 Level: developer
3459
3460 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3461 @*/
MatMatSolve(Mat A,Mat B,Mat X)3462 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3463 {
3464 PetscErrorCode ierr;
3465
3466 PetscFunctionBegin;
3467 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3468 PetscValidType(A,1);
3469 PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3470 PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3471 PetscCheckSameComm(A,1,B,2);
3472 PetscCheckSameComm(A,1,X,3);
3473 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);
3474 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);
3475 if (X->cmap->N != B->cmap->N) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3476 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3477 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3478 MatCheckPreallocated(A,1);
3479
3480 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3481 if (!A->ops->matsolve) {
3482 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3483 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3484 } else {
3485 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3486 }
3487 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3488 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3489 PetscFunctionReturn(0);
3490 }
3491
3492 /*@
3493 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3494
3495 Neighbor-wise Collective on Mat
3496
3497 Input Parameters:
3498 + A - the factored matrix
3499 - B - the right-hand-side matrix (dense matrix)
3500
3501 Output Parameter:
3502 . X - the result matrix (dense matrix)
3503
3504 Notes:
3505 The matrices B and X cannot be the same. I.e., one cannot
3506 call MatMatSolveTranspose(A,X,X).
3507
3508 Notes:
3509 Most users should usually employ the simplified KSP interface for linear solvers
3510 instead of working directly with matrix algebra routines such as this.
3511 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3512 at a time.
3513
3514 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3515
3516 Level: developer
3517
3518 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3519 @*/
MatMatSolveTranspose(Mat A,Mat B,Mat X)3520 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3521 {
3522 PetscErrorCode ierr;
3523
3524 PetscFunctionBegin;
3525 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3526 PetscValidType(A,1);
3527 PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3528 PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3529 PetscCheckSameComm(A,1,B,2);
3530 PetscCheckSameComm(A,1,X,3);
3531 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3532 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);
3533 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);
3534 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);
3535 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");
3536 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3537 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3538 MatCheckPreallocated(A,1);
3539
3540 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3541 if (!A->ops->matsolvetranspose) {
3542 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3543 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3544 } else {
3545 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3546 }
3547 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3548 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3549 PetscFunctionReturn(0);
3550 }
3551
3552 /*@
3553 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3554
3555 Neighbor-wise Collective on Mat
3556
3557 Input Parameters:
3558 + A - the factored matrix
3559 - Bt - the transpose of right-hand-side matrix
3560
3561 Output Parameter:
3562 . X - the result matrix (dense matrix)
3563
3564 Notes:
3565 Most users should usually employ the simplified KSP interface for linear solvers
3566 instead of working directly with matrix algebra routines such as this.
3567 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3568 at a time.
3569
3570 For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve().
3571
3572 Level: developer
3573
3574 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3575 @*/
MatMatTransposeSolve(Mat A,Mat Bt,Mat X)3576 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3577 {
3578 PetscErrorCode ierr;
3579
3580 PetscFunctionBegin;
3581 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3582 PetscValidType(A,1);
3583 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3584 PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3585 PetscCheckSameComm(A,1,Bt,2);
3586 PetscCheckSameComm(A,1,X,3);
3587
3588 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3589 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);
3590 if (A->rmap->N != Bt->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %D %D",A->rmap->N,Bt->cmap->N);
3591 if (X->cmap->N < Bt->rmap->N) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix");
3592 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3593 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3594 MatCheckPreallocated(A,1);
3595
3596 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3597 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3598 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3599 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3600 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3601 PetscFunctionReturn(0);
3602 }
3603
3604 /*@
3605 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3606 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3607
3608 Neighbor-wise Collective on Mat
3609
3610 Input Parameters:
3611 + mat - the factored matrix
3612 - b - the right-hand-side vector
3613
3614 Output Parameter:
3615 . x - the result vector
3616
3617 Notes:
3618 MatSolve() should be used for most applications, as it performs
3619 a forward solve followed by a backward solve.
3620
3621 The vectors b and x cannot be the same, i.e., one cannot
3622 call MatForwardSolve(A,x,x).
3623
3624 For matrix in seqsbaij format with block size larger than 1,
3625 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3626 MatForwardSolve() solves U^T*D y = b, and
3627 MatBackwardSolve() solves U x = y.
3628 Thus they do not provide a symmetric preconditioner.
3629
3630 Most users should employ the simplified KSP interface for linear solvers
3631 instead of working directly with matrix algebra routines such as this.
3632 See, e.g., KSPCreate().
3633
3634 Level: developer
3635
3636 .seealso: MatSolve(), MatBackwardSolve()
3637 @*/
MatForwardSolve(Mat mat,Vec b,Vec x)3638 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3639 {
3640 PetscErrorCode ierr;
3641
3642 PetscFunctionBegin;
3643 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3644 PetscValidType(mat,1);
3645 PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3646 PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3647 PetscCheckSameComm(mat,1,b,2);
3648 PetscCheckSameComm(mat,1,x,3);
3649 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3650 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);
3651 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);
3652 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);
3653 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3654 MatCheckPreallocated(mat,1);
3655
3656 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3657 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3658 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3659 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3660 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3661 PetscFunctionReturn(0);
3662 }
3663
3664 /*@
3665 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3666 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3667
3668 Neighbor-wise Collective on Mat
3669
3670 Input Parameters:
3671 + mat - the factored matrix
3672 - b - the right-hand-side vector
3673
3674 Output Parameter:
3675 . x - the result vector
3676
3677 Notes:
3678 MatSolve() should be used for most applications, as it performs
3679 a forward solve followed by a backward solve.
3680
3681 The vectors b and x cannot be the same. I.e., one cannot
3682 call MatBackwardSolve(A,x,x).
3683
3684 For matrix in seqsbaij format with block size larger than 1,
3685 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3686 MatForwardSolve() solves U^T*D y = b, and
3687 MatBackwardSolve() solves U x = y.
3688 Thus they do not provide a symmetric preconditioner.
3689
3690 Most users should employ the simplified KSP interface for linear solvers
3691 instead of working directly with matrix algebra routines such as this.
3692 See, e.g., KSPCreate().
3693
3694 Level: developer
3695
3696 .seealso: MatSolve(), MatForwardSolve()
3697 @*/
MatBackwardSolve(Mat mat,Vec b,Vec x)3698 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3699 {
3700 PetscErrorCode ierr;
3701
3702 PetscFunctionBegin;
3703 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3704 PetscValidType(mat,1);
3705 PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3706 PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3707 PetscCheckSameComm(mat,1,b,2);
3708 PetscCheckSameComm(mat,1,x,3);
3709 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3710 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);
3711 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);
3712 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);
3713 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3714 MatCheckPreallocated(mat,1);
3715
3716 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3717 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3718 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3719 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3720 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3721 PetscFunctionReturn(0);
3722 }
3723
3724 /*@
3725 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3726
3727 Neighbor-wise Collective on Mat
3728
3729 Input Parameters:
3730 + mat - the factored matrix
3731 . b - the right-hand-side vector
3732 - y - the vector to be added to
3733
3734 Output Parameter:
3735 . x - the result vector
3736
3737 Notes:
3738 The vectors b and x cannot be the same. I.e., one cannot
3739 call MatSolveAdd(A,x,y,x).
3740
3741 Most users should employ the simplified KSP interface for linear solvers
3742 instead of working directly with matrix algebra routines such as this.
3743 See, e.g., KSPCreate().
3744
3745 Level: developer
3746
3747 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3748 @*/
MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)3749 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3750 {
3751 PetscScalar one = 1.0;
3752 Vec tmp;
3753 PetscErrorCode ierr;
3754
3755 PetscFunctionBegin;
3756 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3757 PetscValidType(mat,1);
3758 PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3759 PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3760 PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3761 PetscCheckSameComm(mat,1,b,2);
3762 PetscCheckSameComm(mat,1,y,2);
3763 PetscCheckSameComm(mat,1,x,3);
3764 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3765 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);
3766 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);
3767 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);
3768 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);
3769 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);
3770 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3771 MatCheckPreallocated(mat,1);
3772
3773 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3774 if (mat->factorerrortype) {
3775 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3776 ierr = VecSetInf(x);CHKERRQ(ierr);
3777 } else if (mat->ops->solveadd) {
3778 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3779 } else {
3780 /* do the solve then the add manually */
3781 if (x != y) {
3782 ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3783 ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3784 } else {
3785 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3786 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3787 ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3788 ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3789 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3790 ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3791 }
3792 }
3793 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3794 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3795 PetscFunctionReturn(0);
3796 }
3797
3798 /*@
3799 MatSolveTranspose - Solves A' x = b, given a factored matrix.
3800
3801 Neighbor-wise Collective on Mat
3802
3803 Input Parameters:
3804 + mat - the factored matrix
3805 - b - the right-hand-side vector
3806
3807 Output Parameter:
3808 . x - the result vector
3809
3810 Notes:
3811 The vectors b and x cannot be the same. I.e., one cannot
3812 call MatSolveTranspose(A,x,x).
3813
3814 Most users should employ the simplified KSP interface for linear solvers
3815 instead of working directly with matrix algebra routines such as this.
3816 See, e.g., KSPCreate().
3817
3818 Level: developer
3819
3820 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3821 @*/
MatSolveTranspose(Mat mat,Vec b,Vec x)3822 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3823 {
3824 PetscErrorCode ierr;
3825
3826 PetscFunctionBegin;
3827 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3828 PetscValidType(mat,1);
3829 PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3830 PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3831 PetscCheckSameComm(mat,1,b,2);
3832 PetscCheckSameComm(mat,1,x,3);
3833 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3834 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);
3835 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);
3836 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3837 MatCheckPreallocated(mat,1);
3838 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3839 if (mat->factorerrortype) {
3840 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3841 ierr = VecSetInf(x);CHKERRQ(ierr);
3842 } else {
3843 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3844 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3845 }
3846 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3847 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3848 PetscFunctionReturn(0);
3849 }
3850
3851 /*@
3852 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3853 factored matrix.
3854
3855 Neighbor-wise Collective on Mat
3856
3857 Input Parameters:
3858 + mat - the factored matrix
3859 . b - the right-hand-side vector
3860 - y - the vector to be added to
3861
3862 Output Parameter:
3863 . x - the result vector
3864
3865 Notes:
3866 The vectors b and x cannot be the same. I.e., one cannot
3867 call MatSolveTransposeAdd(A,x,y,x).
3868
3869 Most users should employ the simplified KSP interface for linear solvers
3870 instead of working directly with matrix algebra routines such as this.
3871 See, e.g., KSPCreate().
3872
3873 Level: developer
3874
3875 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3876 @*/
MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)3877 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3878 {
3879 PetscScalar one = 1.0;
3880 PetscErrorCode ierr;
3881 Vec tmp;
3882
3883 PetscFunctionBegin;
3884 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3885 PetscValidType(mat,1);
3886 PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3887 PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3888 PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3889 PetscCheckSameComm(mat,1,b,2);
3890 PetscCheckSameComm(mat,1,y,3);
3891 PetscCheckSameComm(mat,1,x,4);
3892 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3893 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);
3894 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);
3895 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);
3896 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);
3897 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3898 MatCheckPreallocated(mat,1);
3899
3900 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3901 if (mat->factorerrortype) {
3902 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3903 ierr = VecSetInf(x);CHKERRQ(ierr);
3904 } else if (mat->ops->solvetransposeadd){
3905 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3906 } else {
3907 /* do the solve then the add manually */
3908 if (x != y) {
3909 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3910 ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3911 } else {
3912 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3913 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3914 ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3915 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3916 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3917 ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3918 }
3919 }
3920 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3921 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3922 PetscFunctionReturn(0);
3923 }
3924 /* ----------------------------------------------------------------*/
3925
3926 /*@
3927 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3928
3929 Neighbor-wise Collective on Mat
3930
3931 Input Parameters:
3932 + mat - the matrix
3933 . b - the right hand side
3934 . omega - the relaxation factor
3935 . flag - flag indicating the type of SOR (see below)
3936 . shift - diagonal shift
3937 . its - the number of iterations
3938 - lits - the number of local iterations
3939
3940 Output Parameters:
3941 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3942
3943 SOR Flags:
3944 + SOR_FORWARD_SWEEP - forward SOR
3945 . SOR_BACKWARD_SWEEP - backward SOR
3946 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3947 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3948 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3949 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3950 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3951 upper/lower triangular part of matrix to
3952 vector (with omega)
3953 - SOR_ZERO_INITIAL_GUESS - zero initial guess
3954
3955 Notes:
3956 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3957 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3958 on each processor.
3959
3960 Application programmers will not generally use MatSOR() directly,
3961 but instead will employ the KSP/PC interface.
3962
3963 Notes:
3964 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3965
3966 Notes for Advanced Users:
3967 The flags are implemented as bitwise inclusive or operations.
3968 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3969 to specify a zero initial guess for SSOR.
3970
3971 Most users should employ the simplified KSP interface for linear solvers
3972 instead of working directly with matrix algebra routines such as this.
3973 See, e.g., KSPCreate().
3974
3975 Vectors x and b CANNOT be the same
3976
3977 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3978
3979 Level: developer
3980
3981 @*/
MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)3982 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3983 {
3984 PetscErrorCode ierr;
3985
3986 PetscFunctionBegin;
3987 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3988 PetscValidType(mat,1);
3989 PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3990 PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3991 PetscCheckSameComm(mat,1,b,2);
3992 PetscCheckSameComm(mat,1,x,8);
3993 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3994 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3995 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3996 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);
3997 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);
3998 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);
3999 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4000 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4001 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4002
4003 MatCheckPreallocated(mat,1);
4004 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4005 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4006 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4007 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4008 PetscFunctionReturn(0);
4009 }
4010
4011 /*
4012 Default matrix copy routine.
4013 */
MatCopy_Basic(Mat A,Mat B,MatStructure str)4014 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4015 {
4016 PetscErrorCode ierr;
4017 PetscInt i,rstart = 0,rend = 0,nz;
4018 const PetscInt *cwork;
4019 const PetscScalar *vwork;
4020
4021 PetscFunctionBegin;
4022 if (B->assembled) {
4023 ierr = MatZeroEntries(B);CHKERRQ(ierr);
4024 }
4025 if (str == SAME_NONZERO_PATTERN) {
4026 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4027 for (i=rstart; i<rend; i++) {
4028 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4029 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4030 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4031 }
4032 } else {
4033 ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
4034 }
4035 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4036 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4037 PetscFunctionReturn(0);
4038 }
4039
4040 /*@
4041 MatCopy - Copies a matrix to another matrix.
4042
4043 Collective on Mat
4044
4045 Input Parameters:
4046 + A - the matrix
4047 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4048
4049 Output Parameter:
4050 . B - where the copy is put
4051
4052 Notes:
4053 If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4054 same nonzero pattern or the routine will crash.
4055
4056 MatCopy() copies the matrix entries of a matrix to another existing
4057 matrix (after first zeroing the second matrix). A related routine is
4058 MatConvert(), which first creates a new matrix and then copies the data.
4059
4060 Level: intermediate
4061
4062 .seealso: MatConvert(), MatDuplicate()
4063
4064 @*/
MatCopy(Mat A,Mat B,MatStructure str)4065 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4066 {
4067 PetscErrorCode ierr;
4068 PetscInt i;
4069
4070 PetscFunctionBegin;
4071 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4072 PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4073 PetscValidType(A,1);
4074 PetscValidType(B,2);
4075 PetscCheckSameComm(A,1,B,2);
4076 MatCheckPreallocated(B,2);
4077 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4078 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4079 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);
4080 MatCheckPreallocated(A,1);
4081 if (A == B) PetscFunctionReturn(0);
4082
4083 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4084 if (A->ops->copy) {
4085 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4086 } else { /* generic conversion */
4087 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4088 }
4089
4090 B->stencil.dim = A->stencil.dim;
4091 B->stencil.noc = A->stencil.noc;
4092 for (i=0; i<=A->stencil.dim; i++) {
4093 B->stencil.dims[i] = A->stencil.dims[i];
4094 B->stencil.starts[i] = A->stencil.starts[i];
4095 }
4096
4097 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4098 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4099 PetscFunctionReturn(0);
4100 }
4101
4102 /*@C
4103 MatConvert - Converts a matrix to another matrix, either of the same
4104 or different type.
4105
4106 Collective on Mat
4107
4108 Input Parameters:
4109 + mat - the matrix
4110 . newtype - new matrix type. Use MATSAME to create a new matrix of the
4111 same type as the original matrix.
4112 - reuse - denotes if the destination matrix is to be created or reused.
4113 Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use
4114 MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused).
4115
4116 Output Parameter:
4117 . M - pointer to place new matrix
4118
4119 Notes:
4120 MatConvert() first creates a new matrix and then copies the data from
4121 the first matrix. A related routine is MatCopy(), which copies the matrix
4122 entries of one matrix to another already existing matrix context.
4123
4124 Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4125 the MPI communicator of the generated matrix is always the same as the communicator
4126 of the input matrix.
4127
4128 Level: intermediate
4129
4130 .seealso: MatCopy(), MatDuplicate()
4131 @*/
MatConvert(Mat mat,MatType newtype,MatReuse reuse,Mat * M)4132 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4133 {
4134 PetscErrorCode ierr;
4135 PetscBool sametype,issame,flg,issymmetric,ishermitian;
4136 char convname[256],mtype[256];
4137 Mat B;
4138
4139 PetscFunctionBegin;
4140 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4141 PetscValidType(mat,1);
4142 PetscValidPointer(M,4);
4143 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4144 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4145 MatCheckPreallocated(mat,1);
4146
4147 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg);CHKERRQ(ierr);
4148 if (flg) newtype = mtype;
4149
4150 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4151 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4152 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4153 if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX");
4154
4155 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) {
4156 ierr = PetscInfo3(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4157 PetscFunctionReturn(0);
4158 }
4159
4160 /* Cache Mat options because some converter use MatHeaderReplace */
4161 issymmetric = mat->symmetric;
4162 ishermitian = mat->hermitian;
4163
4164 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4165 ierr = PetscInfo3(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4166 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4167 } else {
4168 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4169 const char *prefix[3] = {"seq","mpi",""};
4170 PetscInt i;
4171 /*
4172 Order of precedence:
4173 0) See if newtype is a superclass of the current matrix.
4174 1) See if a specialized converter is known to the current matrix.
4175 2) See if a specialized converter is known to the desired matrix class.
4176 3) See if a good general converter is registered for the desired class
4177 (as of 6/27/03 only MATMPIADJ falls into this category).
4178 4) See if a good general converter is known for the current matrix.
4179 5) Use a really basic converter.
4180 */
4181
4182 /* 0) See if newtype is a superclass of the current matrix.
4183 i.e mat is mpiaij and newtype is aij */
4184 for (i=0; i<2; i++) {
4185 ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4186 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4187 ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4188 ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4189 if (flg) {
4190 if (reuse == MAT_INPLACE_MATRIX) {
4191 ierr = PetscInfo(mat,"Early return\n");CHKERRQ(ierr);
4192 PetscFunctionReturn(0);
4193 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4194 ierr = PetscInfo(mat,"Calling MatDuplicate\n");CHKERRQ(ierr);
4195 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4196 PetscFunctionReturn(0);
4197 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4198 ierr = PetscInfo(mat,"Calling MatCopy\n");CHKERRQ(ierr);
4199 ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4200 PetscFunctionReturn(0);
4201 }
4202 }
4203 }
4204 /* 1) See if a specialized converter is known to the current matrix and the desired class */
4205 for (i=0; i<3; i++) {
4206 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4207 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4208 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4209 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4210 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4211 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4212 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4213 ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4214 if (conv) goto foundconv;
4215 }
4216
4217 /* 2) See if a specialized converter is known to the desired matrix class. */
4218 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4219 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4220 ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4221 for (i=0; i<3; i++) {
4222 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4223 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4224 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4225 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4226 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4227 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4228 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4229 ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4230 if (conv) {
4231 ierr = MatDestroy(&B);CHKERRQ(ierr);
4232 goto foundconv;
4233 }
4234 }
4235
4236 /* 3) See if a good general converter is registered for the desired class */
4237 conv = B->ops->convertfrom;
4238 ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4239 ierr = MatDestroy(&B);CHKERRQ(ierr);
4240 if (conv) goto foundconv;
4241
4242 /* 4) See if a good general converter is known for the current matrix */
4243 if (mat->ops->convert) conv = mat->ops->convert;
4244
4245 ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4246 if (conv) goto foundconv;
4247
4248 /* 5) Use a really basic converter. */
4249 ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4250 conv = MatConvert_Basic;
4251
4252 foundconv:
4253 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4254 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4255 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4256 /* the block sizes must be same if the mappings are copied over */
4257 (*M)->rmap->bs = mat->rmap->bs;
4258 (*M)->cmap->bs = mat->cmap->bs;
4259 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4260 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4261 (*M)->rmap->mapping = mat->rmap->mapping;
4262 (*M)->cmap->mapping = mat->cmap->mapping;
4263 }
4264 (*M)->stencil.dim = mat->stencil.dim;
4265 (*M)->stencil.noc = mat->stencil.noc;
4266 for (i=0; i<=mat->stencil.dim; i++) {
4267 (*M)->stencil.dims[i] = mat->stencil.dims[i];
4268 (*M)->stencil.starts[i] = mat->stencil.starts[i];
4269 }
4270 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4271 }
4272 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4273
4274 /* Copy Mat options */
4275 if (issymmetric) {
4276 ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
4277 }
4278 if (ishermitian) {
4279 ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
4280 }
4281 PetscFunctionReturn(0);
4282 }
4283
4284 /*@C
4285 MatFactorGetSolverType - Returns name of the package providing the factorization routines
4286
4287 Not Collective
4288
4289 Input Parameter:
4290 . mat - the matrix, must be a factored matrix
4291
4292 Output Parameter:
4293 . type - the string name of the package (do not free this string)
4294
4295 Notes:
4296 In Fortran you pass in a empty string and the package name will be copied into it.
4297 (Make sure the string is long enough)
4298
4299 Level: intermediate
4300
4301 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4302 @*/
MatFactorGetSolverType(Mat mat,MatSolverType * type)4303 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4304 {
4305 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4306
4307 PetscFunctionBegin;
4308 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4309 PetscValidType(mat,1);
4310 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4311 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4312 if (!conv) {
4313 *type = MATSOLVERPETSC;
4314 } else {
4315 ierr = (*conv)(mat,type);CHKERRQ(ierr);
4316 }
4317 PetscFunctionReturn(0);
4318 }
4319
4320 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4321 struct _MatSolverTypeForSpecifcType {
4322 MatType mtype;
4323 PetscErrorCode (*createfactor[4])(Mat,MatFactorType,Mat*);
4324 MatSolverTypeForSpecifcType next;
4325 };
4326
4327 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4328 struct _MatSolverTypeHolder {
4329 char *name;
4330 MatSolverTypeForSpecifcType handlers;
4331 MatSolverTypeHolder next;
4332 };
4333
4334 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4335
4336 /*@C
4337 MatSolveTypeRegister - Registers a MatSolverType that works for a particular matrix type
4338
4339 Input Parameters:
4340 + package - name of the package, for example petsc or superlu
4341 . mtype - the matrix type that works with this package
4342 . ftype - the type of factorization supported by the package
4343 - createfactor - routine that will create the factored matrix ready to be used
4344
4345 Level: intermediate
4346
4347 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4348 @*/
MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (* createfactor)(Mat,MatFactorType,Mat *))4349 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*))
4350 {
4351 PetscErrorCode ierr;
4352 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL;
4353 PetscBool flg;
4354 MatSolverTypeForSpecifcType inext,iprev = NULL;
4355
4356 PetscFunctionBegin;
4357 ierr = MatInitializePackage();CHKERRQ(ierr);
4358 if (!next) {
4359 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4360 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4361 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4362 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4363 MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor;
4364 PetscFunctionReturn(0);
4365 }
4366 while (next) {
4367 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4368 if (flg) {
4369 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4370 inext = next->handlers;
4371 while (inext) {
4372 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4373 if (flg) {
4374 inext->createfactor[(int)ftype-1] = createfactor;
4375 PetscFunctionReturn(0);
4376 }
4377 iprev = inext;
4378 inext = inext->next;
4379 }
4380 ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4381 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4382 iprev->next->createfactor[(int)ftype-1] = createfactor;
4383 PetscFunctionReturn(0);
4384 }
4385 prev = next;
4386 next = next->next;
4387 }
4388 ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4389 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4390 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4391 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4392 prev->next->handlers->createfactor[(int)ftype-1] = createfactor;
4393 PetscFunctionReturn(0);
4394 }
4395
4396 /*@C
4397 MatSolveTypeGet - Gets the function that creates the factor matrix if it exist
4398
4399 Input Parameters:
4400 + type - name of the package, for example petsc or superlu
4401 . ftype - the type of factorization supported by the type
4402 - mtype - the matrix type that works with this type
4403
4404 Output Parameters:
4405 + foundtype - PETSC_TRUE if the type was registered
4406 . foundmtype - PETSC_TRUE if the type supports the requested mtype
4407 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found
4408
4409 Level: intermediate
4410
4411 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatSolvePackageRegister), MatGetFactor()
4412 @*/
MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool * foundtype,PetscBool * foundmtype,PetscErrorCode (** createfactor)(Mat,MatFactorType,Mat *))4413 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*))
4414 {
4415 PetscErrorCode ierr;
4416 MatSolverTypeHolder next = MatSolverTypeHolders;
4417 PetscBool flg;
4418 MatSolverTypeForSpecifcType inext;
4419
4420 PetscFunctionBegin;
4421 if (foundtype) *foundtype = PETSC_FALSE;
4422 if (foundmtype) *foundmtype = PETSC_FALSE;
4423 if (createfactor) *createfactor = NULL;
4424
4425 if (type) {
4426 while (next) {
4427 ierr = PetscStrcasecmp(type,next->name,&flg);CHKERRQ(ierr);
4428 if (flg) {
4429 if (foundtype) *foundtype = PETSC_TRUE;
4430 inext = next->handlers;
4431 while (inext) {
4432 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4433 if (flg) {
4434 if (foundmtype) *foundmtype = PETSC_TRUE;
4435 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1];
4436 PetscFunctionReturn(0);
4437 }
4438 inext = inext->next;
4439 }
4440 }
4441 next = next->next;
4442 }
4443 } else {
4444 while (next) {
4445 inext = next->handlers;
4446 while (inext) {
4447 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4448 if (flg && inext->createfactor[(int)ftype-1]) {
4449 if (foundtype) *foundtype = PETSC_TRUE;
4450 if (foundmtype) *foundmtype = PETSC_TRUE;
4451 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1];
4452 PetscFunctionReturn(0);
4453 }
4454 inext = inext->next;
4455 }
4456 next = next->next;
4457 }
4458 }
4459 PetscFunctionReturn(0);
4460 }
4461
MatSolverTypeDestroy(void)4462 PetscErrorCode MatSolverTypeDestroy(void)
4463 {
4464 PetscErrorCode ierr;
4465 MatSolverTypeHolder next = MatSolverTypeHolders,prev;
4466 MatSolverTypeForSpecifcType inext,iprev;
4467
4468 PetscFunctionBegin;
4469 while (next) {
4470 ierr = PetscFree(next->name);CHKERRQ(ierr);
4471 inext = next->handlers;
4472 while (inext) {
4473 ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4474 iprev = inext;
4475 inext = inext->next;
4476 ierr = PetscFree(iprev);CHKERRQ(ierr);
4477 }
4478 prev = next;
4479 next = next->next;
4480 ierr = PetscFree(prev);CHKERRQ(ierr);
4481 }
4482 MatSolverTypeHolders = NULL;
4483 PetscFunctionReturn(0);
4484 }
4485
4486 /*@C
4487 MatFactorGetUseOrdering - Indicates if the factorization uses the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4488
4489 Logically Collective on Mat
4490
4491 Input Parameters:
4492 . mat - the matrix
4493
4494 Output Parameters:
4495 . flg - PETSC_TRUE if uses the ordering
4496
4497 Notes:
4498 Most internal PETSc factorizations use the ordering past to the factorization routine but external
4499 packages do no, thus we want to skip the ordering when it is not needed.
4500
4501 Level: developer
4502
4503 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4504 @*/
MatFactorGetUseOrdering(Mat mat,PetscBool * flg)4505 PetscErrorCode MatFactorGetUseOrdering(Mat mat, PetscBool *flg)
4506 {
4507 PetscFunctionBegin;
4508 *flg = mat->useordering;
4509 PetscFunctionReturn(0);
4510 }
4511
4512 /*@C
4513 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4514
4515 Collective on Mat
4516
4517 Input Parameters:
4518 + mat - the matrix
4519 . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4520 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4521
4522 Output Parameters:
4523 . f - the factor matrix used with MatXXFactorSymbolic() calls
4524
4525 Notes:
4526 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4527 such as pastix, superlu, mumps etc.
4528
4529 PETSc must have been ./configure to use the external solver, using the option --download-package
4530
4531 Developer Notes:
4532 This should actually be called MatCreateFactor() since it creates a new factor object
4533
4534 Level: intermediate
4535
4536 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatFactorGetUseOrdering(), MatSolverTypeRegister()
4537 @*/
MatGetFactor(Mat mat,MatSolverType type,MatFactorType ftype,Mat * f)4538 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4539 {
4540 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4541 PetscBool foundtype,foundmtype;
4542
4543 PetscFunctionBegin;
4544 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4545 PetscValidType(mat,1);
4546
4547 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4548 MatCheckPreallocated(mat,1);
4549
4550 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv);CHKERRQ(ierr);
4551 if (!foundtype) {
4552 if (type) {
4553 SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver type %s for factorization type %s and matrix type %s. Perhaps you must ./configure with --download-%s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name,type);
4554 } else {
4555 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver type for factorization type %s and matrix type %s.",MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4556 }
4557 }
4558 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4559 if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support factorization type %s for matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4560
4561 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4562 PetscFunctionReturn(0);
4563 }
4564
4565 /*@C
4566 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type
4567
4568 Not Collective
4569
4570 Input Parameters:
4571 + mat - the matrix
4572 . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4573 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4574
4575 Output Parameter:
4576 . flg - PETSC_TRUE if the factorization is available
4577
4578 Notes:
4579 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4580 such as pastix, superlu, mumps etc.
4581
4582 PETSc must have been ./configure to use the external solver, using the option --download-package
4583
4584 Developer Notes:
4585 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object
4586
4587 Level: intermediate
4588
4589 .seealso: MatCopy(), MatDuplicate(), MatGetFactor(), MatSolverTypeRegister()
4590 @*/
MatGetFactorAvailable(Mat mat,MatSolverType type,MatFactorType ftype,PetscBool * flg)4591 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg)
4592 {
4593 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4594
4595 PetscFunctionBegin;
4596 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4597 PetscValidType(mat,1);
4598
4599 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4600 MatCheckPreallocated(mat,1);
4601
4602 *flg = PETSC_FALSE;
4603 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4604 if (gconv) {
4605 *flg = PETSC_TRUE;
4606 }
4607 PetscFunctionReturn(0);
4608 }
4609
4610 #include <petscdmtypes.h>
4611
4612 /*@
4613 MatDuplicate - Duplicates a matrix including the non-zero structure.
4614
4615 Collective on Mat
4616
4617 Input Parameters:
4618 + mat - the matrix
4619 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4620 See the manual page for MatDuplicateOption for an explanation of these options.
4621
4622 Output Parameter:
4623 . M - pointer to place new matrix
4624
4625 Level: intermediate
4626
4627 Notes:
4628 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4629 When original mat is a product of matrix operation, e.g., an output of MatMatMult() or MatCreateSubMatrix(), only the simple matrix data structure of mat is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. User should not use MatDuplicate() to create new matrix M if M is intended to be reused as the product of matrix operation.
4630
4631 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4632 @*/
MatDuplicate(Mat mat,MatDuplicateOption op,Mat * M)4633 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4634 {
4635 PetscErrorCode ierr;
4636 Mat B;
4637 PetscInt i;
4638 DM dm;
4639 void (*viewf)(void);
4640
4641 PetscFunctionBegin;
4642 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4643 PetscValidType(mat,1);
4644 PetscValidPointer(M,3);
4645 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4646 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4647 MatCheckPreallocated(mat,1);
4648
4649 *M = NULL;
4650 if (!mat->ops->duplicate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s\n",((PetscObject)mat)->type_name);
4651 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4652 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4653 B = *M;
4654
4655 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4656 if (viewf) {
4657 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4658 }
4659
4660 B->stencil.dim = mat->stencil.dim;
4661 B->stencil.noc = mat->stencil.noc;
4662 for (i=0; i<=mat->stencil.dim; i++) {
4663 B->stencil.dims[i] = mat->stencil.dims[i];
4664 B->stencil.starts[i] = mat->stencil.starts[i];
4665 }
4666
4667 B->nooffproczerorows = mat->nooffproczerorows;
4668 B->nooffprocentries = mat->nooffprocentries;
4669
4670 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4671 if (dm) {
4672 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4673 }
4674 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4675 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4676 PetscFunctionReturn(0);
4677 }
4678
4679 /*@
4680 MatGetDiagonal - Gets the diagonal of a matrix.
4681
4682 Logically Collective on Mat
4683
4684 Input Parameters:
4685 + mat - the matrix
4686 - v - the vector for storing the diagonal
4687
4688 Output Parameter:
4689 . v - the diagonal of the matrix
4690
4691 Level: intermediate
4692
4693 Note:
4694 Currently only correct in parallel for square matrices.
4695
4696 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4697 @*/
MatGetDiagonal(Mat mat,Vec v)4698 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4699 {
4700 PetscErrorCode ierr;
4701
4702 PetscFunctionBegin;
4703 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4704 PetscValidType(mat,1);
4705 PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4706 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4707 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4708 MatCheckPreallocated(mat,1);
4709
4710 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4711 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4712 PetscFunctionReturn(0);
4713 }
4714
4715 /*@C
4716 MatGetRowMin - Gets the minimum value (of the real part) of each
4717 row of the matrix
4718
4719 Logically Collective on Mat
4720
4721 Input Parameters:
4722 . mat - the matrix
4723
4724 Output Parameter:
4725 + v - the vector for storing the maximums
4726 - idx - the indices of the column found for each row (optional)
4727
4728 Level: intermediate
4729
4730 Notes:
4731 The result of this call are the same as if one converted the matrix to dense format
4732 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4733
4734 This code is only implemented for a couple of matrix formats.
4735
4736 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4737 MatGetRowMax()
4738 @*/
MatGetRowMin(Mat mat,Vec v,PetscInt idx[])4739 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4740 {
4741 PetscErrorCode ierr;
4742
4743 PetscFunctionBegin;
4744 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4745 PetscValidType(mat,1);
4746 PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4747 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4748
4749 if (!mat->cmap->N) {
4750 ierr = VecSet(v,PETSC_MAX_REAL);CHKERRQ(ierr);
4751 if (idx) {
4752 PetscInt i,m = mat->rmap->n;
4753 for (i=0; i<m; i++) idx[i] = -1;
4754 }
4755 } else {
4756 if (!mat->ops->getrowmin) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4757 MatCheckPreallocated(mat,1);
4758 }
4759 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4760 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4761 PetscFunctionReturn(0);
4762 }
4763
4764 /*@C
4765 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4766 row of the matrix
4767
4768 Logically Collective on Mat
4769
4770 Input Parameters:
4771 . mat - the matrix
4772
4773 Output Parameter:
4774 + v - the vector for storing the minimums
4775 - idx - the indices of the column found for each row (or NULL if not needed)
4776
4777 Level: intermediate
4778
4779 Notes:
4780 if a row is completely empty or has only 0.0 values then the idx[] value for that
4781 row is 0 (the first column).
4782
4783 This code is only implemented for a couple of matrix formats.
4784
4785 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4786 @*/
MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])4787 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4788 {
4789 PetscErrorCode ierr;
4790
4791 PetscFunctionBegin;
4792 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4793 PetscValidType(mat,1);
4794 PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4795 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4796 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4797
4798 if (!mat->cmap->N) {
4799 ierr = VecSet(v,0.0);CHKERRQ(ierr);
4800 if (idx) {
4801 PetscInt i,m = mat->rmap->n;
4802 for (i=0; i<m; i++) idx[i] = -1;
4803 }
4804 } else {
4805 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4806 MatCheckPreallocated(mat,1);
4807 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4808 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4809 }
4810 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4811 PetscFunctionReturn(0);
4812 }
4813
4814 /*@C
4815 MatGetRowMax - Gets the maximum value (of the real part) of each
4816 row of the matrix
4817
4818 Logically Collective on Mat
4819
4820 Input Parameters:
4821 . mat - the matrix
4822
4823 Output Parameter:
4824 + v - the vector for storing the maximums
4825 - idx - the indices of the column found for each row (optional)
4826
4827 Level: intermediate
4828
4829 Notes:
4830 The result of this call are the same as if one converted the matrix to dense format
4831 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4832
4833 This code is only implemented for a couple of matrix formats.
4834
4835 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4836 @*/
MatGetRowMax(Mat mat,Vec v,PetscInt idx[])4837 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4838 {
4839 PetscErrorCode ierr;
4840
4841 PetscFunctionBegin;
4842 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4843 PetscValidType(mat,1);
4844 PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4845 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4846
4847 if (!mat->cmap->N) {
4848 ierr = VecSet(v,PETSC_MIN_REAL);CHKERRQ(ierr);
4849 if (idx) {
4850 PetscInt i,m = mat->rmap->n;
4851 for (i=0; i<m; i++) idx[i] = -1;
4852 }
4853 } else {
4854 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4855 MatCheckPreallocated(mat,1);
4856 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4857 }
4858 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4859 PetscFunctionReturn(0);
4860 }
4861
4862 /*@C
4863 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4864 row of the matrix
4865
4866 Logically Collective on Mat
4867
4868 Input Parameters:
4869 . mat - the matrix
4870
4871 Output Parameter:
4872 + v - the vector for storing the maximums
4873 - idx - the indices of the column found for each row (or NULL if not needed)
4874
4875 Level: intermediate
4876
4877 Notes:
4878 if a row is completely empty or has only 0.0 values then the idx[] value for that
4879 row is 0 (the first column).
4880
4881 This code is only implemented for a couple of matrix formats.
4882
4883 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4884 @*/
MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])4885 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4886 {
4887 PetscErrorCode ierr;
4888
4889 PetscFunctionBegin;
4890 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4891 PetscValidType(mat,1);
4892 PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4893 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4894
4895 if (!mat->cmap->N) {
4896 ierr = VecSet(v,0.0);CHKERRQ(ierr);
4897 if (idx) {
4898 PetscInt i,m = mat->rmap->n;
4899 for (i=0; i<m; i++) idx[i] = -1;
4900 }
4901 } else {
4902 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4903 MatCheckPreallocated(mat,1);
4904 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
4905 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4906 }
4907 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4908 PetscFunctionReturn(0);
4909 }
4910
4911 /*@
4912 MatGetRowSum - Gets the sum of each row of the matrix
4913
4914 Logically or Neighborhood Collective on Mat
4915
4916 Input Parameters:
4917 . mat - the matrix
4918
4919 Output Parameter:
4920 . v - the vector for storing the sum of rows
4921
4922 Level: intermediate
4923
4924 Notes:
4925 This code is slow since it is not currently specialized for different formats
4926
4927 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4928 @*/
MatGetRowSum(Mat mat,Vec v)4929 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4930 {
4931 Vec ones;
4932 PetscErrorCode ierr;
4933
4934 PetscFunctionBegin;
4935 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4936 PetscValidType(mat,1);
4937 PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4938 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4939 MatCheckPreallocated(mat,1);
4940 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4941 ierr = VecSet(ones,1.);CHKERRQ(ierr);
4942 ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4943 ierr = VecDestroy(&ones);CHKERRQ(ierr);
4944 PetscFunctionReturn(0);
4945 }
4946
4947 /*@
4948 MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4949
4950 Collective on Mat
4951
4952 Input Parameter:
4953 + mat - the matrix to transpose
4954 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4955
4956 Output Parameters:
4957 . B - the transpose
4958
4959 Notes:
4960 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4961
4962 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4963
4964 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4965
4966 Level: intermediate
4967
4968 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4969 @*/
MatTranspose(Mat mat,MatReuse reuse,Mat * B)4970 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4971 {
4972 PetscErrorCode ierr;
4973
4974 PetscFunctionBegin;
4975 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4976 PetscValidType(mat,1);
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");
4979 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4980 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4981 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4982 MatCheckPreallocated(mat,1);
4983
4984 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4985 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4986 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4987 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4988 PetscFunctionReturn(0);
4989 }
4990
4991 /*@
4992 MatIsTranspose - Test whether a matrix is another one's transpose,
4993 or its own, in which case it tests symmetry.
4994
4995 Collective on Mat
4996
4997 Input Parameter:
4998 + A - the matrix to test
4999 - B - the matrix to test against, this can equal the first parameter
5000
5001 Output Parameters:
5002 . flg - the result
5003
5004 Notes:
5005 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5006 has a running time of the order of the number of nonzeros; the parallel
5007 test involves parallel copies of the block-offdiagonal parts of the matrix.
5008
5009 Level: intermediate
5010
5011 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
5012 @*/
MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool * flg)5013 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
5014 {
5015 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5016
5017 PetscFunctionBegin;
5018 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5019 PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5020 PetscValidBoolPointer(flg,3);
5021 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
5022 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
5023 *flg = PETSC_FALSE;
5024 if (f && g) {
5025 if (f == g) {
5026 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5027 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
5028 } else {
5029 MatType mattype;
5030 if (!f) {
5031 ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
5032 } else {
5033 ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
5034 }
5035 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype);
5036 }
5037 PetscFunctionReturn(0);
5038 }
5039
5040 /*@
5041 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5042
5043 Collective on Mat
5044
5045 Input Parameter:
5046 + mat - the matrix to transpose and complex conjugate
5047 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
5048
5049 Output Parameters:
5050 . B - the Hermitian
5051
5052 Level: intermediate
5053
5054 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5055 @*/
MatHermitianTranspose(Mat mat,MatReuse reuse,Mat * B)5056 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5057 {
5058 PetscErrorCode ierr;
5059
5060 PetscFunctionBegin;
5061 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5062 #if defined(PETSC_USE_COMPLEX)
5063 ierr = MatConjugate(*B);CHKERRQ(ierr);
5064 #endif
5065 PetscFunctionReturn(0);
5066 }
5067
5068 /*@
5069 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5070
5071 Collective on Mat
5072
5073 Input Parameter:
5074 + A - the matrix to test
5075 - B - the matrix to test against, this can equal the first parameter
5076
5077 Output Parameters:
5078 . flg - the result
5079
5080 Notes:
5081 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5082 has a running time of the order of the number of nonzeros; the parallel
5083 test involves parallel copies of the block-offdiagonal parts of the matrix.
5084
5085 Level: intermediate
5086
5087 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5088 @*/
MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool * flg)5089 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
5090 {
5091 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5092
5093 PetscFunctionBegin;
5094 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5095 PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5096 PetscValidBoolPointer(flg,3);
5097 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5098 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5099 if (f && g) {
5100 if (f==g) {
5101 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5102 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5103 }
5104 PetscFunctionReturn(0);
5105 }
5106
5107 /*@
5108 MatPermute - Creates a new matrix with rows and columns permuted from the
5109 original.
5110
5111 Collective on Mat
5112
5113 Input Parameters:
5114 + mat - the matrix to permute
5115 . row - row permutation, each processor supplies only the permutation for its rows
5116 - col - column permutation, each processor supplies only the permutation for its columns
5117
5118 Output Parameters:
5119 . B - the permuted matrix
5120
5121 Level: advanced
5122
5123 Note:
5124 The index sets map from row/col of permuted matrix to row/col of original matrix.
5125 The index sets should be on the same communicator as Mat and have the same local sizes.
5126
5127 .seealso: MatGetOrdering(), ISAllGather()
5128
5129 @*/
MatPermute(Mat mat,IS row,IS col,Mat * B)5130 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5131 {
5132 PetscErrorCode ierr;
5133
5134 PetscFunctionBegin;
5135 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5136 PetscValidType(mat,1);
5137 PetscValidHeaderSpecific(row,IS_CLASSID,2);
5138 PetscValidHeaderSpecific(col,IS_CLASSID,3);
5139 PetscValidPointer(B,4);
5140 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5141 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5142 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5143 MatCheckPreallocated(mat,1);
5144
5145 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5146 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5147 PetscFunctionReturn(0);
5148 }
5149
5150 /*@
5151 MatEqual - Compares two matrices.
5152
5153 Collective on Mat
5154
5155 Input Parameters:
5156 + A - the first matrix
5157 - B - the second matrix
5158
5159 Output Parameter:
5160 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5161
5162 Level: intermediate
5163
5164 @*/
MatEqual(Mat A,Mat B,PetscBool * flg)5165 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
5166 {
5167 PetscErrorCode ierr;
5168
5169 PetscFunctionBegin;
5170 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5171 PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5172 PetscValidType(A,1);
5173 PetscValidType(B,2);
5174 PetscValidBoolPointer(flg,3);
5175 PetscCheckSameComm(A,1,B,2);
5176 MatCheckPreallocated(B,2);
5177 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5178 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5179 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);
5180 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5181 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5182 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);
5183 MatCheckPreallocated(A,1);
5184
5185 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5186 PetscFunctionReturn(0);
5187 }
5188
5189 /*@
5190 MatDiagonalScale - Scales a matrix on the left and right by diagonal
5191 matrices that are stored as vectors. Either of the two scaling
5192 matrices can be NULL.
5193
5194 Collective on Mat
5195
5196 Input Parameters:
5197 + mat - the matrix to be scaled
5198 . l - the left scaling vector (or NULL)
5199 - r - the right scaling vector (or NULL)
5200
5201 Notes:
5202 MatDiagonalScale() computes A = LAR, where
5203 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5204 The L scales the rows of the matrix, the R scales the columns of the matrix.
5205
5206 Level: intermediate
5207
5208
5209 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5210 @*/
MatDiagonalScale(Mat mat,Vec l,Vec r)5211 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5212 {
5213 PetscErrorCode ierr;
5214
5215 PetscFunctionBegin;
5216 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5217 PetscValidType(mat,1);
5218 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5219 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5220 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5221 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5222 MatCheckPreallocated(mat,1);
5223 if (!l && !r) PetscFunctionReturn(0);
5224
5225 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5226 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5227 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5228 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5229 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5230 PetscFunctionReturn(0);
5231 }
5232
5233 /*@
5234 MatScale - Scales all elements of a matrix by a given number.
5235
5236 Logically Collective on Mat
5237
5238 Input Parameters:
5239 + mat - the matrix to be scaled
5240 - a - the scaling value
5241
5242 Output Parameter:
5243 . mat - the scaled matrix
5244
5245 Level: intermediate
5246
5247 .seealso: MatDiagonalScale()
5248 @*/
MatScale(Mat mat,PetscScalar a)5249 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5250 {
5251 PetscErrorCode ierr;
5252
5253 PetscFunctionBegin;
5254 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5255 PetscValidType(mat,1);
5256 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5257 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5258 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5259 PetscValidLogicalCollectiveScalar(mat,a,2);
5260 MatCheckPreallocated(mat,1);
5261
5262 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5263 if (a != (PetscScalar)1.0) {
5264 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5265 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5266 }
5267 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5268 PetscFunctionReturn(0);
5269 }
5270
5271 /*@
5272 MatNorm - Calculates various norms of a matrix.
5273
5274 Collective on Mat
5275
5276 Input Parameters:
5277 + mat - the matrix
5278 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5279
5280 Output Parameters:
5281 . nrm - the resulting norm
5282
5283 Level: intermediate
5284
5285 @*/
MatNorm(Mat mat,NormType type,PetscReal * nrm)5286 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5287 {
5288 PetscErrorCode ierr;
5289
5290 PetscFunctionBegin;
5291 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5292 PetscValidType(mat,1);
5293 PetscValidScalarPointer(nrm,3);
5294
5295 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5296 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5297 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5298 MatCheckPreallocated(mat,1);
5299
5300 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5301 PetscFunctionReturn(0);
5302 }
5303
5304 /*
5305 This variable is used to prevent counting of MatAssemblyBegin() that
5306 are called from within a MatAssemblyEnd().
5307 */
5308 static PetscInt MatAssemblyEnd_InUse = 0;
5309 /*@
5310 MatAssemblyBegin - Begins assembling the matrix. This routine should
5311 be called after completing all calls to MatSetValues().
5312
5313 Collective on Mat
5314
5315 Input Parameters:
5316 + mat - the matrix
5317 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5318
5319 Notes:
5320 MatSetValues() generally caches the values. The matrix is ready to
5321 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5322 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5323 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5324 using the matrix.
5325
5326 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5327 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
5328 a global collective operation requring all processes that share the matrix.
5329
5330 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5331 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5332 before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5333
5334 Level: beginner
5335
5336 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5337 @*/
MatAssemblyBegin(Mat mat,MatAssemblyType type)5338 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5339 {
5340 PetscErrorCode ierr;
5341
5342 PetscFunctionBegin;
5343 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5344 PetscValidType(mat,1);
5345 MatCheckPreallocated(mat,1);
5346 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5347 if (mat->assembled) {
5348 mat->was_assembled = PETSC_TRUE;
5349 mat->assembled = PETSC_FALSE;
5350 }
5351
5352 if (!MatAssemblyEnd_InUse) {
5353 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5354 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5355 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5356 } else if (mat->ops->assemblybegin) {
5357 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5358 }
5359 PetscFunctionReturn(0);
5360 }
5361
5362 /*@
5363 MatAssembled - Indicates if a matrix has been assembled and is ready for
5364 use; for example, in matrix-vector product.
5365
5366 Not Collective
5367
5368 Input Parameter:
5369 . mat - the matrix
5370
5371 Output Parameter:
5372 . assembled - PETSC_TRUE or PETSC_FALSE
5373
5374 Level: advanced
5375
5376 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5377 @*/
MatAssembled(Mat mat,PetscBool * assembled)5378 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
5379 {
5380 PetscFunctionBegin;
5381 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5382 PetscValidPointer(assembled,2);
5383 *assembled = mat->assembled;
5384 PetscFunctionReturn(0);
5385 }
5386
5387 /*@
5388 MatAssemblyEnd - Completes assembling the matrix. This routine should
5389 be called after MatAssemblyBegin().
5390
5391 Collective on Mat
5392
5393 Input Parameters:
5394 + mat - the matrix
5395 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5396
5397 Options Database Keys:
5398 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5399 . -mat_view ::ascii_info_detail - Prints more detailed info
5400 . -mat_view - Prints matrix in ASCII format
5401 . -mat_view ::ascii_matlab - Prints matrix in Matlab format
5402 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5403 . -display <name> - Sets display name (default is host)
5404 . -draw_pause <sec> - Sets number of seconds to pause after display
5405 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab)
5406 . -viewer_socket_machine <machine> - Machine to use for socket
5407 . -viewer_socket_port <port> - Port number to use for socket
5408 - -mat_view binary:filename[:append] - Save matrix to file in binary format
5409
5410 Notes:
5411 MatSetValues() generally caches the values. The matrix is ready to
5412 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5413 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5414 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5415 using the matrix.
5416
5417 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5418 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5419 before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5420
5421 Level: beginner
5422
5423 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5424 @*/
MatAssemblyEnd(Mat mat,MatAssemblyType type)5425 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5426 {
5427 PetscErrorCode ierr;
5428 static PetscInt inassm = 0;
5429 PetscBool flg = PETSC_FALSE;
5430
5431 PetscFunctionBegin;
5432 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5433 PetscValidType(mat,1);
5434
5435 inassm++;
5436 MatAssemblyEnd_InUse++;
5437 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5438 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5439 if (mat->ops->assemblyend) {
5440 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5441 }
5442 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5443 } else if (mat->ops->assemblyend) {
5444 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5445 }
5446
5447 /* Flush assembly is not a true assembly */
5448 if (type != MAT_FLUSH_ASSEMBLY) {
5449 mat->num_ass++;
5450 mat->assembled = PETSC_TRUE;
5451 mat->ass_nonzerostate = mat->nonzerostate;
5452 }
5453
5454 mat->insertmode = NOT_SET_VALUES;
5455 MatAssemblyEnd_InUse--;
5456 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5457 if (!mat->symmetric_eternal) {
5458 mat->symmetric_set = PETSC_FALSE;
5459 mat->hermitian_set = PETSC_FALSE;
5460 mat->structurally_symmetric_set = PETSC_FALSE;
5461 }
5462 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5463 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5464
5465 if (mat->checksymmetryonassembly) {
5466 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5467 if (flg) {
5468 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5469 } else {
5470 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5471 }
5472 }
5473 if (mat->nullsp && mat->checknullspaceonassembly) {
5474 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5475 }
5476 }
5477 inassm--;
5478 PetscFunctionReturn(0);
5479 }
5480
5481 /*@
5482 MatSetOption - Sets a parameter option for a matrix. Some options
5483 may be specific to certain storage formats. Some options
5484 determine how values will be inserted (or added). Sorted,
5485 row-oriented input will generally assemble the fastest. The default
5486 is row-oriented.
5487
5488 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5489
5490 Input Parameters:
5491 + mat - the matrix
5492 . option - the option, one of those listed below (and possibly others),
5493 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5494
5495 Options Describing Matrix Structure:
5496 + MAT_SPD - symmetric positive definite
5497 . MAT_SYMMETRIC - symmetric in terms of both structure and value
5498 . MAT_HERMITIAN - transpose is the complex conjugation
5499 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5500 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5501 you set to be kept with all future use of the matrix
5502 including after MatAssemblyBegin/End() which could
5503 potentially change the symmetry structure, i.e. you
5504 KNOW the matrix will ALWAYS have the property you set.
5505 Note that setting this flag alone implies nothing about whether the matrix is symmetric/Hermitian;
5506 the relevant flags must be set independently.
5507
5508
5509 Options For Use with MatSetValues():
5510 Insert a logically dense subblock, which can be
5511 . MAT_ROW_ORIENTED - row-oriented (default)
5512
5513 Note these options reflect the data you pass in with MatSetValues(); it has
5514 nothing to do with how the data is stored internally in the matrix
5515 data structure.
5516
5517 When (re)assembling a matrix, we can restrict the input for
5518 efficiency/debugging purposes. These options include:
5519 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5520 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5521 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5522 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5523 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5524 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5525 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5526 performance for very large process counts.
5527 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5528 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5529 functions, instead sending only neighbor messages.
5530
5531 Notes:
5532 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5533
5534 Some options are relevant only for particular matrix types and
5535 are thus ignored by others. Other options are not supported by
5536 certain matrix types and will generate an error message if set.
5537
5538 If using a Fortran 77 module to compute a matrix, one may need to
5539 use the column-oriented option (or convert to the row-oriented
5540 format).
5541
5542 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5543 that would generate a new entry in the nonzero structure is instead
5544 ignored. Thus, if memory has not alredy been allocated for this particular
5545 data, then the insertion is ignored. For dense matrices, in which
5546 the entire array is allocated, no entries are ever ignored.
5547 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5548
5549 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5550 that would generate a new entry in the nonzero structure instead produces
5551 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
5552
5553 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5554 that would generate a new entry that has not been preallocated will
5555 instead produce an error. (Currently supported for AIJ and BAIJ formats
5556 only.) This is a useful flag when debugging matrix memory preallocation.
5557 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5558
5559 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5560 other processors should be dropped, rather than stashed.
5561 This is useful if you know that the "owning" processor is also
5562 always generating the correct matrix entries, so that PETSc need
5563 not transfer duplicate entries generated on another processor.
5564
5565 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5566 searches during matrix assembly. When this flag is set, the hash table
5567 is created during the first Matrix Assembly. This hash table is
5568 used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5569 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5570 should be used with MAT_USE_HASH_TABLE flag. This option is currently
5571 supported by MATMPIBAIJ format only.
5572
5573 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5574 are kept in the nonzero structure
5575
5576 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5577 a zero location in the matrix
5578
5579 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5580
5581 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5582 zero row routines and thus improves performance for very large process counts.
5583
5584 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5585 part of the matrix (since they should match the upper triangular part).
5586
5587 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a
5588 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common
5589 with finite difference schemes with non-periodic boundary conditions.
5590 Notes:
5591 Can only be called after MatSetSizes() and MatSetType() have been set.
5592
5593 Level: intermediate
5594
5595 .seealso: MatOption, Mat
5596
5597 @*/
MatSetOption(Mat mat,MatOption op,PetscBool flg)5598 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5599 {
5600 PetscErrorCode ierr;
5601
5602 PetscFunctionBegin;
5603 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5604 PetscValidType(mat,1);
5605 if (op > 0) {
5606 PetscValidLogicalCollectiveEnum(mat,op,2);
5607 PetscValidLogicalCollectiveBool(mat,flg,3);
5608 }
5609
5610 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);
5611 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()");
5612
5613 switch (op) {
5614 case MAT_NO_OFF_PROC_ENTRIES:
5615 mat->nooffprocentries = flg;
5616 PetscFunctionReturn(0);
5617 break;
5618 case MAT_SUBSET_OFF_PROC_ENTRIES:
5619 mat->assembly_subset = flg;
5620 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5621 #if !defined(PETSC_HAVE_MPIUNI)
5622 ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5623 #endif
5624 mat->stash.first_assembly_done = PETSC_FALSE;
5625 }
5626 PetscFunctionReturn(0);
5627 case MAT_NO_OFF_PROC_ZERO_ROWS:
5628 mat->nooffproczerorows = flg;
5629 PetscFunctionReturn(0);
5630 break;
5631 case MAT_SPD:
5632 mat->spd_set = PETSC_TRUE;
5633 mat->spd = flg;
5634 if (flg) {
5635 mat->symmetric = PETSC_TRUE;
5636 mat->structurally_symmetric = PETSC_TRUE;
5637 mat->symmetric_set = PETSC_TRUE;
5638 mat->structurally_symmetric_set = PETSC_TRUE;
5639 }
5640 break;
5641 case MAT_SYMMETRIC:
5642 mat->symmetric = flg;
5643 if (flg) mat->structurally_symmetric = PETSC_TRUE;
5644 mat->symmetric_set = PETSC_TRUE;
5645 mat->structurally_symmetric_set = flg;
5646 #if !defined(PETSC_USE_COMPLEX)
5647 mat->hermitian = flg;
5648 mat->hermitian_set = PETSC_TRUE;
5649 #endif
5650 break;
5651 case MAT_HERMITIAN:
5652 mat->hermitian = flg;
5653 if (flg) mat->structurally_symmetric = PETSC_TRUE;
5654 mat->hermitian_set = PETSC_TRUE;
5655 mat->structurally_symmetric_set = flg;
5656 #if !defined(PETSC_USE_COMPLEX)
5657 mat->symmetric = flg;
5658 mat->symmetric_set = PETSC_TRUE;
5659 #endif
5660 break;
5661 case MAT_STRUCTURALLY_SYMMETRIC:
5662 mat->structurally_symmetric = flg;
5663 mat->structurally_symmetric_set = PETSC_TRUE;
5664 break;
5665 case MAT_SYMMETRY_ETERNAL:
5666 mat->symmetric_eternal = flg;
5667 break;
5668 case MAT_STRUCTURE_ONLY:
5669 mat->structure_only = flg;
5670 break;
5671 case MAT_SORTED_FULL:
5672 mat->sortedfull = flg;
5673 break;
5674 default:
5675 break;
5676 }
5677 if (mat->ops->setoption) {
5678 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5679 }
5680 PetscFunctionReturn(0);
5681 }
5682
5683 /*@
5684 MatGetOption - Gets a parameter option that has been set for a matrix.
5685
5686 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5687
5688 Input Parameters:
5689 + mat - the matrix
5690 - option - the option, this only responds to certain options, check the code for which ones
5691
5692 Output Parameter:
5693 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5694
5695 Notes:
5696 Can only be called after MatSetSizes() and MatSetType() have been set.
5697
5698 Level: intermediate
5699
5700 .seealso: MatOption, MatSetOption()
5701
5702 @*/
MatGetOption(Mat mat,MatOption op,PetscBool * flg)5703 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5704 {
5705 PetscFunctionBegin;
5706 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5707 PetscValidType(mat,1);
5708
5709 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);
5710 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()");
5711
5712 switch (op) {
5713 case MAT_NO_OFF_PROC_ENTRIES:
5714 *flg = mat->nooffprocentries;
5715 break;
5716 case MAT_NO_OFF_PROC_ZERO_ROWS:
5717 *flg = mat->nooffproczerorows;
5718 break;
5719 case MAT_SYMMETRIC:
5720 *flg = mat->symmetric;
5721 break;
5722 case MAT_HERMITIAN:
5723 *flg = mat->hermitian;
5724 break;
5725 case MAT_STRUCTURALLY_SYMMETRIC:
5726 *flg = mat->structurally_symmetric;
5727 break;
5728 case MAT_SYMMETRY_ETERNAL:
5729 *flg = mat->symmetric_eternal;
5730 break;
5731 case MAT_SPD:
5732 *flg = mat->spd;
5733 break;
5734 default:
5735 break;
5736 }
5737 PetscFunctionReturn(0);
5738 }
5739
5740 /*@
5741 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5742 this routine retains the old nonzero structure.
5743
5744 Logically Collective on Mat
5745
5746 Input Parameters:
5747 . mat - the matrix
5748
5749 Level: intermediate
5750
5751 Notes:
5752 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.
5753 See the Performance chapter of the users manual for information on preallocating matrices.
5754
5755 .seealso: MatZeroRows()
5756 @*/
MatZeroEntries(Mat mat)5757 PetscErrorCode MatZeroEntries(Mat mat)
5758 {
5759 PetscErrorCode ierr;
5760
5761 PetscFunctionBegin;
5762 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5763 PetscValidType(mat,1);
5764 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5765 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");
5766 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5767 MatCheckPreallocated(mat,1);
5768
5769 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5770 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5771 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5772 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5773 PetscFunctionReturn(0);
5774 }
5775
5776 /*@
5777 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5778 of a set of rows and columns of a matrix.
5779
5780 Collective on Mat
5781
5782 Input Parameters:
5783 + mat - the matrix
5784 . numRows - the number of rows to remove
5785 . rows - the global row indices
5786 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5787 . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5788 - b - optional vector of right hand side, that will be adjusted by provided solution
5789
5790 Notes:
5791 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5792
5793 The user can set a value in the diagonal entry (or for the AIJ and
5794 row formats can optionally remove the main diagonal entry from the
5795 nonzero structure as well, by passing 0.0 as the final argument).
5796
5797 For the parallel case, all processes that share the matrix (i.e.,
5798 those in the communicator used for matrix creation) MUST call this
5799 routine, regardless of whether any rows being zeroed are owned by
5800 them.
5801
5802 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5803 list only rows local to itself).
5804
5805 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5806
5807 Level: intermediate
5808
5809 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5810 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5811 @*/
MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)5812 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5813 {
5814 PetscErrorCode ierr;
5815
5816 PetscFunctionBegin;
5817 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5818 PetscValidType(mat,1);
5819 if (numRows) PetscValidIntPointer(rows,3);
5820 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5821 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5822 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5823 MatCheckPreallocated(mat,1);
5824
5825 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5826 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5827 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5828 PetscFunctionReturn(0);
5829 }
5830
5831 /*@
5832 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5833 of a set of rows and columns of a matrix.
5834
5835 Collective on Mat
5836
5837 Input Parameters:
5838 + mat - the matrix
5839 . is - the rows to zero
5840 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5841 . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5842 - b - optional vector of right hand side, that will be adjusted by provided solution
5843
5844 Notes:
5845 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5846
5847 The user can set a value in the diagonal entry (or for the AIJ and
5848 row formats can optionally remove the main diagonal entry from the
5849 nonzero structure as well, by passing 0.0 as the final argument).
5850
5851 For the parallel case, all processes that share the matrix (i.e.,
5852 those in the communicator used for matrix creation) MUST call this
5853 routine, regardless of whether any rows being zeroed are owned by
5854 them.
5855
5856 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5857 list only rows local to itself).
5858
5859 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5860
5861 Level: intermediate
5862
5863 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5864 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5865 @*/
MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)5866 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5867 {
5868 PetscErrorCode ierr;
5869 PetscInt numRows;
5870 const PetscInt *rows;
5871
5872 PetscFunctionBegin;
5873 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5874 PetscValidHeaderSpecific(is,IS_CLASSID,2);
5875 PetscValidType(mat,1);
5876 PetscValidType(is,2);
5877 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5878 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5879 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5880 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5881 PetscFunctionReturn(0);
5882 }
5883
5884 /*@
5885 MatZeroRows - Zeros all entries (except possibly the main diagonal)
5886 of a set of rows of a matrix.
5887
5888 Collective on Mat
5889
5890 Input Parameters:
5891 + mat - the matrix
5892 . numRows - the number of rows to remove
5893 . rows - the global row indices
5894 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5895 . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5896 - b - optional vector of right hand side, that will be adjusted by provided solution
5897
5898 Notes:
5899 For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5900 but does not release memory. For the dense and block diagonal
5901 formats this does not alter the nonzero structure.
5902
5903 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5904 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5905 merely zeroed.
5906
5907 The user can set a value in the diagonal entry (or for the AIJ and
5908 row formats can optionally remove the main diagonal entry from the
5909 nonzero structure as well, by passing 0.0 as the final argument).
5910
5911 For the parallel case, all processes that share the matrix (i.e.,
5912 those in the communicator used for matrix creation) MUST call this
5913 routine, regardless of whether any rows being zeroed are owned by
5914 them.
5915
5916 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5917 list only rows local to itself).
5918
5919 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5920 owns that are to be zeroed. This saves a global synchronization in the implementation.
5921
5922 Level: intermediate
5923
5924 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5925 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5926 @*/
MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)5927 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5928 {
5929 PetscErrorCode ierr;
5930
5931 PetscFunctionBegin;
5932 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5933 PetscValidType(mat,1);
5934 if (numRows) PetscValidIntPointer(rows,3);
5935 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5936 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5937 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5938 MatCheckPreallocated(mat,1);
5939
5940 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5941 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5942 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5943 PetscFunctionReturn(0);
5944 }
5945
5946 /*@
5947 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5948 of a set of rows of a matrix.
5949
5950 Collective on Mat
5951
5952 Input Parameters:
5953 + mat - the matrix
5954 . is - index set of rows to remove
5955 . diag - value put in all diagonals of eliminated rows
5956 . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5957 - b - optional vector of right hand side, that will be adjusted by provided solution
5958
5959 Notes:
5960 For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5961 but does not release memory. For the dense and block diagonal
5962 formats this does not alter the nonzero structure.
5963
5964 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5965 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5966 merely zeroed.
5967
5968 The user can set a value in the diagonal entry (or for the AIJ and
5969 row formats can optionally remove the main diagonal entry from the
5970 nonzero structure as well, by passing 0.0 as the final argument).
5971
5972 For the parallel case, all processes that share the matrix (i.e.,
5973 those in the communicator used for matrix creation) MUST call this
5974 routine, regardless of whether any rows being zeroed are owned by
5975 them.
5976
5977 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5978 list only rows local to itself).
5979
5980 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5981 owns that are to be zeroed. This saves a global synchronization in the implementation.
5982
5983 Level: intermediate
5984
5985 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5986 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5987 @*/
MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)5988 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5989 {
5990 PetscInt numRows;
5991 const PetscInt *rows;
5992 PetscErrorCode ierr;
5993
5994 PetscFunctionBegin;
5995 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5996 PetscValidType(mat,1);
5997 PetscValidHeaderSpecific(is,IS_CLASSID,2);
5998 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5999 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6000 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6001 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6002 PetscFunctionReturn(0);
6003 }
6004
6005 /*@
6006 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6007 of a set of rows of a matrix. These rows must be local to the process.
6008
6009 Collective on Mat
6010
6011 Input Parameters:
6012 + mat - the matrix
6013 . numRows - the number of rows to remove
6014 . rows - the grid coordinates (and component number when dof > 1) for matrix rows
6015 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6016 . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6017 - b - optional vector of right hand side, that will be adjusted by provided solution
6018
6019 Notes:
6020 For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6021 but does not release memory. For the dense and block diagonal
6022 formats this does not alter the nonzero structure.
6023
6024 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6025 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6026 merely zeroed.
6027
6028 The user can set a value in the diagonal entry (or for the AIJ and
6029 row formats can optionally remove the main diagonal entry from the
6030 nonzero structure as well, by passing 0.0 as the final argument).
6031
6032 For the parallel case, all processes that share the matrix (i.e.,
6033 those in the communicator used for matrix creation) MUST call this
6034 routine, regardless of whether any rows being zeroed are owned by
6035 them.
6036
6037 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6038 list only rows local to itself).
6039
6040 The grid coordinates are across the entire grid, not just the local portion
6041
6042 In Fortran idxm and idxn should be declared as
6043 $ MatStencil idxm(4,m)
6044 and the values inserted using
6045 $ idxm(MatStencil_i,1) = i
6046 $ idxm(MatStencil_j,1) = j
6047 $ idxm(MatStencil_k,1) = k
6048 $ idxm(MatStencil_c,1) = c
6049 etc
6050
6051 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6052 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6053 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6054 DM_BOUNDARY_PERIODIC boundary type.
6055
6056 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
6057 a single value per point) you can skip filling those indices.
6058
6059 Level: intermediate
6060
6061 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6062 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6063 @*/
MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)6064 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6065 {
6066 PetscInt dim = mat->stencil.dim;
6067 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
6068 PetscInt *dims = mat->stencil.dims+1;
6069 PetscInt *starts = mat->stencil.starts;
6070 PetscInt *dxm = (PetscInt*) rows;
6071 PetscInt *jdxm, i, j, tmp, numNewRows = 0;
6072 PetscErrorCode ierr;
6073
6074 PetscFunctionBegin;
6075 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6076 PetscValidType(mat,1);
6077 if (numRows) PetscValidIntPointer(rows,3);
6078
6079 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6080 for (i = 0; i < numRows; ++i) {
6081 /* Skip unused dimensions (they are ordered k, j, i, c) */
6082 for (j = 0; j < 3-sdim; ++j) dxm++;
6083 /* Local index in X dir */
6084 tmp = *dxm++ - starts[0];
6085 /* Loop over remaining dimensions */
6086 for (j = 0; j < dim-1; ++j) {
6087 /* If nonlocal, set index to be negative */
6088 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6089 /* Update local index */
6090 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6091 }
6092 /* Skip component slot if necessary */
6093 if (mat->stencil.noc) dxm++;
6094 /* Local row number */
6095 if (tmp >= 0) {
6096 jdxm[numNewRows++] = tmp;
6097 }
6098 }
6099 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6100 ierr = PetscFree(jdxm);CHKERRQ(ierr);
6101 PetscFunctionReturn(0);
6102 }
6103
6104 /*@
6105 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6106 of a set of rows and columns of a matrix.
6107
6108 Collective on Mat
6109
6110 Input Parameters:
6111 + mat - the matrix
6112 . numRows - the number of rows/columns to remove
6113 . rows - the grid coordinates (and component number when dof > 1) for matrix rows
6114 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6115 . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6116 - b - optional vector of right hand side, that will be adjusted by provided solution
6117
6118 Notes:
6119 For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6120 but does not release memory. For the dense and block diagonal
6121 formats this does not alter the nonzero structure.
6122
6123 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6124 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6125 merely zeroed.
6126
6127 The user can set a value in the diagonal entry (or for the AIJ and
6128 row formats can optionally remove the main diagonal entry from the
6129 nonzero structure as well, by passing 0.0 as the final argument).
6130
6131 For the parallel case, all processes that share the matrix (i.e.,
6132 those in the communicator used for matrix creation) MUST call this
6133 routine, regardless of whether any rows being zeroed are owned by
6134 them.
6135
6136 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6137 list only rows local to itself, but the row/column numbers are given in local numbering).
6138
6139 The grid coordinates are across the entire grid, not just the local portion
6140
6141 In Fortran idxm and idxn should be declared as
6142 $ MatStencil idxm(4,m)
6143 and the values inserted using
6144 $ idxm(MatStencil_i,1) = i
6145 $ idxm(MatStencil_j,1) = j
6146 $ idxm(MatStencil_k,1) = k
6147 $ idxm(MatStencil_c,1) = c
6148 etc
6149
6150 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6151 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6152 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6153 DM_BOUNDARY_PERIODIC boundary type.
6154
6155 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
6156 a single value per point) you can skip filling those indices.
6157
6158 Level: intermediate
6159
6160 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6161 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6162 @*/
MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)6163 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6164 {
6165 PetscInt dim = mat->stencil.dim;
6166 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
6167 PetscInt *dims = mat->stencil.dims+1;
6168 PetscInt *starts = mat->stencil.starts;
6169 PetscInt *dxm = (PetscInt*) rows;
6170 PetscInt *jdxm, i, j, tmp, numNewRows = 0;
6171 PetscErrorCode ierr;
6172
6173 PetscFunctionBegin;
6174 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6175 PetscValidType(mat,1);
6176 if (numRows) PetscValidIntPointer(rows,3);
6177
6178 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6179 for (i = 0; i < numRows; ++i) {
6180 /* Skip unused dimensions (they are ordered k, j, i, c) */
6181 for (j = 0; j < 3-sdim; ++j) dxm++;
6182 /* Local index in X dir */
6183 tmp = *dxm++ - starts[0];
6184 /* Loop over remaining dimensions */
6185 for (j = 0; j < dim-1; ++j) {
6186 /* If nonlocal, set index to be negative */
6187 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6188 /* Update local index */
6189 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6190 }
6191 /* Skip component slot if necessary */
6192 if (mat->stencil.noc) dxm++;
6193 /* Local row number */
6194 if (tmp >= 0) {
6195 jdxm[numNewRows++] = tmp;
6196 }
6197 }
6198 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6199 ierr = PetscFree(jdxm);CHKERRQ(ierr);
6200 PetscFunctionReturn(0);
6201 }
6202
6203 /*@C
6204 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6205 of a set of rows of a matrix; using local numbering of rows.
6206
6207 Collective on Mat
6208
6209 Input Parameters:
6210 + mat - the matrix
6211 . numRows - the number of rows to remove
6212 . rows - the global row indices
6213 . diag - value put in all diagonals of eliminated rows
6214 . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6215 - b - optional vector of right hand side, that will be adjusted by provided solution
6216
6217 Notes:
6218 Before calling MatZeroRowsLocal(), the user must first set the
6219 local-to-global mapping by calling MatSetLocalToGlobalMapping().
6220
6221 For the AIJ matrix formats this removes the old nonzero structure,
6222 but does not release memory. For the dense and block diagonal
6223 formats this does not alter the nonzero structure.
6224
6225 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6226 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6227 merely zeroed.
6228
6229 The user can set a value in the diagonal entry (or for the AIJ and
6230 row formats can optionally remove the main diagonal entry from the
6231 nonzero structure as well, by passing 0.0 as the final argument).
6232
6233 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6234 owns that are to be zeroed. This saves a global synchronization in the implementation.
6235
6236 Level: intermediate
6237
6238 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6239 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6240 @*/
MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)6241 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6242 {
6243 PetscErrorCode ierr;
6244
6245 PetscFunctionBegin;
6246 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6247 PetscValidType(mat,1);
6248 if (numRows) PetscValidIntPointer(rows,3);
6249 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6250 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6251 MatCheckPreallocated(mat,1);
6252
6253 if (mat->ops->zerorowslocal) {
6254 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6255 } else {
6256 IS is, newis;
6257 const PetscInt *newRows;
6258
6259 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6260 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6261 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6262 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6263 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6264 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6265 ierr = ISDestroy(&newis);CHKERRQ(ierr);
6266 ierr = ISDestroy(&is);CHKERRQ(ierr);
6267 }
6268 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6269 PetscFunctionReturn(0);
6270 }
6271
6272 /*@
6273 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6274 of a set of rows of a matrix; using local numbering of rows.
6275
6276 Collective on Mat
6277
6278 Input Parameters:
6279 + mat - the matrix
6280 . is - index set of rows to remove
6281 . diag - value put in all diagonals of eliminated rows
6282 . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6283 - b - optional vector of right hand side, that will be adjusted by provided solution
6284
6285 Notes:
6286 Before calling MatZeroRowsLocalIS(), the user must first set the
6287 local-to-global mapping by calling MatSetLocalToGlobalMapping().
6288
6289 For the AIJ matrix formats this removes the old nonzero structure,
6290 but does not release memory. For the dense and block diagonal
6291 formats this does not alter the nonzero structure.
6292
6293 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6294 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6295 merely zeroed.
6296
6297 The user can set a value in the diagonal entry (or for the AIJ and
6298 row formats can optionally remove the main diagonal entry from the
6299 nonzero structure as well, by passing 0.0 as the final argument).
6300
6301 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6302 owns that are to be zeroed. This saves a global synchronization in the implementation.
6303
6304 Level: intermediate
6305
6306 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6307 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6308 @*/
MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)6309 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6310 {
6311 PetscErrorCode ierr;
6312 PetscInt numRows;
6313 const PetscInt *rows;
6314
6315 PetscFunctionBegin;
6316 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6317 PetscValidType(mat,1);
6318 PetscValidHeaderSpecific(is,IS_CLASSID,2);
6319 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6320 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6321 MatCheckPreallocated(mat,1);
6322
6323 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6324 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6325 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6326 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6327 PetscFunctionReturn(0);
6328 }
6329
6330 /*@
6331 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6332 of a set of rows and columns of a matrix; using local numbering of rows.
6333
6334 Collective on Mat
6335
6336 Input Parameters:
6337 + mat - the matrix
6338 . numRows - the number of rows to remove
6339 . rows - the global row indices
6340 . diag - value put in all diagonals of eliminated rows
6341 . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6342 - b - optional vector of right hand side, that will be adjusted by provided solution
6343
6344 Notes:
6345 Before calling MatZeroRowsColumnsLocal(), the user must first set the
6346 local-to-global mapping by calling MatSetLocalToGlobalMapping().
6347
6348 The user can set a value in the diagonal entry (or for the AIJ and
6349 row formats can optionally remove the main diagonal entry from the
6350 nonzero structure as well, by passing 0.0 as the final argument).
6351
6352 Level: intermediate
6353
6354 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6355 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6356 @*/
MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)6357 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6358 {
6359 PetscErrorCode ierr;
6360 IS is, newis;
6361 const PetscInt *newRows;
6362
6363 PetscFunctionBegin;
6364 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6365 PetscValidType(mat,1);
6366 if (numRows) PetscValidIntPointer(rows,3);
6367 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6368 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6369 MatCheckPreallocated(mat,1);
6370
6371 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6372 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6373 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6374 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6375 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6376 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6377 ierr = ISDestroy(&newis);CHKERRQ(ierr);
6378 ierr = ISDestroy(&is);CHKERRQ(ierr);
6379 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6380 PetscFunctionReturn(0);
6381 }
6382
6383 /*@
6384 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6385 of a set of rows and columns of a matrix; using local numbering of rows.
6386
6387 Collective on Mat
6388
6389 Input Parameters:
6390 + mat - the matrix
6391 . is - index set of rows to remove
6392 . diag - value put in all diagonals of eliminated rows
6393 . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6394 - b - optional vector of right hand side, that will be adjusted by provided solution
6395
6396 Notes:
6397 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6398 local-to-global mapping by calling MatSetLocalToGlobalMapping().
6399
6400 The user can set a value in the diagonal entry (or for the AIJ and
6401 row formats can optionally remove the main diagonal entry from the
6402 nonzero structure as well, by passing 0.0 as the final argument).
6403
6404 Level: intermediate
6405
6406 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6407 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6408 @*/
MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)6409 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6410 {
6411 PetscErrorCode ierr;
6412 PetscInt numRows;
6413 const PetscInt *rows;
6414
6415 PetscFunctionBegin;
6416 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6417 PetscValidType(mat,1);
6418 PetscValidHeaderSpecific(is,IS_CLASSID,2);
6419 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6420 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6421 MatCheckPreallocated(mat,1);
6422
6423 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6424 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6425 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6426 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6427 PetscFunctionReturn(0);
6428 }
6429
6430 /*@C
6431 MatGetSize - Returns the numbers of rows and columns in a matrix.
6432
6433 Not Collective
6434
6435 Input Parameter:
6436 . mat - the matrix
6437
6438 Output Parameters:
6439 + m - the number of global rows
6440 - n - the number of global columns
6441
6442 Note: both output parameters can be NULL on input.
6443
6444 Level: beginner
6445
6446 .seealso: MatGetLocalSize()
6447 @*/
MatGetSize(Mat mat,PetscInt * m,PetscInt * n)6448 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6449 {
6450 PetscFunctionBegin;
6451 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6452 if (m) *m = mat->rmap->N;
6453 if (n) *n = mat->cmap->N;
6454 PetscFunctionReturn(0);
6455 }
6456
6457 /*@C
6458 MatGetLocalSize - Returns the number of local rows and local columns
6459 of a matrix, that is the local size of the left and right vectors as returned by MatCreateVecs().
6460
6461 Not Collective
6462
6463 Input Parameters:
6464 . mat - the matrix
6465
6466 Output Parameters:
6467 + m - the number of local rows
6468 - n - the number of local columns
6469
6470 Note: both output parameters can be NULL on input.
6471
6472 Level: beginner
6473
6474 .seealso: MatGetSize()
6475 @*/
MatGetLocalSize(Mat mat,PetscInt * m,PetscInt * n)6476 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6477 {
6478 PetscFunctionBegin;
6479 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6480 if (m) PetscValidIntPointer(m,2);
6481 if (n) PetscValidIntPointer(n,3);
6482 if (m) *m = mat->rmap->n;
6483 if (n) *n = mat->cmap->n;
6484 PetscFunctionReturn(0);
6485 }
6486
6487 /*@C
6488 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6489 this processor. (The columns of the "diagonal block")
6490
6491 Not Collective, unless matrix has not been allocated, then collective on Mat
6492
6493 Input Parameters:
6494 . mat - the matrix
6495
6496 Output Parameters:
6497 + m - the global index of the first local column
6498 - n - one more than the global index of the last local column
6499
6500 Notes:
6501 both output parameters can be NULL on input.
6502
6503 Level: developer
6504
6505 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6506
6507 @*/
MatGetOwnershipRangeColumn(Mat mat,PetscInt * m,PetscInt * n)6508 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6509 {
6510 PetscFunctionBegin;
6511 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6512 PetscValidType(mat,1);
6513 if (m) PetscValidIntPointer(m,2);
6514 if (n) PetscValidIntPointer(n,3);
6515 MatCheckPreallocated(mat,1);
6516 if (m) *m = mat->cmap->rstart;
6517 if (n) *n = mat->cmap->rend;
6518 PetscFunctionReturn(0);
6519 }
6520
6521 /*@C
6522 MatGetOwnershipRange - Returns the range of matrix rows owned by
6523 this processor, assuming that the matrix is laid out with the first
6524 n1 rows on the first processor, the next n2 rows on the second, etc.
6525 For certain parallel layouts this range may not be well defined.
6526
6527 Not Collective
6528
6529 Input Parameters:
6530 . mat - the matrix
6531
6532 Output Parameters:
6533 + m - the global index of the first local row
6534 - n - one more than the global index of the last local row
6535
6536 Note: Both output parameters can be NULL on input.
6537 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using
6538 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6539 $ and then MPI_Scan() to calculate prefix sums of the local sizes.
6540
6541 Level: beginner
6542
6543 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6544
6545 @*/
MatGetOwnershipRange(Mat mat,PetscInt * m,PetscInt * n)6546 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6547 {
6548 PetscFunctionBegin;
6549 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6550 PetscValidType(mat,1);
6551 if (m) PetscValidIntPointer(m,2);
6552 if (n) PetscValidIntPointer(n,3);
6553 MatCheckPreallocated(mat,1);
6554 if (m) *m = mat->rmap->rstart;
6555 if (n) *n = mat->rmap->rend;
6556 PetscFunctionReturn(0);
6557 }
6558
6559 /*@C
6560 MatGetOwnershipRanges - Returns the range of matrix rows owned by
6561 each process
6562
6563 Not Collective, unless matrix has not been allocated, then collective on Mat
6564
6565 Input Parameters:
6566 . mat - the matrix
6567
6568 Output Parameters:
6569 . ranges - start of each processors portion plus one more than the total length at the end
6570
6571 Level: beginner
6572
6573 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6574
6575 @*/
MatGetOwnershipRanges(Mat mat,const PetscInt ** ranges)6576 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6577 {
6578 PetscErrorCode ierr;
6579
6580 PetscFunctionBegin;
6581 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6582 PetscValidType(mat,1);
6583 MatCheckPreallocated(mat,1);
6584 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6585 PetscFunctionReturn(0);
6586 }
6587
6588 /*@C
6589 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6590 this processor. (The columns of the "diagonal blocks" for each process)
6591
6592 Not Collective, unless matrix has not been allocated, then collective on Mat
6593
6594 Input Parameters:
6595 . mat - the matrix
6596
6597 Output Parameters:
6598 . ranges - start of each processors portion plus one more then the total length at the end
6599
6600 Level: beginner
6601
6602 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6603
6604 @*/
MatGetOwnershipRangesColumn(Mat mat,const PetscInt ** ranges)6605 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6606 {
6607 PetscErrorCode ierr;
6608
6609 PetscFunctionBegin;
6610 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6611 PetscValidType(mat,1);
6612 MatCheckPreallocated(mat,1);
6613 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6614 PetscFunctionReturn(0);
6615 }
6616
6617 /*@C
6618 MatGetOwnershipIS - Get row and column ownership as index sets
6619
6620 Not Collective
6621
6622 Input Arguments:
6623 . A - matrix of type Elemental or ScaLAPACK
6624
6625 Output Arguments:
6626 + rows - rows in which this process owns elements
6627 - cols - columns in which this process owns elements
6628
6629 Level: intermediate
6630
6631 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6632 @*/
MatGetOwnershipIS(Mat A,IS * rows,IS * cols)6633 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6634 {
6635 PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6636
6637 PetscFunctionBegin;
6638 MatCheckPreallocated(A,1);
6639 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6640 if (f) {
6641 ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6642 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6643 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6644 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6645 }
6646 PetscFunctionReturn(0);
6647 }
6648
6649 /*@C
6650 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6651 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6652 to complete the factorization.
6653
6654 Collective on Mat
6655
6656 Input Parameters:
6657 + mat - the matrix
6658 . row - row permutation
6659 . column - column permutation
6660 - info - structure containing
6661 $ levels - number of levels of fill.
6662 $ expected fill - as ratio of original fill.
6663 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6664 missing diagonal entries)
6665
6666 Output Parameters:
6667 . fact - new matrix that has been symbolically factored
6668
6669 Notes:
6670 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6671
6672 Most users should employ the simplified KSP interface for linear solvers
6673 instead of working directly with matrix algebra routines such as this.
6674 See, e.g., KSPCreate().
6675
6676 Level: developer
6677
6678 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6679 MatGetOrdering(), MatFactorInfo
6680
6681 Note: this uses the definition of level of fill as in Y. Saad, 2003
6682
6683 Developer Note: fortran interface is not autogenerated as the f90
6684 interface defintion cannot be generated correctly [due to MatFactorInfo]
6685
6686 References:
6687 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6688 @*/
MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo * info)6689 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6690 {
6691 PetscErrorCode ierr;
6692
6693 PetscFunctionBegin;
6694 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6695 PetscValidType(mat,1);
6696 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
6697 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
6698 PetscValidPointer(info,4);
6699 PetscValidPointer(fact,5);
6700 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6701 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6702 if (!fact->ops->ilufactorsymbolic) {
6703 MatSolverType stype;
6704 ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
6705 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype);
6706 }
6707 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6708 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6709 MatCheckPreallocated(mat,2);
6710
6711 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6712 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6713 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6714 PetscFunctionReturn(0);
6715 }
6716
6717 /*@C
6718 MatICCFactorSymbolic - Performs symbolic incomplete
6719 Cholesky factorization for a symmetric matrix. Use
6720 MatCholeskyFactorNumeric() to complete the factorization.
6721
6722 Collective on Mat
6723
6724 Input Parameters:
6725 + mat - the matrix
6726 . perm - row and column permutation
6727 - info - structure containing
6728 $ levels - number of levels of fill.
6729 $ expected fill - as ratio of original fill.
6730
6731 Output Parameter:
6732 . fact - the factored matrix
6733
6734 Notes:
6735 Most users should employ the KSP interface for linear solvers
6736 instead of working directly with matrix algebra routines such as this.
6737 See, e.g., KSPCreate().
6738
6739 Level: developer
6740
6741 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6742
6743 Note: this uses the definition of level of fill as in Y. Saad, 2003
6744
6745 Developer Note: fortran interface is not autogenerated as the f90
6746 interface defintion cannot be generated correctly [due to MatFactorInfo]
6747
6748 References:
6749 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6750 @*/
MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo * info)6751 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6752 {
6753 PetscErrorCode ierr;
6754
6755 PetscFunctionBegin;
6756 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6757 PetscValidType(mat,1);
6758 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6759 PetscValidPointer(info,3);
6760 PetscValidPointer(fact,4);
6761 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6762 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6763 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6764 if (!(fact)->ops->iccfactorsymbolic) {
6765 MatSolverType stype;
6766 ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
6767 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype);
6768 }
6769 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6770 MatCheckPreallocated(mat,2);
6771
6772 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6773 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6774 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6775 PetscFunctionReturn(0);
6776 }
6777
6778 /*@C
6779 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6780 points to an array of valid matrices, they may be reused to store the new
6781 submatrices.
6782
6783 Collective on Mat
6784
6785 Input Parameters:
6786 + mat - the matrix
6787 . n - the number of submatrixes to be extracted (on this processor, may be zero)
6788 . irow, icol - index sets of rows and columns to extract
6789 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6790
6791 Output Parameter:
6792 . submat - the array of submatrices
6793
6794 Notes:
6795 MatCreateSubMatrices() can extract ONLY sequential submatrices
6796 (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6797 to extract a parallel submatrix.
6798
6799 Some matrix types place restrictions on the row and column
6800 indices, such as that they be sorted or that they be equal to each other.
6801
6802 The index sets may not have duplicate entries.
6803
6804 When extracting submatrices from a parallel matrix, each processor can
6805 form a different submatrix by setting the rows and columns of its
6806 individual index sets according to the local submatrix desired.
6807
6808 When finished using the submatrices, the user should destroy
6809 them with MatDestroySubMatrices().
6810
6811 MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6812 original matrix has not changed from that last call to MatCreateSubMatrices().
6813
6814 This routine creates the matrices in submat; you should NOT create them before
6815 calling it. It also allocates the array of matrix pointers submat.
6816
6817 For BAIJ matrices the index sets must respect the block structure, that is if they
6818 request one row/column in a block, they must request all rows/columns that are in
6819 that block. For example, if the block size is 2 you cannot request just row 0 and
6820 column 0.
6821
6822 Fortran Note:
6823 The Fortran interface is slightly different from that given below; it
6824 requires one to pass in as submat a Mat (integer) array of size at least n+1.
6825
6826 Level: advanced
6827
6828
6829 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6830 @*/
MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat * submat[])6831 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6832 {
6833 PetscErrorCode ierr;
6834 PetscInt i;
6835 PetscBool eq;
6836
6837 PetscFunctionBegin;
6838 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6839 PetscValidType(mat,1);
6840 if (n) {
6841 PetscValidPointer(irow,3);
6842 PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6843 PetscValidPointer(icol,4);
6844 PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6845 }
6846 PetscValidPointer(submat,6);
6847 if (n && scall == MAT_REUSE_MATRIX) {
6848 PetscValidPointer(*submat,6);
6849 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6850 }
6851 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6852 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6853 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6854 MatCheckPreallocated(mat,1);
6855
6856 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6857 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6858 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6859 for (i=0; i<n; i++) {
6860 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */
6861 ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
6862 if (eq) {
6863 ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
6864 }
6865 }
6866 PetscFunctionReturn(0);
6867 }
6868
6869 /*@C
6870 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6871
6872 Collective on Mat
6873
6874 Input Parameters:
6875 + mat - the matrix
6876 . n - the number of submatrixes to be extracted
6877 . irow, icol - index sets of rows and columns to extract
6878 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6879
6880 Output Parameter:
6881 . submat - the array of submatrices
6882
6883 Level: advanced
6884
6885
6886 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6887 @*/
MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat * submat[])6888 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6889 {
6890 PetscErrorCode ierr;
6891 PetscInt i;
6892 PetscBool eq;
6893
6894 PetscFunctionBegin;
6895 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6896 PetscValidType(mat,1);
6897 if (n) {
6898 PetscValidPointer(irow,3);
6899 PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6900 PetscValidPointer(icol,4);
6901 PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6902 }
6903 PetscValidPointer(submat,6);
6904 if (n && scall == MAT_REUSE_MATRIX) {
6905 PetscValidPointer(*submat,6);
6906 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6907 }
6908 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6909 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6910 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6911 MatCheckPreallocated(mat,1);
6912
6913 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6914 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6915 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6916 for (i=0; i<n; i++) {
6917 ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
6918 if (eq) {
6919 ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
6920 }
6921 }
6922 PetscFunctionReturn(0);
6923 }
6924
6925 /*@C
6926 MatDestroyMatrices - Destroys an array of matrices.
6927
6928 Collective on Mat
6929
6930 Input Parameters:
6931 + n - the number of local matrices
6932 - mat - the matrices (note that this is a pointer to the array of matrices)
6933
6934 Level: advanced
6935
6936 Notes:
6937 Frees not only the matrices, but also the array that contains the matrices
6938 In Fortran will not free the array.
6939
6940 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6941 @*/
MatDestroyMatrices(PetscInt n,Mat * mat[])6942 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6943 {
6944 PetscErrorCode ierr;
6945 PetscInt i;
6946
6947 PetscFunctionBegin;
6948 if (!*mat) PetscFunctionReturn(0);
6949 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6950 PetscValidPointer(mat,2);
6951
6952 for (i=0; i<n; i++) {
6953 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6954 }
6955
6956 /* memory is allocated even if n = 0 */
6957 ierr = PetscFree(*mat);CHKERRQ(ierr);
6958 PetscFunctionReturn(0);
6959 }
6960
6961 /*@C
6962 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6963
6964 Collective on Mat
6965
6966 Input Parameters:
6967 + n - the number of local matrices
6968 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6969 sequence of MatCreateSubMatrices())
6970
6971 Level: advanced
6972
6973 Notes:
6974 Frees not only the matrices, but also the array that contains the matrices
6975 In Fortran will not free the array.
6976
6977 .seealso: MatCreateSubMatrices()
6978 @*/
MatDestroySubMatrices(PetscInt n,Mat * mat[])6979 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6980 {
6981 PetscErrorCode ierr;
6982 Mat mat0;
6983
6984 PetscFunctionBegin;
6985 if (!*mat) PetscFunctionReturn(0);
6986 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6987 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6988 PetscValidPointer(mat,2);
6989
6990 mat0 = (*mat)[0];
6991 if (mat0 && mat0->ops->destroysubmatrices) {
6992 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
6993 } else {
6994 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
6995 }
6996 PetscFunctionReturn(0);
6997 }
6998
6999 /*@C
7000 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7001
7002 Collective on Mat
7003
7004 Input Parameters:
7005 . mat - the matrix
7006
7007 Output Parameter:
7008 . matstruct - the sequential matrix with the nonzero structure of mat
7009
7010 Level: intermediate
7011
7012 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7013 @*/
MatGetSeqNonzeroStructure(Mat mat,Mat * matstruct)7014 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7015 {
7016 PetscErrorCode ierr;
7017
7018 PetscFunctionBegin;
7019 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7020 PetscValidPointer(matstruct,2);
7021
7022 PetscValidType(mat,1);
7023 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7024 MatCheckPreallocated(mat,1);
7025
7026 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7027 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7028 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7029 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7030 PetscFunctionReturn(0);
7031 }
7032
7033 /*@C
7034 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7035
7036 Collective on Mat
7037
7038 Input Parameters:
7039 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7040 sequence of MatGetSequentialNonzeroStructure())
7041
7042 Level: advanced
7043
7044 Notes:
7045 Frees not only the matrices, but also the array that contains the matrices
7046
7047 .seealso: MatGetSeqNonzeroStructure()
7048 @*/
MatDestroySeqNonzeroStructure(Mat * mat)7049 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7050 {
7051 PetscErrorCode ierr;
7052
7053 PetscFunctionBegin;
7054 PetscValidPointer(mat,1);
7055 ierr = MatDestroy(mat);CHKERRQ(ierr);
7056 PetscFunctionReturn(0);
7057 }
7058
7059 /*@
7060 MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7061 replaces the index sets by larger ones that represent submatrices with
7062 additional overlap.
7063
7064 Collective on Mat
7065
7066 Input Parameters:
7067 + mat - the matrix
7068 . n - the number of index sets
7069 . is - the array of index sets (these index sets will changed during the call)
7070 - ov - the additional overlap requested
7071
7072 Options Database:
7073 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7074
7075 Level: developer
7076
7077
7078 .seealso: MatCreateSubMatrices()
7079 @*/
MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)7080 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7081 {
7082 PetscErrorCode ierr;
7083
7084 PetscFunctionBegin;
7085 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7086 PetscValidType(mat,1);
7087 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7088 if (n) {
7089 PetscValidPointer(is,3);
7090 PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7091 }
7092 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7093 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7094 MatCheckPreallocated(mat,1);
7095
7096 if (!ov) PetscFunctionReturn(0);
7097 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7098 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7099 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7100 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7101 PetscFunctionReturn(0);
7102 }
7103
7104
7105 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7106
7107 /*@
7108 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7109 a sub communicator, replaces the index sets by larger ones that represent submatrices with
7110 additional overlap.
7111
7112 Collective on Mat
7113
7114 Input Parameters:
7115 + mat - the matrix
7116 . n - the number of index sets
7117 . is - the array of index sets (these index sets will changed during the call)
7118 - ov - the additional overlap requested
7119
7120 Options Database:
7121 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7122
7123 Level: developer
7124
7125
7126 .seealso: MatCreateSubMatrices()
7127 @*/
MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)7128 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7129 {
7130 PetscInt i;
7131 PetscErrorCode ierr;
7132
7133 PetscFunctionBegin;
7134 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7135 PetscValidType(mat,1);
7136 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7137 if (n) {
7138 PetscValidPointer(is,3);
7139 PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7140 }
7141 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7142 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7143 MatCheckPreallocated(mat,1);
7144 if (!ov) PetscFunctionReturn(0);
7145 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7146 for (i=0; i<n; i++){
7147 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7148 }
7149 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7150 PetscFunctionReturn(0);
7151 }
7152
7153
7154
7155
7156 /*@
7157 MatGetBlockSize - Returns the matrix block size.
7158
7159 Not Collective
7160
7161 Input Parameter:
7162 . mat - the matrix
7163
7164 Output Parameter:
7165 . bs - block size
7166
7167 Notes:
7168 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7169
7170 If the block size has not been set yet this routine returns 1.
7171
7172 Level: intermediate
7173
7174 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7175 @*/
MatGetBlockSize(Mat mat,PetscInt * bs)7176 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7177 {
7178 PetscFunctionBegin;
7179 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7180 PetscValidIntPointer(bs,2);
7181 *bs = PetscAbs(mat->rmap->bs);
7182 PetscFunctionReturn(0);
7183 }
7184
7185 /*@
7186 MatGetBlockSizes - Returns the matrix block row and column sizes.
7187
7188 Not Collective
7189
7190 Input Parameter:
7191 . mat - the matrix
7192
7193 Output Parameter:
7194 + rbs - row block size
7195 - cbs - column block size
7196
7197 Notes:
7198 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7199 If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7200
7201 If a block size has not been set yet this routine returns 1.
7202
7203 Level: intermediate
7204
7205 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7206 @*/
MatGetBlockSizes(Mat mat,PetscInt * rbs,PetscInt * cbs)7207 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7208 {
7209 PetscFunctionBegin;
7210 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7211 if (rbs) PetscValidIntPointer(rbs,2);
7212 if (cbs) PetscValidIntPointer(cbs,3);
7213 if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7214 if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7215 PetscFunctionReturn(0);
7216 }
7217
7218 /*@
7219 MatSetBlockSize - Sets the matrix block size.
7220
7221 Logically Collective on Mat
7222
7223 Input Parameters:
7224 + mat - the matrix
7225 - bs - block size
7226
7227 Notes:
7228 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7229 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7230
7231 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7232 is compatible with the matrix local sizes.
7233
7234 Level: intermediate
7235
7236 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7237 @*/
MatSetBlockSize(Mat mat,PetscInt bs)7238 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7239 {
7240 PetscErrorCode ierr;
7241
7242 PetscFunctionBegin;
7243 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7244 PetscValidLogicalCollectiveInt(mat,bs,2);
7245 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7246 PetscFunctionReturn(0);
7247 }
7248
7249 /*@
7250 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7251
7252 Logically Collective on Mat
7253
7254 Input Parameters:
7255 + mat - the matrix
7256 . nblocks - the number of blocks on this process
7257 - bsizes - the block sizes
7258
7259 Notes:
7260 Currently used by PCVPBJACOBI for SeqAIJ matrices
7261
7262 Level: intermediate
7263
7264 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7265 @*/
MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt * bsizes)7266 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7267 {
7268 PetscErrorCode ierr;
7269 PetscInt i,ncnt = 0, nlocal;
7270
7271 PetscFunctionBegin;
7272 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7273 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7274 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7275 for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7276 if (ncnt != nlocal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %D does not equal local size of matrix %D",ncnt,nlocal);
7277 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7278 mat->nblocks = nblocks;
7279 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7280 ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr);
7281 PetscFunctionReturn(0);
7282 }
7283
7284 /*@C
7285 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7286
7287 Logically Collective on Mat
7288
7289 Input Parameters:
7290 . mat - the matrix
7291
7292 Output Parameters:
7293 + nblocks - the number of blocks on this process
7294 - bsizes - the block sizes
7295
7296 Notes: Currently not supported from Fortran
7297
7298 Level: intermediate
7299
7300 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7301 @*/
MatGetVariableBlockSizes(Mat mat,PetscInt * nblocks,const PetscInt ** bsizes)7302 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7303 {
7304 PetscFunctionBegin;
7305 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7306 *nblocks = mat->nblocks;
7307 *bsizes = mat->bsizes;
7308 PetscFunctionReturn(0);
7309 }
7310
7311 /*@
7312 MatSetBlockSizes - Sets the matrix block row and column sizes.
7313
7314 Logically Collective on Mat
7315
7316 Input Parameters:
7317 + mat - the matrix
7318 . rbs - row block size
7319 - cbs - column block size
7320
7321 Notes:
7322 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7323 If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7324 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7325
7326 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7327 are compatible with the matrix local sizes.
7328
7329 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7330
7331 Level: intermediate
7332
7333 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7334 @*/
MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)7335 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7336 {
7337 PetscErrorCode ierr;
7338
7339 PetscFunctionBegin;
7340 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7341 PetscValidLogicalCollectiveInt(mat,rbs,2);
7342 PetscValidLogicalCollectiveInt(mat,cbs,3);
7343 if (mat->ops->setblocksizes) {
7344 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7345 }
7346 if (mat->rmap->refcnt) {
7347 ISLocalToGlobalMapping l2g = NULL;
7348 PetscLayout nmap = NULL;
7349
7350 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7351 if (mat->rmap->mapping) {
7352 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7353 }
7354 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7355 mat->rmap = nmap;
7356 mat->rmap->mapping = l2g;
7357 }
7358 if (mat->cmap->refcnt) {
7359 ISLocalToGlobalMapping l2g = NULL;
7360 PetscLayout nmap = NULL;
7361
7362 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7363 if (mat->cmap->mapping) {
7364 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7365 }
7366 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7367 mat->cmap = nmap;
7368 mat->cmap->mapping = l2g;
7369 }
7370 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7371 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7372 PetscFunctionReturn(0);
7373 }
7374
7375 /*@
7376 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7377
7378 Logically Collective on Mat
7379
7380 Input Parameters:
7381 + mat - the matrix
7382 . fromRow - matrix from which to copy row block size
7383 - fromCol - matrix from which to copy column block size (can be same as fromRow)
7384
7385 Level: developer
7386
7387 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7388 @*/
MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)7389 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7390 {
7391 PetscErrorCode ierr;
7392
7393 PetscFunctionBegin;
7394 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7395 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7396 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7397 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7398 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7399 PetscFunctionReturn(0);
7400 }
7401
7402 /*@
7403 MatResidual - Default routine to calculate the residual.
7404
7405 Collective on Mat
7406
7407 Input Parameters:
7408 + mat - the matrix
7409 . b - the right-hand-side
7410 - x - the approximate solution
7411
7412 Output Parameter:
7413 . r - location to store the residual
7414
7415 Level: developer
7416
7417 .seealso: PCMGSetResidual()
7418 @*/
MatResidual(Mat mat,Vec b,Vec x,Vec r)7419 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7420 {
7421 PetscErrorCode ierr;
7422
7423 PetscFunctionBegin;
7424 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7425 PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7426 PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7427 PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7428 PetscValidType(mat,1);
7429 MatCheckPreallocated(mat,1);
7430 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7431 if (!mat->ops->residual) {
7432 ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7433 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7434 } else {
7435 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7436 }
7437 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7438 PetscFunctionReturn(0);
7439 }
7440
7441 /*@C
7442 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7443
7444 Collective on Mat
7445
7446 Input Parameters:
7447 + mat - the matrix
7448 . shift - 0 or 1 indicating we want the indices starting at 0 or 1
7449 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
7450 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7451 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7452 always used.
7453
7454 Output Parameters:
7455 + n - number of rows in the (possibly compressed) matrix
7456 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7457 . ja - the column indices
7458 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7459 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7460
7461 Level: developer
7462
7463 Notes:
7464 You CANNOT change any of the ia[] or ja[] values.
7465
7466 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7467
7468 Fortran Notes:
7469 In Fortran use
7470 $
7471 $ PetscInt ia(1), ja(1)
7472 $ PetscOffset iia, jja
7473 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7474 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7475
7476 or
7477 $
7478 $ PetscInt, pointer :: ia(:),ja(:)
7479 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7480 $ ! Access the ith and jth entries via ia(i) and ja(j)
7481
7482 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7483 @*/
MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt * n,const PetscInt * ia[],const PetscInt * ja[],PetscBool * done)7484 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7485 {
7486 PetscErrorCode ierr;
7487
7488 PetscFunctionBegin;
7489 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7490 PetscValidType(mat,1);
7491 PetscValidIntPointer(n,5);
7492 if (ia) PetscValidIntPointer(ia,6);
7493 if (ja) PetscValidIntPointer(ja,7);
7494 PetscValidIntPointer(done,8);
7495 MatCheckPreallocated(mat,1);
7496 if (!mat->ops->getrowij) *done = PETSC_FALSE;
7497 else {
7498 *done = PETSC_TRUE;
7499 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7500 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7501 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7502 }
7503 PetscFunctionReturn(0);
7504 }
7505
7506 /*@C
7507 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7508
7509 Collective on Mat
7510
7511 Input Parameters:
7512 + mat - the matrix
7513 . shift - 1 or zero indicating we want the indices starting at 0 or 1
7514 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7515 symmetrized
7516 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7517 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7518 always used.
7519 . n - number of columns in the (possibly compressed) matrix
7520 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7521 - ja - the row indices
7522
7523 Output Parameters:
7524 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7525
7526 Level: developer
7527
7528 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7529 @*/
MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt * n,const PetscInt * ia[],const PetscInt * ja[],PetscBool * done)7530 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7531 {
7532 PetscErrorCode ierr;
7533
7534 PetscFunctionBegin;
7535 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7536 PetscValidType(mat,1);
7537 PetscValidIntPointer(n,4);
7538 if (ia) PetscValidIntPointer(ia,5);
7539 if (ja) PetscValidIntPointer(ja,6);
7540 PetscValidIntPointer(done,7);
7541 MatCheckPreallocated(mat,1);
7542 if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7543 else {
7544 *done = PETSC_TRUE;
7545 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7546 }
7547 PetscFunctionReturn(0);
7548 }
7549
7550 /*@C
7551 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7552 MatGetRowIJ().
7553
7554 Collective on Mat
7555
7556 Input Parameters:
7557 + mat - the matrix
7558 . shift - 1 or zero indicating we want the indices starting at 0 or 1
7559 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7560 symmetrized
7561 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7562 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7563 always used.
7564 . n - size of (possibly compressed) matrix
7565 . ia - the row pointers
7566 - ja - the column indices
7567
7568 Output Parameters:
7569 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7570
7571 Note:
7572 This routine zeros out n, ia, and ja. This is to prevent accidental
7573 us of the array after it has been restored. If you pass NULL, it will
7574 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid.
7575
7576 Level: developer
7577
7578 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7579 @*/
MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt * n,const PetscInt * ia[],const PetscInt * ja[],PetscBool * done)7580 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7581 {
7582 PetscErrorCode ierr;
7583
7584 PetscFunctionBegin;
7585 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7586 PetscValidType(mat,1);
7587 if (ia) PetscValidIntPointer(ia,6);
7588 if (ja) PetscValidIntPointer(ja,7);
7589 PetscValidIntPointer(done,8);
7590 MatCheckPreallocated(mat,1);
7591
7592 if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7593 else {
7594 *done = PETSC_TRUE;
7595 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7596 if (n) *n = 0;
7597 if (ia) *ia = NULL;
7598 if (ja) *ja = NULL;
7599 }
7600 PetscFunctionReturn(0);
7601 }
7602
7603 /*@C
7604 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7605 MatGetColumnIJ().
7606
7607 Collective on Mat
7608
7609 Input Parameters:
7610 + mat - the matrix
7611 . shift - 1 or zero indicating we want the indices starting at 0 or 1
7612 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7613 symmetrized
7614 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7615 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7616 always used.
7617
7618 Output Parameters:
7619 + n - size of (possibly compressed) matrix
7620 . ia - the column pointers
7621 . ja - the row indices
7622 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7623
7624 Level: developer
7625
7626 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7627 @*/
MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt * n,const PetscInt * ia[],const PetscInt * ja[],PetscBool * done)7628 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7629 {
7630 PetscErrorCode ierr;
7631
7632 PetscFunctionBegin;
7633 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7634 PetscValidType(mat,1);
7635 if (ia) PetscValidIntPointer(ia,5);
7636 if (ja) PetscValidIntPointer(ja,6);
7637 PetscValidIntPointer(done,7);
7638 MatCheckPreallocated(mat,1);
7639
7640 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7641 else {
7642 *done = PETSC_TRUE;
7643 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7644 if (n) *n = 0;
7645 if (ia) *ia = NULL;
7646 if (ja) *ja = NULL;
7647 }
7648 PetscFunctionReturn(0);
7649 }
7650
7651 /*@C
7652 MatColoringPatch -Used inside matrix coloring routines that
7653 use MatGetRowIJ() and/or MatGetColumnIJ().
7654
7655 Collective on Mat
7656
7657 Input Parameters:
7658 + mat - the matrix
7659 . ncolors - max color value
7660 . n - number of entries in colorarray
7661 - colorarray - array indicating color for each column
7662
7663 Output Parameters:
7664 . iscoloring - coloring generated using colorarray information
7665
7666 Level: developer
7667
7668 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7669
7670 @*/
MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring * iscoloring)7671 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7672 {
7673 PetscErrorCode ierr;
7674
7675 PetscFunctionBegin;
7676 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7677 PetscValidType(mat,1);
7678 PetscValidIntPointer(colorarray,4);
7679 PetscValidPointer(iscoloring,5);
7680 MatCheckPreallocated(mat,1);
7681
7682 if (!mat->ops->coloringpatch) {
7683 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7684 } else {
7685 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7686 }
7687 PetscFunctionReturn(0);
7688 }
7689
7690
7691 /*@
7692 MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7693
7694 Logically Collective on Mat
7695
7696 Input Parameter:
7697 . mat - the factored matrix to be reset
7698
7699 Notes:
7700 This routine should be used only with factored matrices formed by in-place
7701 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7702 format). This option can save memory, for example, when solving nonlinear
7703 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7704 ILU(0) preconditioner.
7705
7706 Note that one can specify in-place ILU(0) factorization by calling
7707 .vb
7708 PCType(pc,PCILU);
7709 PCFactorSeUseInPlace(pc);
7710 .ve
7711 or by using the options -pc_type ilu -pc_factor_in_place
7712
7713 In-place factorization ILU(0) can also be used as a local
7714 solver for the blocks within the block Jacobi or additive Schwarz
7715 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc
7716 for details on setting local solver options.
7717
7718 Most users should employ the simplified KSP interface for linear solvers
7719 instead of working directly with matrix algebra routines such as this.
7720 See, e.g., KSPCreate().
7721
7722 Level: developer
7723
7724 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7725
7726 @*/
MatSetUnfactored(Mat mat)7727 PetscErrorCode MatSetUnfactored(Mat mat)
7728 {
7729 PetscErrorCode ierr;
7730
7731 PetscFunctionBegin;
7732 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7733 PetscValidType(mat,1);
7734 MatCheckPreallocated(mat,1);
7735 mat->factortype = MAT_FACTOR_NONE;
7736 if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7737 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7738 PetscFunctionReturn(0);
7739 }
7740
7741 /*MC
7742 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7743
7744 Synopsis:
7745 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7746
7747 Not collective
7748
7749 Input Parameter:
7750 . x - matrix
7751
7752 Output Parameters:
7753 + xx_v - the Fortran90 pointer to the array
7754 - ierr - error code
7755
7756 Example of Usage:
7757 .vb
7758 PetscScalar, pointer xx_v(:,:)
7759 ....
7760 call MatDenseGetArrayF90(x,xx_v,ierr)
7761 a = xx_v(3)
7762 call MatDenseRestoreArrayF90(x,xx_v,ierr)
7763 .ve
7764
7765 Level: advanced
7766
7767 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7768
7769 M*/
7770
7771 /*MC
7772 MatDenseRestoreArrayF90 - Restores a matrix array that has been
7773 accessed with MatDenseGetArrayF90().
7774
7775 Synopsis:
7776 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7777
7778 Not collective
7779
7780 Input Parameters:
7781 + x - matrix
7782 - xx_v - the Fortran90 pointer to the array
7783
7784 Output Parameter:
7785 . ierr - error code
7786
7787 Example of Usage:
7788 .vb
7789 PetscScalar, pointer xx_v(:,:)
7790 ....
7791 call MatDenseGetArrayF90(x,xx_v,ierr)
7792 a = xx_v(3)
7793 call MatDenseRestoreArrayF90(x,xx_v,ierr)
7794 .ve
7795
7796 Level: advanced
7797
7798 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7799
7800 M*/
7801
7802
7803 /*MC
7804 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7805
7806 Synopsis:
7807 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7808
7809 Not collective
7810
7811 Input Parameter:
7812 . x - matrix
7813
7814 Output Parameters:
7815 + xx_v - the Fortran90 pointer to the array
7816 - ierr - error code
7817
7818 Example of Usage:
7819 .vb
7820 PetscScalar, pointer xx_v(:)
7821 ....
7822 call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7823 a = xx_v(3)
7824 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7825 .ve
7826
7827 Level: advanced
7828
7829 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7830
7831 M*/
7832
7833 /*MC
7834 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7835 accessed with MatSeqAIJGetArrayF90().
7836
7837 Synopsis:
7838 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7839
7840 Not collective
7841
7842 Input Parameters:
7843 + x - matrix
7844 - xx_v - the Fortran90 pointer to the array
7845
7846 Output Parameter:
7847 . ierr - error code
7848
7849 Example of Usage:
7850 .vb
7851 PetscScalar, pointer xx_v(:)
7852 ....
7853 call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7854 a = xx_v(3)
7855 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7856 .ve
7857
7858 Level: advanced
7859
7860 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7861
7862 M*/
7863
7864
7865 /*@
7866 MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7867 as the original matrix.
7868
7869 Collective on Mat
7870
7871 Input Parameters:
7872 + mat - the original matrix
7873 . isrow - parallel IS containing the rows this processor should obtain
7874 . 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.
7875 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7876
7877 Output Parameter:
7878 . newmat - the new submatrix, of the same type as the old
7879
7880 Level: advanced
7881
7882 Notes:
7883 The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7884
7885 Some matrix types place restrictions on the row and column indices, such
7886 as that they be sorted or that they be equal to each other.
7887
7888 The index sets may not have duplicate entries.
7889
7890 The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7891 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7892 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7893 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7894 you are finished using it.
7895
7896 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7897 the input matrix.
7898
7899 If iscol is NULL then all columns are obtained (not supported in Fortran).
7900
7901 Example usage:
7902 Consider the following 8x8 matrix with 34 non-zero values, that is
7903 assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7904 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7905 as follows:
7906
7907 .vb
7908 1 2 0 | 0 3 0 | 0 4
7909 Proc0 0 5 6 | 7 0 0 | 8 0
7910 9 0 10 | 11 0 0 | 12 0
7911 -------------------------------------
7912 13 0 14 | 15 16 17 | 0 0
7913 Proc1 0 18 0 | 19 20 21 | 0 0
7914 0 0 0 | 22 23 0 | 24 0
7915 -------------------------------------
7916 Proc2 25 26 27 | 0 0 28 | 29 0
7917 30 0 0 | 31 32 33 | 0 34
7918 .ve
7919
7920 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7921
7922 .vb
7923 2 0 | 0 3 0 | 0
7924 Proc0 5 6 | 7 0 0 | 8
7925 -------------------------------
7926 Proc1 18 0 | 19 20 21 | 0
7927 -------------------------------
7928 Proc2 26 27 | 0 0 28 | 29
7929 0 0 | 31 32 33 | 0
7930 .ve
7931
7932
7933 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate()
7934 @*/
MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat * newmat)7935 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7936 {
7937 PetscErrorCode ierr;
7938 PetscMPIInt size;
7939 Mat *local;
7940 IS iscoltmp;
7941 PetscBool flg;
7942
7943 PetscFunctionBegin;
7944 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7945 PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7946 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7947 PetscValidPointer(newmat,5);
7948 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7949 PetscValidType(mat,1);
7950 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7951 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7952
7953 MatCheckPreallocated(mat,1);
7954 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7955
7956 if (!iscol || isrow == iscol) {
7957 PetscBool stride;
7958 PetscMPIInt grabentirematrix = 0,grab;
7959 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7960 if (stride) {
7961 PetscInt first,step,n,rstart,rend;
7962 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7963 if (step == 1) {
7964 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7965 if (rstart == first) {
7966 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7967 if (n == rend-rstart) {
7968 grabentirematrix = 1;
7969 }
7970 }
7971 }
7972 }
7973 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7974 if (grab) {
7975 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7976 if (cll == MAT_INITIAL_MATRIX) {
7977 *newmat = mat;
7978 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7979 }
7980 PetscFunctionReturn(0);
7981 }
7982 }
7983
7984 if (!iscol) {
7985 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7986 } else {
7987 iscoltmp = iscol;
7988 }
7989
7990 /* if original matrix is on just one processor then use submatrix generated */
7991 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7992 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7993 goto setproperties;
7994 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7995 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7996 *newmat = *local;
7997 ierr = PetscFree(local);CHKERRQ(ierr);
7998 goto setproperties;
7999 } else if (!mat->ops->createsubmatrix) {
8000 /* Create a new matrix type that implements the operation using the full matrix */
8001 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8002 switch (cll) {
8003 case MAT_INITIAL_MATRIX:
8004 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8005 break;
8006 case MAT_REUSE_MATRIX:
8007 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8008 break;
8009 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8010 }
8011 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8012 goto setproperties;
8013 }
8014
8015 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8016 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8017 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8018 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8019
8020 setproperties:
8021 ierr = ISEqualUnsorted(isrow,iscoltmp,&flg);CHKERRQ(ierr);
8022 if (flg) {
8023 ierr = MatPropagateSymmetryOptions(mat,*newmat);CHKERRQ(ierr);
8024 }
8025 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8026 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8027 PetscFunctionReturn(0);
8028 }
8029
8030 /*@
8031 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix
8032
8033 Not Collective
8034
8035 Input Parameters:
8036 + A - the matrix we wish to propagate options from
8037 - B - the matrix we wish to propagate options to
8038
8039 Level: beginner
8040
8041 Notes: Propagates the options associated to MAT_SYMMETRY_ETERNAL, MAT_STRUCTURALLY_SYMMETRIC, MAT_HERMITIAN, MAT_SPD and MAT_SYMMETRIC
8042
8043 .seealso: MatSetOption()
8044 @*/
MatPropagateSymmetryOptions(Mat A,Mat B)8045 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B)
8046 {
8047 PetscErrorCode ierr;
8048
8049 PetscFunctionBegin;
8050 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8051 PetscValidHeaderSpecific(B,MAT_CLASSID,1);
8052 if (A->symmetric_eternal) { /* symmetric_eternal does not have a corresponding *set flag */
8053 ierr = MatSetOption(B,MAT_SYMMETRY_ETERNAL,A->symmetric_eternal);CHKERRQ(ierr);
8054 }
8055 if (A->structurally_symmetric_set) {
8056 ierr = MatSetOption(B,MAT_STRUCTURALLY_SYMMETRIC,A->structurally_symmetric);CHKERRQ(ierr);
8057 }
8058 if (A->hermitian_set) {
8059 ierr = MatSetOption(B,MAT_HERMITIAN,A->hermitian);CHKERRQ(ierr);
8060 }
8061 if (A->spd_set) {
8062 ierr = MatSetOption(B,MAT_SPD,A->spd);CHKERRQ(ierr);
8063 }
8064 if (A->symmetric_set) {
8065 ierr = MatSetOption(B,MAT_SYMMETRIC,A->symmetric);CHKERRQ(ierr);
8066 }
8067 PetscFunctionReturn(0);
8068 }
8069
8070 /*@
8071 MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8072 used during the assembly process to store values that belong to
8073 other processors.
8074
8075 Not Collective
8076
8077 Input Parameters:
8078 + mat - the matrix
8079 . size - the initial size of the stash.
8080 - bsize - the initial size of the block-stash(if used).
8081
8082 Options Database Keys:
8083 + -matstash_initial_size <size> or <size0,size1,...sizep-1>
8084 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
8085
8086 Level: intermediate
8087
8088 Notes:
8089 The block-stash is used for values set with MatSetValuesBlocked() while
8090 the stash is used for values set with MatSetValues()
8091
8092 Run with the option -info and look for output of the form
8093 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8094 to determine the appropriate value, MM, to use for size and
8095 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8096 to determine the value, BMM to use for bsize
8097
8098
8099 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8100
8101 @*/
MatStashSetInitialSize(Mat mat,PetscInt size,PetscInt bsize)8102 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8103 {
8104 PetscErrorCode ierr;
8105
8106 PetscFunctionBegin;
8107 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8108 PetscValidType(mat,1);
8109 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8110 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8111 PetscFunctionReturn(0);
8112 }
8113
8114 /*@
8115 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8116 the matrix
8117
8118 Neighbor-wise Collective on Mat
8119
8120 Input Parameters:
8121 + mat - the matrix
8122 . x,y - the vectors
8123 - w - where the result is stored
8124
8125 Level: intermediate
8126
8127 Notes:
8128 w may be the same vector as y.
8129
8130 This allows one to use either the restriction or interpolation (its transpose)
8131 matrix to do the interpolation
8132
8133 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8134
8135 @*/
MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)8136 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8137 {
8138 PetscErrorCode ierr;
8139 PetscInt M,N,Ny;
8140
8141 PetscFunctionBegin;
8142 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8143 PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8144 PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8145 PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8146 PetscValidType(A,1);
8147 MatCheckPreallocated(A,1);
8148 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8149 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8150 if (M == Ny) {
8151 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8152 } else {
8153 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8154 }
8155 PetscFunctionReturn(0);
8156 }
8157
8158 /*@
8159 MatInterpolate - y = A*x or A'*x depending on the shape of
8160 the matrix
8161
8162 Neighbor-wise Collective on Mat
8163
8164 Input Parameters:
8165 + mat - the matrix
8166 - x,y - the vectors
8167
8168 Level: intermediate
8169
8170 Notes:
8171 This allows one to use either the restriction or interpolation (its transpose)
8172 matrix to do the interpolation
8173
8174 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8175
8176 @*/
MatInterpolate(Mat A,Vec x,Vec y)8177 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8178 {
8179 PetscErrorCode ierr;
8180 PetscInt M,N,Ny;
8181
8182 PetscFunctionBegin;
8183 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8184 PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8185 PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8186 PetscValidType(A,1);
8187 MatCheckPreallocated(A,1);
8188 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8189 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8190 if (M == Ny) {
8191 ierr = MatMult(A,x,y);CHKERRQ(ierr);
8192 } else {
8193 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8194 }
8195 PetscFunctionReturn(0);
8196 }
8197
8198 /*@
8199 MatRestrict - y = A*x or A'*x
8200
8201 Neighbor-wise Collective on Mat
8202
8203 Input Parameters:
8204 + mat - the matrix
8205 - x,y - the vectors
8206
8207 Level: intermediate
8208
8209 Notes:
8210 This allows one to use either the restriction or interpolation (its transpose)
8211 matrix to do the restriction
8212
8213 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8214
8215 @*/
MatRestrict(Mat A,Vec x,Vec y)8216 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8217 {
8218 PetscErrorCode ierr;
8219 PetscInt M,N,Ny;
8220
8221 PetscFunctionBegin;
8222 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8223 PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8224 PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8225 PetscValidType(A,1);
8226 MatCheckPreallocated(A,1);
8227
8228 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8229 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8230 if (M == Ny) {
8231 ierr = MatMult(A,x,y);CHKERRQ(ierr);
8232 } else {
8233 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8234 }
8235 PetscFunctionReturn(0);
8236 }
8237
8238 /*@
8239 MatGetNullSpace - retrieves the null space of a matrix.
8240
8241 Logically Collective on Mat
8242
8243 Input Parameters:
8244 + mat - the matrix
8245 - nullsp - the null space object
8246
8247 Level: developer
8248
8249 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8250 @*/
MatGetNullSpace(Mat mat,MatNullSpace * nullsp)8251 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8252 {
8253 PetscFunctionBegin;
8254 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8255 PetscValidPointer(nullsp,2);
8256 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8257 PetscFunctionReturn(0);
8258 }
8259
8260 /*@
8261 MatSetNullSpace - attaches a null space to a matrix.
8262
8263 Logically Collective on Mat
8264
8265 Input Parameters:
8266 + mat - the matrix
8267 - nullsp - the null space object
8268
8269 Level: advanced
8270
8271 Notes:
8272 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8273
8274 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8275 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8276
8277 You can remove the null space by calling this routine with an nullsp of NULL
8278
8279
8280 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8281 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).
8282 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
8283 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
8284 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).
8285
8286 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8287
8288 If the matrix is known to be symmetric because it is an SBAIJ matrix or one as called MatSetOption(mat,MAT_SYMMETRIC or MAT_SYMMETRIC_ETERNAL,PETSC_TRUE); this
8289 routine also automatically calls MatSetTransposeNullSpace().
8290
8291 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8292 @*/
MatSetNullSpace(Mat mat,MatNullSpace nullsp)8293 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8294 {
8295 PetscErrorCode ierr;
8296
8297 PetscFunctionBegin;
8298 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8299 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8300 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8301 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8302 mat->nullsp = nullsp;
8303 if (mat->symmetric_set && mat->symmetric) {
8304 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8305 }
8306 PetscFunctionReturn(0);
8307 }
8308
8309 /*@
8310 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8311
8312 Logically Collective on Mat
8313
8314 Input Parameters:
8315 + mat - the matrix
8316 - nullsp - the null space object
8317
8318 Level: developer
8319
8320 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8321 @*/
MatGetTransposeNullSpace(Mat mat,MatNullSpace * nullsp)8322 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8323 {
8324 PetscFunctionBegin;
8325 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8326 PetscValidType(mat,1);
8327 PetscValidPointer(nullsp,2);
8328 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8329 PetscFunctionReturn(0);
8330 }
8331
8332 /*@
8333 MatSetTransposeNullSpace - attaches a null space to a matrix.
8334
8335 Logically Collective on Mat
8336
8337 Input Parameters:
8338 + mat - the matrix
8339 - nullsp - the null space object
8340
8341 Level: advanced
8342
8343 Notes:
8344 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.
8345 You must also call MatSetNullSpace()
8346
8347
8348 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8349 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).
8350 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
8351 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
8352 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).
8353
8354 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8355
8356 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8357 @*/
MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)8358 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8359 {
8360 PetscErrorCode ierr;
8361
8362 PetscFunctionBegin;
8363 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8364 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8365 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8366 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8367 mat->transnullsp = nullsp;
8368 PetscFunctionReturn(0);
8369 }
8370
8371 /*@
8372 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8373 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8374
8375 Logically Collective on Mat
8376
8377 Input Parameters:
8378 + mat - the matrix
8379 - nullsp - the null space object
8380
8381 Level: advanced
8382
8383 Notes:
8384 Overwrites any previous near null space that may have been attached
8385
8386 You can remove the null space by calling this routine with an nullsp of NULL
8387
8388 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8389 @*/
MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)8390 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8391 {
8392 PetscErrorCode ierr;
8393
8394 PetscFunctionBegin;
8395 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8396 PetscValidType(mat,1);
8397 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8398 MatCheckPreallocated(mat,1);
8399 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8400 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8401 mat->nearnullsp = nullsp;
8402 PetscFunctionReturn(0);
8403 }
8404
8405 /*@
8406 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace()
8407
8408 Not Collective
8409
8410 Input Parameter:
8411 . mat - the matrix
8412
8413 Output Parameter:
8414 . nullsp - the null space object, NULL if not set
8415
8416 Level: developer
8417
8418 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8419 @*/
MatGetNearNullSpace(Mat mat,MatNullSpace * nullsp)8420 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8421 {
8422 PetscFunctionBegin;
8423 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8424 PetscValidType(mat,1);
8425 PetscValidPointer(nullsp,2);
8426 MatCheckPreallocated(mat,1);
8427 *nullsp = mat->nearnullsp;
8428 PetscFunctionReturn(0);
8429 }
8430
8431 /*@C
8432 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8433
8434 Collective on Mat
8435
8436 Input Parameters:
8437 + mat - the matrix
8438 . row - row/column permutation
8439 . fill - expected fill factor >= 1.0
8440 - level - level of fill, for ICC(k)
8441
8442 Notes:
8443 Probably really in-place only when level of fill is zero, otherwise allocates
8444 new space to store factored matrix and deletes previous memory.
8445
8446 Most users should employ the simplified KSP interface for linear solvers
8447 instead of working directly with matrix algebra routines such as this.
8448 See, e.g., KSPCreate().
8449
8450 Level: developer
8451
8452
8453 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8454
8455 Developer Note: fortran interface is not autogenerated as the f90
8456 interface defintion cannot be generated correctly [due to MatFactorInfo]
8457
8458 @*/
MatICCFactor(Mat mat,IS row,const MatFactorInfo * info)8459 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8460 {
8461 PetscErrorCode ierr;
8462
8463 PetscFunctionBegin;
8464 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8465 PetscValidType(mat,1);
8466 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8467 PetscValidPointer(info,3);
8468 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8469 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8470 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8471 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8472 MatCheckPreallocated(mat,1);
8473 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8474 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8475 PetscFunctionReturn(0);
8476 }
8477
8478 /*@
8479 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8480 ghosted ones.
8481
8482 Not Collective
8483
8484 Input Parameters:
8485 + mat - the matrix
8486 - diag = the diagonal values, including ghost ones
8487
8488 Level: developer
8489
8490 Notes:
8491 Works only for MPIAIJ and MPIBAIJ matrices
8492
8493 .seealso: MatDiagonalScale()
8494 @*/
MatDiagonalScaleLocal(Mat mat,Vec diag)8495 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8496 {
8497 PetscErrorCode ierr;
8498 PetscMPIInt size;
8499
8500 PetscFunctionBegin;
8501 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8502 PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8503 PetscValidType(mat,1);
8504
8505 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8506 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8507 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8508 if (size == 1) {
8509 PetscInt n,m;
8510 ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8511 ierr = MatGetSize(mat,NULL,&m);CHKERRQ(ierr);
8512 if (m == n) {
8513 ierr = MatDiagonalScale(mat,NULL,diag);CHKERRQ(ierr);
8514 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8515 } else {
8516 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8517 }
8518 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8519 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8520 PetscFunctionReturn(0);
8521 }
8522
8523 /*@
8524 MatGetInertia - Gets the inertia from a factored matrix
8525
8526 Collective on Mat
8527
8528 Input Parameter:
8529 . mat - the matrix
8530
8531 Output Parameters:
8532 + nneg - number of negative eigenvalues
8533 . nzero - number of zero eigenvalues
8534 - npos - number of positive eigenvalues
8535
8536 Level: advanced
8537
8538 Notes:
8539 Matrix must have been factored by MatCholeskyFactor()
8540
8541
8542 @*/
MatGetInertia(Mat mat,PetscInt * nneg,PetscInt * nzero,PetscInt * npos)8543 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8544 {
8545 PetscErrorCode ierr;
8546
8547 PetscFunctionBegin;
8548 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8549 PetscValidType(mat,1);
8550 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8551 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8552 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8553 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8554 PetscFunctionReturn(0);
8555 }
8556
8557 /* ----------------------------------------------------------------*/
8558 /*@C
8559 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8560
8561 Neighbor-wise Collective on Mats
8562
8563 Input Parameters:
8564 + mat - the factored matrix
8565 - b - the right-hand-side vectors
8566
8567 Output Parameter:
8568 . x - the result vectors
8569
8570 Notes:
8571 The vectors b and x cannot be the same. I.e., one cannot
8572 call MatSolves(A,x,x).
8573
8574 Notes:
8575 Most users should employ the simplified KSP interface for linear solvers
8576 instead of working directly with matrix algebra routines such as this.
8577 See, e.g., KSPCreate().
8578
8579 Level: developer
8580
8581 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8582 @*/
MatSolves(Mat mat,Vecs b,Vecs x)8583 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8584 {
8585 PetscErrorCode ierr;
8586
8587 PetscFunctionBegin;
8588 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8589 PetscValidType(mat,1);
8590 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8591 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8592 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8593
8594 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8595 MatCheckPreallocated(mat,1);
8596 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8597 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8598 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8599 PetscFunctionReturn(0);
8600 }
8601
8602 /*@
8603 MatIsSymmetric - Test whether a matrix is symmetric
8604
8605 Collective on Mat
8606
8607 Input Parameter:
8608 + A - the matrix to test
8609 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8610
8611 Output Parameters:
8612 . flg - the result
8613
8614 Notes:
8615 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8616
8617 Level: intermediate
8618
8619 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8620 @*/
MatIsSymmetric(Mat A,PetscReal tol,PetscBool * flg)8621 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
8622 {
8623 PetscErrorCode ierr;
8624
8625 PetscFunctionBegin;
8626 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8627 PetscValidBoolPointer(flg,2);
8628
8629 if (!A->symmetric_set) {
8630 if (!A->ops->issymmetric) {
8631 MatType mattype;
8632 ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8633 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
8634 }
8635 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8636 if (!tol) {
8637 ierr = MatSetOption(A,MAT_SYMMETRIC,*flg);CHKERRQ(ierr);
8638 }
8639 } else if (A->symmetric) {
8640 *flg = PETSC_TRUE;
8641 } else if (!tol) {
8642 *flg = PETSC_FALSE;
8643 } else {
8644 if (!A->ops->issymmetric) {
8645 MatType mattype;
8646 ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8647 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
8648 }
8649 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8650 }
8651 PetscFunctionReturn(0);
8652 }
8653
8654 /*@
8655 MatIsHermitian - Test whether a matrix is Hermitian
8656
8657 Collective on Mat
8658
8659 Input Parameter:
8660 + A - the matrix to test
8661 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8662
8663 Output Parameters:
8664 . flg - the result
8665
8666 Level: intermediate
8667
8668 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8669 MatIsSymmetricKnown(), MatIsSymmetric()
8670 @*/
MatIsHermitian(Mat A,PetscReal tol,PetscBool * flg)8671 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
8672 {
8673 PetscErrorCode ierr;
8674
8675 PetscFunctionBegin;
8676 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8677 PetscValidBoolPointer(flg,2);
8678
8679 if (!A->hermitian_set) {
8680 if (!A->ops->ishermitian) {
8681 MatType mattype;
8682 ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8683 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
8684 }
8685 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8686 if (!tol) {
8687 ierr = MatSetOption(A,MAT_HERMITIAN,*flg);CHKERRQ(ierr);
8688 }
8689 } else if (A->hermitian) {
8690 *flg = PETSC_TRUE;
8691 } else if (!tol) {
8692 *flg = PETSC_FALSE;
8693 } else {
8694 if (!A->ops->ishermitian) {
8695 MatType mattype;
8696 ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8697 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
8698 }
8699 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8700 }
8701 PetscFunctionReturn(0);
8702 }
8703
8704 /*@
8705 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8706
8707 Not Collective
8708
8709 Input Parameter:
8710 . A - the matrix to check
8711
8712 Output Parameters:
8713 + set - if the symmetric flag is set (this tells you if the next flag is valid)
8714 - flg - the result
8715
8716 Level: advanced
8717
8718 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8719 if you want it explicitly checked
8720
8721 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8722 @*/
MatIsSymmetricKnown(Mat A,PetscBool * set,PetscBool * flg)8723 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
8724 {
8725 PetscFunctionBegin;
8726 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8727 PetscValidPointer(set,2);
8728 PetscValidBoolPointer(flg,3);
8729 if (A->symmetric_set) {
8730 *set = PETSC_TRUE;
8731 *flg = A->symmetric;
8732 } else {
8733 *set = PETSC_FALSE;
8734 }
8735 PetscFunctionReturn(0);
8736 }
8737
8738 /*@
8739 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8740
8741 Not Collective
8742
8743 Input Parameter:
8744 . A - the matrix to check
8745
8746 Output Parameters:
8747 + set - if the hermitian flag is set (this tells you if the next flag is valid)
8748 - flg - the result
8749
8750 Level: advanced
8751
8752 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8753 if you want it explicitly checked
8754
8755 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8756 @*/
MatIsHermitianKnown(Mat A,PetscBool * set,PetscBool * flg)8757 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8758 {
8759 PetscFunctionBegin;
8760 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8761 PetscValidPointer(set,2);
8762 PetscValidBoolPointer(flg,3);
8763 if (A->hermitian_set) {
8764 *set = PETSC_TRUE;
8765 *flg = A->hermitian;
8766 } else {
8767 *set = PETSC_FALSE;
8768 }
8769 PetscFunctionReturn(0);
8770 }
8771
8772 /*@
8773 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8774
8775 Collective on Mat
8776
8777 Input Parameter:
8778 . A - the matrix to test
8779
8780 Output Parameters:
8781 . flg - the result
8782
8783 Level: intermediate
8784
8785 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8786 @*/
MatIsStructurallySymmetric(Mat A,PetscBool * flg)8787 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8788 {
8789 PetscErrorCode ierr;
8790
8791 PetscFunctionBegin;
8792 PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8793 PetscValidBoolPointer(flg,2);
8794 if (!A->structurally_symmetric_set) {
8795 if (!A->ops->isstructurallysymmetric) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type %s does not support checking for structural symmetric",((PetscObject)A)->type_name);
8796 ierr = (*A->ops->isstructurallysymmetric)(A,flg);CHKERRQ(ierr);
8797 ierr = MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg);CHKERRQ(ierr);
8798 } else *flg = A->structurally_symmetric;
8799 PetscFunctionReturn(0);
8800 }
8801
8802 /*@
8803 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8804 to be communicated to other processors during the MatAssemblyBegin/End() process
8805
8806 Not collective
8807
8808 Input Parameter:
8809 . vec - the vector
8810
8811 Output Parameters:
8812 + nstash - the size of the stash
8813 . reallocs - the number of additional mallocs incurred.
8814 . bnstash - the size of the block stash
8815 - breallocs - the number of additional mallocs incurred.in the block stash
8816
8817 Level: advanced
8818
8819 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8820
8821 @*/
MatStashGetInfo(Mat mat,PetscInt * nstash,PetscInt * reallocs,PetscInt * bnstash,PetscInt * breallocs)8822 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8823 {
8824 PetscErrorCode ierr;
8825
8826 PetscFunctionBegin;
8827 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8828 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8829 PetscFunctionReturn(0);
8830 }
8831
8832 /*@C
8833 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8834 parallel layout
8835
8836 Collective on Mat
8837
8838 Input Parameter:
8839 . mat - the matrix
8840
8841 Output Parameter:
8842 + right - (optional) vector that the matrix can be multiplied against
8843 - left - (optional) vector that the matrix vector product can be stored in
8844
8845 Notes:
8846 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().
8847
8848 Notes:
8849 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8850
8851 Level: advanced
8852
8853 .seealso: MatCreate(), VecDestroy()
8854 @*/
MatCreateVecs(Mat mat,Vec * right,Vec * left)8855 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8856 {
8857 PetscErrorCode ierr;
8858
8859 PetscFunctionBegin;
8860 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8861 PetscValidType(mat,1);
8862 if (mat->ops->getvecs) {
8863 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8864 } else {
8865 PetscInt rbs,cbs;
8866 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8867 if (right) {
8868 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8869 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8870 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8871 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8872 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8873 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8874 }
8875 if (left) {
8876 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8877 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8878 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8879 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8880 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8881 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8882 }
8883 }
8884 PetscFunctionReturn(0);
8885 }
8886
8887 /*@C
8888 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8889 with default values.
8890
8891 Not Collective
8892
8893 Input Parameters:
8894 . info - the MatFactorInfo data structure
8895
8896
8897 Notes:
8898 The solvers are generally used through the KSP and PC objects, for example
8899 PCLU, PCILU, PCCHOLESKY, PCICC
8900
8901 Level: developer
8902
8903 .seealso: MatFactorInfo
8904
8905 Developer Note: fortran interface is not autogenerated as the f90
8906 interface defintion cannot be generated correctly [due to MatFactorInfo]
8907
8908 @*/
8909
MatFactorInfoInitialize(MatFactorInfo * info)8910 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8911 {
8912 PetscErrorCode ierr;
8913
8914 PetscFunctionBegin;
8915 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8916 PetscFunctionReturn(0);
8917 }
8918
8919 /*@
8920 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8921
8922 Collective on Mat
8923
8924 Input Parameters:
8925 + mat - the factored matrix
8926 - is - the index set defining the Schur indices (0-based)
8927
8928 Notes:
8929 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8930
8931 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8932
8933 Level: developer
8934
8935 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8936 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8937
8938 @*/
MatFactorSetSchurIS(Mat mat,IS is)8939 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8940 {
8941 PetscErrorCode ierr,(*f)(Mat,IS);
8942
8943 PetscFunctionBegin;
8944 PetscValidType(mat,1);
8945 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8946 PetscValidType(is,2);
8947 PetscValidHeaderSpecific(is,IS_CLASSID,2);
8948 PetscCheckSameComm(mat,1,is,2);
8949 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8950 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8951 if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
8952 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
8953 ierr = (*f)(mat,is);CHKERRQ(ierr);
8954 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8955 PetscFunctionReturn(0);
8956 }
8957
8958 /*@
8959 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8960
8961 Logically Collective on Mat
8962
8963 Input Parameters:
8964 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8965 . S - location where to return the Schur complement, can be NULL
8966 - status - the status of the Schur complement matrix, can be NULL
8967
8968 Notes:
8969 You must call MatFactorSetSchurIS() before calling this routine.
8970
8971 The routine provides a copy of the Schur matrix stored within the solver data structures.
8972 The caller must destroy the object when it is no longer needed.
8973 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8974
8975 Use MatFactorGetSchurComplement() to get access to the Schur complement matrix inside the factored matrix instead of making a copy of it (which this function does)
8976
8977 Developer Notes:
8978 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
8979 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8980
8981 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8982
8983 Level: advanced
8984
8985 References:
8986
8987 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8988 @*/
MatFactorCreateSchurComplement(Mat F,Mat * S,MatFactorSchurStatus * status)8989 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8990 {
8991 PetscErrorCode ierr;
8992
8993 PetscFunctionBegin;
8994 PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8995 if (S) PetscValidPointer(S,2);
8996 if (status) PetscValidPointer(status,3);
8997 if (S) {
8998 PetscErrorCode (*f)(Mat,Mat*);
8999
9000 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9001 if (f) {
9002 ierr = (*f)(F,S);CHKERRQ(ierr);
9003 } else {
9004 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9005 }
9006 }
9007 if (status) *status = F->schur_status;
9008 PetscFunctionReturn(0);
9009 }
9010
9011 /*@
9012 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9013
9014 Logically Collective on Mat
9015
9016 Input Parameters:
9017 + F - the factored matrix obtained by calling MatGetFactor()
9018 . *S - location where to return the Schur complement, can be NULL
9019 - status - the status of the Schur complement matrix, can be NULL
9020
9021 Notes:
9022 You must call MatFactorSetSchurIS() before calling this routine.
9023
9024 Schur complement mode is currently implemented for sequential matrices.
9025 The routine returns a the Schur Complement stored within the data strutures of the solver.
9026 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9027 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9028
9029 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9030
9031 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9032
9033 Level: advanced
9034
9035 References:
9036
9037 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9038 @*/
MatFactorGetSchurComplement(Mat F,Mat * S,MatFactorSchurStatus * status)9039 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9040 {
9041 PetscFunctionBegin;
9042 PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9043 if (S) PetscValidPointer(S,2);
9044 if (status) PetscValidPointer(status,3);
9045 if (S) *S = F->schur;
9046 if (status) *status = F->schur_status;
9047 PetscFunctionReturn(0);
9048 }
9049
9050 /*@
9051 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9052
9053 Logically Collective on Mat
9054
9055 Input Parameters:
9056 + F - the factored matrix obtained by calling MatGetFactor()
9057 . *S - location where the Schur complement is stored
9058 - status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9059
9060 Notes:
9061
9062 Level: advanced
9063
9064 References:
9065
9066 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9067 @*/
MatFactorRestoreSchurComplement(Mat F,Mat * S,MatFactorSchurStatus status)9068 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9069 {
9070 PetscErrorCode ierr;
9071
9072 PetscFunctionBegin;
9073 PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9074 if (S) {
9075 PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9076 *S = NULL;
9077 }
9078 F->schur_status = status;
9079 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9080 PetscFunctionReturn(0);
9081 }
9082
9083 /*@
9084 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9085
9086 Logically Collective on Mat
9087
9088 Input Parameters:
9089 + F - the factored matrix obtained by calling MatGetFactor()
9090 . rhs - location where the right hand side of the Schur complement system is stored
9091 - sol - location where the solution of the Schur complement system has to be returned
9092
9093 Notes:
9094 The sizes of the vectors should match the size of the Schur complement
9095
9096 Must be called after MatFactorSetSchurIS()
9097
9098 Level: advanced
9099
9100 References:
9101
9102 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9103 @*/
MatFactorSolveSchurComplementTranspose(Mat F,Vec rhs,Vec sol)9104 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9105 {
9106 PetscErrorCode ierr;
9107
9108 PetscFunctionBegin;
9109 PetscValidType(F,1);
9110 PetscValidType(rhs,2);
9111 PetscValidType(sol,3);
9112 PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9113 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9114 PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9115 PetscCheckSameComm(F,1,rhs,2);
9116 PetscCheckSameComm(F,1,sol,3);
9117 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9118 switch (F->schur_status) {
9119 case MAT_FACTOR_SCHUR_FACTORED:
9120 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9121 break;
9122 case MAT_FACTOR_SCHUR_INVERTED:
9123 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9124 break;
9125 default:
9126 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9127 break;
9128 }
9129 PetscFunctionReturn(0);
9130 }
9131
9132 /*@
9133 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9134
9135 Logically Collective on Mat
9136
9137 Input Parameters:
9138 + F - the factored matrix obtained by calling MatGetFactor()
9139 . rhs - location where the right hand side of the Schur complement system is stored
9140 - sol - location where the solution of the Schur complement system has to be returned
9141
9142 Notes:
9143 The sizes of the vectors should match the size of the Schur complement
9144
9145 Must be called after MatFactorSetSchurIS()
9146
9147 Level: advanced
9148
9149 References:
9150
9151 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9152 @*/
MatFactorSolveSchurComplement(Mat F,Vec rhs,Vec sol)9153 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9154 {
9155 PetscErrorCode ierr;
9156
9157 PetscFunctionBegin;
9158 PetscValidType(F,1);
9159 PetscValidType(rhs,2);
9160 PetscValidType(sol,3);
9161 PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9162 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9163 PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9164 PetscCheckSameComm(F,1,rhs,2);
9165 PetscCheckSameComm(F,1,sol,3);
9166 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9167 switch (F->schur_status) {
9168 case MAT_FACTOR_SCHUR_FACTORED:
9169 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9170 break;
9171 case MAT_FACTOR_SCHUR_INVERTED:
9172 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9173 break;
9174 default:
9175 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9176 break;
9177 }
9178 PetscFunctionReturn(0);
9179 }
9180
9181 /*@
9182 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9183
9184 Logically Collective on Mat
9185
9186 Input Parameters:
9187 . F - the factored matrix obtained by calling MatGetFactor()
9188
9189 Notes:
9190 Must be called after MatFactorSetSchurIS().
9191
9192 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9193
9194 Level: advanced
9195
9196 References:
9197
9198 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9199 @*/
MatFactorInvertSchurComplement(Mat F)9200 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9201 {
9202 PetscErrorCode ierr;
9203
9204 PetscFunctionBegin;
9205 PetscValidType(F,1);
9206 PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9207 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9208 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9209 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9210 F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9211 PetscFunctionReturn(0);
9212 }
9213
9214 /*@
9215 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9216
9217 Logically Collective on Mat
9218
9219 Input Parameters:
9220 . F - the factored matrix obtained by calling MatGetFactor()
9221
9222 Notes:
9223 Must be called after MatFactorSetSchurIS().
9224
9225 Level: advanced
9226
9227 References:
9228
9229 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9230 @*/
MatFactorFactorizeSchurComplement(Mat F)9231 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9232 {
9233 PetscErrorCode ierr;
9234
9235 PetscFunctionBegin;
9236 PetscValidType(F,1);
9237 PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9238 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9239 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9240 F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9241 PetscFunctionReturn(0);
9242 }
9243
9244 /*@
9245 MatPtAP - Creates the matrix product C = P^T * A * P
9246
9247 Neighbor-wise Collective on Mat
9248
9249 Input Parameters:
9250 + A - the matrix
9251 . P - the projection matrix
9252 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9253 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9254 if the result is a dense matrix this is irrelevent
9255
9256 Output Parameters:
9257 . C - the product matrix
9258
9259 Notes:
9260 C will be created and must be destroyed by the user with MatDestroy().
9261
9262 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult().
9263
9264 Level: intermediate
9265
9266 .seealso: MatMatMult(), MatRARt()
9267 @*/
MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat * C)9268 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9269 {
9270 PetscErrorCode ierr;
9271
9272 PetscFunctionBegin;
9273 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5);
9274 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9275
9276 if (scall == MAT_INITIAL_MATRIX) {
9277 ierr = MatProductCreate(A,P,NULL,C);CHKERRQ(ierr);
9278 ierr = MatProductSetType(*C,MATPRODUCT_PtAP);CHKERRQ(ierr);
9279 ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr);
9280 ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9281
9282 (*C)->product->api_user = PETSC_TRUE;
9283 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9284 if (!(*C)->ops->productsymbolic) SETERRQ3(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s and P %s",MatProductTypes[MATPRODUCT_PtAP],((PetscObject)A)->type_name,((PetscObject)P)->type_name);
9285 ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9286 } else { /* scall == MAT_REUSE_MATRIX */
9287 ierr = MatProductReplaceMats(A,P,NULL,*C);CHKERRQ(ierr);
9288 }
9289
9290 ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9291 if (A->symmetric_set && A->symmetric) {
9292 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9293 }
9294 PetscFunctionReturn(0);
9295 }
9296
9297 /*@
9298 MatRARt - Creates the matrix product C = R * A * R^T
9299
9300 Neighbor-wise Collective on Mat
9301
9302 Input Parameters:
9303 + A - the matrix
9304 . R - the projection matrix
9305 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9306 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9307 if the result is a dense matrix this is irrelevent
9308
9309 Output Parameters:
9310 . C - the product matrix
9311
9312 Notes:
9313 C will be created and must be destroyed by the user with MatDestroy().
9314
9315 This routine is currently only implemented for pairs of AIJ matrices and classes
9316 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9317 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9318 We recommend using MatPtAP().
9319
9320 Level: intermediate
9321
9322 .seealso: MatMatMult(), MatPtAP()
9323 @*/
MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat * C)9324 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9325 {
9326 PetscErrorCode ierr;
9327
9328 PetscFunctionBegin;
9329 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5);
9330 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9331
9332 if (scall == MAT_INITIAL_MATRIX) {
9333 ierr = MatProductCreate(A,R,NULL,C);CHKERRQ(ierr);
9334 ierr = MatProductSetType(*C,MATPRODUCT_RARt);CHKERRQ(ierr);
9335 ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr);
9336 ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9337
9338 (*C)->product->api_user = PETSC_TRUE;
9339 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9340 if (!(*C)->ops->productsymbolic) SETERRQ3(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s and R %s",MatProductTypes[MATPRODUCT_RARt],((PetscObject)A)->type_name,((PetscObject)R)->type_name);
9341 ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9342 } else { /* scall == MAT_REUSE_MATRIX */
9343 ierr = MatProductReplaceMats(A,R,NULL,*C);CHKERRQ(ierr);
9344 }
9345
9346 ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9347 if (A->symmetric_set && A->symmetric) {
9348 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9349 }
9350 PetscFunctionReturn(0);
9351 }
9352
9353
MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype,Mat * C)9354 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C)
9355 {
9356 PetscErrorCode ierr;
9357
9358 PetscFunctionBegin;
9359 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9360
9361 if (scall == MAT_INITIAL_MATRIX) {
9362 ierr = PetscInfo1(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype]);CHKERRQ(ierr);
9363 ierr = MatProductCreate(A,B,NULL,C);CHKERRQ(ierr);
9364 ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr);
9365 ierr = MatProductSetAlgorithm(*C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
9366 ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9367
9368 (*C)->product->api_user = PETSC_TRUE;
9369 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9370 ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9371 } else { /* scall == MAT_REUSE_MATRIX */
9372 Mat_Product *product = (*C)->product;
9373
9374 ierr = PetscInfo2(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype]);CHKERRQ(ierr);
9375 if (!product) {
9376 /* user provide the dense matrix *C without calling MatProductCreate() */
9377 PetscBool isdense;
9378
9379 ierr = PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr);
9380 if (isdense) {
9381 /* user wants to reuse an assembled dense matrix */
9382 /* Create product -- see MatCreateProduct() */
9383 ierr = MatProductCreate_Private(A,B,NULL,*C);CHKERRQ(ierr);
9384 product = (*C)->product;
9385 product->fill = fill;
9386 product->api_user = PETSC_TRUE;
9387 product->clear = PETSC_TRUE;
9388
9389 ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr);
9390 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9391 if (!(*C)->ops->productsymbolic) SETERRQ3(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for %s and %s",MatProductTypes[ptype],((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9392 ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9393 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first");
9394 } else { /* user may change input matrices A or B when REUSE */
9395 ierr = MatProductReplaceMats(A,B,NULL,*C);CHKERRQ(ierr);
9396 }
9397 }
9398 ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9399 PetscFunctionReturn(0);
9400 }
9401
9402 /*@
9403 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9404
9405 Neighbor-wise Collective on Mat
9406
9407 Input Parameters:
9408 + A - the left matrix
9409 . B - the right matrix
9410 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9411 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9412 if the result is a dense matrix this is irrelevent
9413
9414 Output Parameters:
9415 . C - the product matrix
9416
9417 Notes:
9418 Unless scall is MAT_REUSE_MATRIX C will be created.
9419
9420 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call and C was obtained from a previous
9421 call to this function with MAT_INITIAL_MATRIX.
9422
9423 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed.
9424
9425 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic(C)/ReplaceMats(), and call MatProductNumeric() repeatedly.
9426
9427 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 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9428
9429 Level: intermediate
9430
9431 .seealso: MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
9432 @*/
MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat * C)9433 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9434 {
9435 PetscErrorCode ierr;
9436
9437 PetscFunctionBegin;
9438 ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C);CHKERRQ(ierr);
9439 PetscFunctionReturn(0);
9440 }
9441
9442 /*@
9443 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9444
9445 Neighbor-wise Collective on Mat
9446
9447 Input Parameters:
9448 + A - the left matrix
9449 . B - the right matrix
9450 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9451 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9452
9453 Output Parameters:
9454 . C - the product matrix
9455
9456 Notes:
9457 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9458
9459 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9460
9461 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9462 actually needed.
9463
9464 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9465 and for pairs of MPIDense matrices.
9466
9467 Options Database Keys:
9468 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9469 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9470 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9471
9472 Level: intermediate
9473
9474 .seealso: MatMatMult(), MatTransposeMatMult() MatPtAP()
9475 @*/
MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat * C)9476 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9477 {
9478 PetscErrorCode ierr;
9479
9480 PetscFunctionBegin;
9481 ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C);CHKERRQ(ierr);
9482 PetscFunctionReturn(0);
9483 }
9484
9485 /*@
9486 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9487
9488 Neighbor-wise Collective on Mat
9489
9490 Input Parameters:
9491 + A - the left matrix
9492 . B - the right matrix
9493 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9494 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9495
9496 Output Parameters:
9497 . C - the product matrix
9498
9499 Notes:
9500 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9501
9502 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call.
9503
9504 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9505 actually needed.
9506
9507 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9508 which inherit from SeqAIJ. C will be of same type as the input matrices.
9509
9510 Level: intermediate
9511
9512 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP()
9513 @*/
MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat * C)9514 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9515 {
9516 PetscErrorCode ierr;
9517
9518 PetscFunctionBegin;
9519 ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C);CHKERRQ(ierr);
9520 PetscFunctionReturn(0);
9521 }
9522
9523 /*@
9524 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9525
9526 Neighbor-wise Collective on Mat
9527
9528 Input Parameters:
9529 + A - the left matrix
9530 . B - the middle matrix
9531 . C - the right matrix
9532 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9533 - 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
9534 if the result is a dense matrix this is irrelevent
9535
9536 Output Parameters:
9537 . D - the product matrix
9538
9539 Notes:
9540 Unless scall is MAT_REUSE_MATRIX D will be created.
9541
9542 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9543
9544 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9545 actually needed.
9546
9547 If you have many matrices with the same non-zero structure to multiply, you
9548 should use MAT_REUSE_MATRIX in all calls but the first or
9549
9550 Level: intermediate
9551
9552 .seealso: MatMatMult, MatPtAP()
9553 @*/
MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat * D)9554 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9555 {
9556 PetscErrorCode ierr;
9557
9558 PetscFunctionBegin;
9559 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6);
9560 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9561
9562 if (scall == MAT_INITIAL_MATRIX) {
9563 ierr = MatProductCreate(A,B,C,D);CHKERRQ(ierr);
9564 ierr = MatProductSetType(*D,MATPRODUCT_ABC);CHKERRQ(ierr);
9565 ierr = MatProductSetAlgorithm(*D,"default");CHKERRQ(ierr);
9566 ierr = MatProductSetFill(*D,fill);CHKERRQ(ierr);
9567
9568 (*D)->product->api_user = PETSC_TRUE;
9569 ierr = MatProductSetFromOptions(*D);CHKERRQ(ierr);
9570 if (!(*D)->ops->productsymbolic) SETERRQ4(PetscObjectComm((PetscObject)(*D)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s, B %s and C %s",MatProductTypes[MATPRODUCT_ABC],((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9571 ierr = MatProductSymbolic(*D);CHKERRQ(ierr);
9572 } else { /* user may change input matrices when REUSE */
9573 ierr = MatProductReplaceMats(A,B,C,*D);CHKERRQ(ierr);
9574 }
9575 ierr = MatProductNumeric(*D);CHKERRQ(ierr);
9576 PetscFunctionReturn(0);
9577 }
9578
9579 /*@
9580 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9581
9582 Collective on Mat
9583
9584 Input Parameters:
9585 + mat - the matrix
9586 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9587 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9588 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9589
9590 Output Parameter:
9591 . matredundant - redundant matrix
9592
9593 Notes:
9594 MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9595 original matrix has not changed from that last call to MatCreateRedundantMatrix().
9596
9597 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9598 calling it.
9599
9600 Level: advanced
9601
9602
9603 .seealso: MatDestroy()
9604 @*/
MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat * matredundant)9605 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9606 {
9607 PetscErrorCode ierr;
9608 MPI_Comm comm;
9609 PetscMPIInt size;
9610 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9611 Mat_Redundant *redund=NULL;
9612 PetscSubcomm psubcomm=NULL;
9613 MPI_Comm subcomm_in=subcomm;
9614 Mat *matseq;
9615 IS isrow,iscol;
9616 PetscBool newsubcomm=PETSC_FALSE;
9617
9618 PetscFunctionBegin;
9619 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9620 if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9621 PetscValidPointer(*matredundant,5);
9622 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9623 }
9624
9625 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
9626 if (size == 1 || nsubcomm == 1) {
9627 if (reuse == MAT_INITIAL_MATRIX) {
9628 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
9629 } else {
9630 if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
9631 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
9632 }
9633 PetscFunctionReturn(0);
9634 }
9635
9636 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9637 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9638 MatCheckPreallocated(mat,1);
9639
9640 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9641 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9642 /* create psubcomm, then get subcomm */
9643 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9644 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
9645 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9646
9647 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
9648 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
9649 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
9650 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
9651 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
9652 newsubcomm = PETSC_TRUE;
9653 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
9654 }
9655
9656 /* get isrow, iscol and a local sequential matrix matseq[0] */
9657 if (reuse == MAT_INITIAL_MATRIX) {
9658 mloc_sub = PETSC_DECIDE;
9659 nloc_sub = PETSC_DECIDE;
9660 if (bs < 1) {
9661 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
9662 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
9663 } else {
9664 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
9665 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
9666 }
9667 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
9668 rstart = rend - mloc_sub;
9669 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
9670 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
9671 } else { /* reuse == MAT_REUSE_MATRIX */
9672 if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
9673 /* retrieve subcomm */
9674 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
9675 redund = (*matredundant)->redundant;
9676 isrow = redund->isrow;
9677 iscol = redund->iscol;
9678 matseq = redund->matseq;
9679 }
9680 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
9681
9682 /* get matredundant over subcomm */
9683 if (reuse == MAT_INITIAL_MATRIX) {
9684 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
9685
9686 /* create a supporting struct and attach it to C for reuse */
9687 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
9688 (*matredundant)->redundant = redund;
9689 redund->isrow = isrow;
9690 redund->iscol = iscol;
9691 redund->matseq = matseq;
9692 if (newsubcomm) {
9693 redund->subcomm = subcomm;
9694 } else {
9695 redund->subcomm = MPI_COMM_NULL;
9696 }
9697 } else {
9698 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
9699 }
9700 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9701 PetscFunctionReturn(0);
9702 }
9703
9704 /*@C
9705 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9706 a given 'mat' object. Each submatrix can span multiple procs.
9707
9708 Collective on Mat
9709
9710 Input Parameters:
9711 + mat - the matrix
9712 . subcomm - the subcommunicator obtained by com_split(comm)
9713 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9714
9715 Output Parameter:
9716 . subMat - 'parallel submatrices each spans a given subcomm
9717
9718 Notes:
9719 The submatrix partition across processors is dictated by 'subComm' a
9720 communicator obtained by com_split(comm). The comm_split
9721 is not restriced to be grouped with consecutive original ranks.
9722
9723 Due the comm_split() usage, the parallel layout of the submatrices
9724 map directly to the layout of the original matrix [wrt the local
9725 row,col partitioning]. So the original 'DiagonalMat' naturally maps
9726 into the 'DiagonalMat' of the subMat, hence it is used directly from
9727 the subMat. However the offDiagMat looses some columns - and this is
9728 reconstructed with MatSetValues()
9729
9730 Level: advanced
9731
9732
9733 .seealso: MatCreateSubMatrices()
9734 @*/
MatGetMultiProcBlock(Mat mat,MPI_Comm subComm,MatReuse scall,Mat * subMat)9735 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9736 {
9737 PetscErrorCode ierr;
9738 PetscMPIInt commsize,subCommSize;
9739
9740 PetscFunctionBegin;
9741 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
9742 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
9743 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9744
9745 if (scall == MAT_REUSE_MATRIX && *subMat == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
9746 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9747 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
9748 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9749 PetscFunctionReturn(0);
9750 }
9751
9752 /*@
9753 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9754
9755 Not Collective
9756
9757 Input Arguments:
9758 + mat - matrix to extract local submatrix from
9759 . isrow - local row indices for submatrix
9760 - iscol - local column indices for submatrix
9761
9762 Output Arguments:
9763 . submat - the submatrix
9764
9765 Level: intermediate
9766
9767 Notes:
9768 The submat should be returned with MatRestoreLocalSubMatrix().
9769
9770 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
9771 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9772
9773 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
9774 MatSetValuesBlockedLocal() will also be implemented.
9775
9776 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
9777 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
9778
9779 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
9780 @*/
MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat * submat)9781 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9782 {
9783 PetscErrorCode ierr;
9784
9785 PetscFunctionBegin;
9786 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9787 PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9788 PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9789 PetscCheckSameComm(isrow,2,iscol,3);
9790 PetscValidPointer(submat,4);
9791 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
9792
9793 if (mat->ops->getlocalsubmatrix) {
9794 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9795 } else {
9796 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
9797 }
9798 PetscFunctionReturn(0);
9799 }
9800
9801 /*@
9802 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9803
9804 Not Collective
9805
9806 Input Arguments:
9807 mat - matrix to extract local submatrix from
9808 isrow - local row indices for submatrix
9809 iscol - local column indices for submatrix
9810 submat - the submatrix
9811
9812 Level: intermediate
9813
9814 .seealso: MatGetLocalSubMatrix()
9815 @*/
MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat * submat)9816 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9817 {
9818 PetscErrorCode ierr;
9819
9820 PetscFunctionBegin;
9821 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9822 PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9823 PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9824 PetscCheckSameComm(isrow,2,iscol,3);
9825 PetscValidPointer(submat,4);
9826 if (*submat) {
9827 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
9828 }
9829
9830 if (mat->ops->restorelocalsubmatrix) {
9831 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9832 } else {
9833 ierr = MatDestroy(submat);CHKERRQ(ierr);
9834 }
9835 *submat = NULL;
9836 PetscFunctionReturn(0);
9837 }
9838
9839 /* --------------------------------------------------------*/
9840 /*@
9841 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
9842
9843 Collective on Mat
9844
9845 Input Parameter:
9846 . mat - the matrix
9847
9848 Output Parameter:
9849 . is - if any rows have zero diagonals this contains the list of them
9850
9851 Level: developer
9852
9853 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9854 @*/
MatFindZeroDiagonals(Mat mat,IS * is)9855 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
9856 {
9857 PetscErrorCode ierr;
9858
9859 PetscFunctionBegin;
9860 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9861 PetscValidType(mat,1);
9862 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9863 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9864
9865 if (!mat->ops->findzerodiagonals) {
9866 Vec diag;
9867 const PetscScalar *a;
9868 PetscInt *rows;
9869 PetscInt rStart, rEnd, r, nrow = 0;
9870
9871 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
9872 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
9873 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
9874 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
9875 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
9876 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
9877 nrow = 0;
9878 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
9879 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
9880 ierr = VecDestroy(&diag);CHKERRQ(ierr);
9881 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
9882 } else {
9883 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
9884 }
9885 PetscFunctionReturn(0);
9886 }
9887
9888 /*@
9889 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
9890
9891 Collective on Mat
9892
9893 Input Parameter:
9894 . mat - the matrix
9895
9896 Output Parameter:
9897 . is - contains the list of rows with off block diagonal entries
9898
9899 Level: developer
9900
9901 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9902 @*/
MatFindOffBlockDiagonalEntries(Mat mat,IS * is)9903 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
9904 {
9905 PetscErrorCode ierr;
9906
9907 PetscFunctionBegin;
9908 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9909 PetscValidType(mat,1);
9910 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9911 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9912
9913 if (!mat->ops->findoffblockdiagonalentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a find off block diagonal entries defined",((PetscObject)mat)->type_name);
9914 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
9915 PetscFunctionReturn(0);
9916 }
9917
9918 /*@C
9919 MatInvertBlockDiagonal - Inverts the block diagonal entries.
9920
9921 Collective on Mat
9922
9923 Input Parameters:
9924 . mat - the matrix
9925
9926 Output Parameters:
9927 . values - the block inverses in column major order (FORTRAN-like)
9928
9929 Note:
9930 This routine is not available from Fortran.
9931
9932 Level: advanced
9933
9934 .seealso: MatInvertBockDiagonalMat
9935 @*/
MatInvertBlockDiagonal(Mat mat,const PetscScalar ** values)9936 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9937 {
9938 PetscErrorCode ierr;
9939
9940 PetscFunctionBegin;
9941 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9942 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9943 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9944 if (!mat->ops->invertblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name);
9945 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
9946 PetscFunctionReturn(0);
9947 }
9948
9949 /*@C
9950 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
9951
9952 Collective on Mat
9953
9954 Input Parameters:
9955 + mat - the matrix
9956 . nblocks - the number of blocks
9957 - bsizes - the size of each block
9958
9959 Output Parameters:
9960 . values - the block inverses in column major order (FORTRAN-like)
9961
9962 Note:
9963 This routine is not available from Fortran.
9964
9965 Level: advanced
9966
9967 .seealso: MatInvertBockDiagonal()
9968 @*/
MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt * bsizes,PetscScalar * values)9969 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
9970 {
9971 PetscErrorCode ierr;
9972
9973 PetscFunctionBegin;
9974 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9975 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9976 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9977 if (!mat->ops->invertvariableblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type",((PetscObject)mat)->type_name);
9978 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
9979 PetscFunctionReturn(0);
9980 }
9981
9982 /*@
9983 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
9984
9985 Collective on Mat
9986
9987 Input Parameters:
9988 . A - the matrix
9989
9990 Output Parameters:
9991 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set.
9992
9993 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
9994
9995 Level: advanced
9996
9997 .seealso: MatInvertBockDiagonal()
9998 @*/
MatInvertBlockDiagonalMat(Mat A,Mat C)9999 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10000 {
10001 PetscErrorCode ierr;
10002 const PetscScalar *vals;
10003 PetscInt *dnnz;
10004 PetscInt M,N,m,n,rstart,rend,bs,i,j;
10005
10006 PetscFunctionBegin;
10007 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10008 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10009 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10010 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10011 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10012 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10013 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10014 for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10015 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10016 ierr = PetscFree(dnnz);CHKERRQ(ierr);
10017 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10018 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10019 for (i = rstart/bs; i < rend/bs; i++) {
10020 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10021 }
10022 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10023 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10024 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10025 PetscFunctionReturn(0);
10026 }
10027
10028 /*@C
10029 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10030 via MatTransposeColoringCreate().
10031
10032 Collective on MatTransposeColoring
10033
10034 Input Parameter:
10035 . c - coloring context
10036
10037 Level: intermediate
10038
10039 .seealso: MatTransposeColoringCreate()
10040 @*/
MatTransposeColoringDestroy(MatTransposeColoring * c)10041 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10042 {
10043 PetscErrorCode ierr;
10044 MatTransposeColoring matcolor=*c;
10045
10046 PetscFunctionBegin;
10047 if (!matcolor) PetscFunctionReturn(0);
10048 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);}
10049
10050 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10051 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10052 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10053 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10054 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10055 if (matcolor->brows>0) {
10056 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10057 }
10058 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10059 PetscFunctionReturn(0);
10060 }
10061
10062 /*@C
10063 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10064 a MatTransposeColoring context has been created, computes a dense B^T by Apply
10065 MatTransposeColoring to sparse B.
10066
10067 Collective on MatTransposeColoring
10068
10069 Input Parameters:
10070 + B - sparse matrix B
10071 . Btdense - symbolic dense matrix B^T
10072 - coloring - coloring context created with MatTransposeColoringCreate()
10073
10074 Output Parameter:
10075 . Btdense - dense matrix B^T
10076
10077 Level: advanced
10078
10079 Notes:
10080 These are used internally for some implementations of MatRARt()
10081
10082 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10083
10084 @*/
MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)10085 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10086 {
10087 PetscErrorCode ierr;
10088
10089 PetscFunctionBegin;
10090 PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10091 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10092 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10093
10094 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10095 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10096 PetscFunctionReturn(0);
10097 }
10098
10099 /*@C
10100 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10101 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10102 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10103 Csp from Cden.
10104
10105 Collective on MatTransposeColoring
10106
10107 Input Parameters:
10108 + coloring - coloring context created with MatTransposeColoringCreate()
10109 - Cden - matrix product of a sparse matrix and a dense matrix Btdense
10110
10111 Output Parameter:
10112 . Csp - sparse matrix
10113
10114 Level: advanced
10115
10116 Notes:
10117 These are used internally for some implementations of MatRARt()
10118
10119 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10120
10121 @*/
MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)10122 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10123 {
10124 PetscErrorCode ierr;
10125
10126 PetscFunctionBegin;
10127 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10128 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10129 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10130
10131 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10132 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10133 ierr = MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10134 ierr = MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10135 PetscFunctionReturn(0);
10136 }
10137
10138 /*@C
10139 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10140
10141 Collective on Mat
10142
10143 Input Parameters:
10144 + mat - the matrix product C
10145 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10146
10147 Output Parameter:
10148 . color - the new coloring context
10149
10150 Level: intermediate
10151
10152 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(),
10153 MatTransColoringApplyDenToSp()
10154 @*/
MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring * color)10155 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10156 {
10157 MatTransposeColoring c;
10158 MPI_Comm comm;
10159 PetscErrorCode ierr;
10160
10161 PetscFunctionBegin;
10162 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10163 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10164 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10165
10166 c->ctype = iscoloring->ctype;
10167 if (mat->ops->transposecoloringcreate) {
10168 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10169 } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name);
10170
10171 *color = c;
10172 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10173 PetscFunctionReturn(0);
10174 }
10175
10176 /*@
10177 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10178 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10179 same, otherwise it will be larger
10180
10181 Not Collective
10182
10183 Input Parameter:
10184 . A - the matrix
10185
10186 Output Parameter:
10187 . state - the current state
10188
10189 Notes:
10190 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10191 different matrices
10192
10193 Level: intermediate
10194
10195 @*/
MatGetNonzeroState(Mat mat,PetscObjectState * state)10196 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10197 {
10198 PetscFunctionBegin;
10199 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10200 *state = mat->nonzerostate;
10201 PetscFunctionReturn(0);
10202 }
10203
10204 /*@
10205 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10206 matrices from each processor
10207
10208 Collective
10209
10210 Input Parameters:
10211 + comm - the communicators the parallel matrix will live on
10212 . seqmat - the input sequential matrices
10213 . n - number of local columns (or PETSC_DECIDE)
10214 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10215
10216 Output Parameter:
10217 . mpimat - the parallel matrix generated
10218
10219 Level: advanced
10220
10221 Notes:
10222 The number of columns of the matrix in EACH processor MUST be the same.
10223
10224 @*/
MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat * mpimat)10225 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10226 {
10227 PetscErrorCode ierr;
10228
10229 PetscFunctionBegin;
10230 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10231 if (reuse == MAT_REUSE_MATRIX && seqmat == *mpimat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10232
10233 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10234 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10235 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10236 PetscFunctionReturn(0);
10237 }
10238
10239 /*@
10240 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10241 ranks' ownership ranges.
10242
10243 Collective on A
10244
10245 Input Parameters:
10246 + A - the matrix to create subdomains from
10247 - N - requested number of subdomains
10248
10249
10250 Output Parameters:
10251 + n - number of subdomains resulting on this rank
10252 - iss - IS list with indices of subdomains on this rank
10253
10254 Level: advanced
10255
10256 Notes:
10257 number of subdomains must be smaller than the communicator size
10258 @*/
MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt * n,IS * iss[])10259 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10260 {
10261 MPI_Comm comm,subcomm;
10262 PetscMPIInt size,rank,color;
10263 PetscInt rstart,rend,k;
10264 PetscErrorCode ierr;
10265
10266 PetscFunctionBegin;
10267 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10268 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10269 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10270 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);
10271 *n = 1;
10272 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10273 color = rank/k;
10274 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10275 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10276 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10277 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10278 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10279 PetscFunctionReturn(0);
10280 }
10281
10282 /*@
10283 MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10284
10285 If the interpolation and restriction operators are the same, uses MatPtAP.
10286 If they are not the same, use MatMatMatMult.
10287
10288 Once the coarse grid problem is constructed, correct for interpolation operators
10289 that are not of full rank, which can legitimately happen in the case of non-nested
10290 geometric multigrid.
10291
10292 Input Parameters:
10293 + restrct - restriction operator
10294 . dA - fine grid matrix
10295 . interpolate - interpolation operator
10296 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10297 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10298
10299 Output Parameters:
10300 . A - the Galerkin coarse matrix
10301
10302 Options Database Key:
10303 . -pc_mg_galerkin <both,pmat,mat,none>
10304
10305 Level: developer
10306
10307 .seealso: MatPtAP(), MatMatMatMult()
10308 @*/
MatGalerkin(Mat restrct,Mat dA,Mat interpolate,MatReuse reuse,PetscReal fill,Mat * A)10309 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10310 {
10311 PetscErrorCode ierr;
10312 IS zerorows;
10313 Vec diag;
10314
10315 PetscFunctionBegin;
10316 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10317 /* Construct the coarse grid matrix */
10318 if (interpolate == restrct) {
10319 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10320 } else {
10321 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10322 }
10323
10324 /* If the interpolation matrix is not of full rank, A will have zero rows.
10325 This can legitimately happen in the case of non-nested geometric multigrid.
10326 In that event, we set the rows of the matrix to the rows of the identity,
10327 ignoring the equations (as the RHS will also be zero). */
10328
10329 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10330
10331 if (zerorows != NULL) { /* if there are any zero rows */
10332 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10333 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10334 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10335 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10336 ierr = VecDestroy(&diag);CHKERRQ(ierr);
10337 ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10338 }
10339 PetscFunctionReturn(0);
10340 }
10341
10342 /*@C
10343 MatSetOperation - Allows user to set a matrix operation for any matrix type
10344
10345 Logically Collective on Mat
10346
10347 Input Parameters:
10348 + mat - the matrix
10349 . op - the name of the operation
10350 - f - the function that provides the operation
10351
10352 Level: developer
10353
10354 Usage:
10355 $ extern PetscErrorCode usermult(Mat,Vec,Vec);
10356 $ ierr = MatCreateXXX(comm,...&A);
10357 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10358
10359 Notes:
10360 See the file include/petscmat.h for a complete list of matrix
10361 operations, which all have the form MATOP_<OPERATION>, where
10362 <OPERATION> is the name (in all capital letters) of the
10363 user interface routine (e.g., MatMult() -> MATOP_MULT).
10364
10365 All user-provided functions (except for MATOP_DESTROY) should have the same calling
10366 sequence as the usual matrix interface routines, since they
10367 are intended to be accessed via the usual matrix interface
10368 routines, e.g.,
10369 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10370
10371 In particular each function MUST return an error code of 0 on success and
10372 nonzero on failure.
10373
10374 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10375
10376 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10377 @*/
MatSetOperation(Mat mat,MatOperation op,void (* f)(void))10378 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10379 {
10380 PetscFunctionBegin;
10381 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10382 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10383 mat->ops->viewnative = mat->ops->view;
10384 }
10385 (((void(**)(void))mat->ops)[op]) = f;
10386 PetscFunctionReturn(0);
10387 }
10388
10389 /*@C
10390 MatGetOperation - Gets a matrix operation for any matrix type.
10391
10392 Not Collective
10393
10394 Input Parameters:
10395 + mat - the matrix
10396 - op - the name of the operation
10397
10398 Output Parameter:
10399 . f - the function that provides the operation
10400
10401 Level: developer
10402
10403 Usage:
10404 $ PetscErrorCode (*usermult)(Mat,Vec,Vec);
10405 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10406
10407 Notes:
10408 See the file include/petscmat.h for a complete list of matrix
10409 operations, which all have the form MATOP_<OPERATION>, where
10410 <OPERATION> is the name (in all capital letters) of the
10411 user interface routine (e.g., MatMult() -> MATOP_MULT).
10412
10413 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10414
10415 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10416 @*/
MatGetOperation(Mat mat,MatOperation op,void (** f)(void))10417 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10418 {
10419 PetscFunctionBegin;
10420 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10421 *f = (((void (**)(void))mat->ops)[op]);
10422 PetscFunctionReturn(0);
10423 }
10424
10425 /*@
10426 MatHasOperation - Determines whether the given matrix supports the particular
10427 operation.
10428
10429 Not Collective
10430
10431 Input Parameters:
10432 + mat - the matrix
10433 - op - the operation, for example, MATOP_GET_DIAGONAL
10434
10435 Output Parameter:
10436 . has - either PETSC_TRUE or PETSC_FALSE
10437
10438 Level: advanced
10439
10440 Notes:
10441 See the file include/petscmat.h for a complete list of matrix
10442 operations, which all have the form MATOP_<OPERATION>, where
10443 <OPERATION> is the name (in all capital letters) of the
10444 user-level routine. E.g., MatNorm() -> MATOP_NORM.
10445
10446 .seealso: MatCreateShell()
10447 @*/
MatHasOperation(Mat mat,MatOperation op,PetscBool * has)10448 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10449 {
10450 PetscErrorCode ierr;
10451
10452 PetscFunctionBegin;
10453 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10454 /* symbolic product can be set before matrix type */
10455 if (op != MATOP_PRODUCTSYMBOLIC) PetscValidType(mat,1);
10456 PetscValidPointer(has,3);
10457 if (mat->ops->hasoperation) {
10458 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10459 } else {
10460 if (((void**)mat->ops)[op]) *has = PETSC_TRUE;
10461 else {
10462 *has = PETSC_FALSE;
10463 if (op == MATOP_CREATE_SUBMATRIX) {
10464 PetscMPIInt size;
10465
10466 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10467 if (size == 1) {
10468 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10469 }
10470 }
10471 }
10472 }
10473 PetscFunctionReturn(0);
10474 }
10475
10476 /*@
10477 MatHasCongruentLayouts - Determines whether the rows and columns layouts
10478 of the matrix are congruent
10479
10480 Collective on mat
10481
10482 Input Parameters:
10483 . mat - the matrix
10484
10485 Output Parameter:
10486 . cong - either PETSC_TRUE or PETSC_FALSE
10487
10488 Level: beginner
10489
10490 Notes:
10491
10492 .seealso: MatCreate(), MatSetSizes()
10493 @*/
MatHasCongruentLayouts(Mat mat,PetscBool * cong)10494 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
10495 {
10496 PetscErrorCode ierr;
10497
10498 PetscFunctionBegin;
10499 PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10500 PetscValidType(mat,1);
10501 PetscValidPointer(cong,2);
10502 if (!mat->rmap || !mat->cmap) {
10503 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
10504 PetscFunctionReturn(0);
10505 }
10506 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
10507 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
10508 if (*cong) mat->congruentlayouts = 1;
10509 else mat->congruentlayouts = 0;
10510 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
10511 PetscFunctionReturn(0);
10512 }
10513
MatSetInf(Mat A)10514 PetscErrorCode MatSetInf(Mat A)
10515 {
10516 PetscErrorCode ierr;
10517
10518 PetscFunctionBegin;
10519 if (!A->ops->setinf) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type");
10520 ierr = (*A->ops->setinf)(A);CHKERRQ(ierr);
10521 PetscFunctionReturn(0);
10522 }
10523