1 2 /* 3 This is where the abstract matrix operations are defined 4 */ 5 6 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 7 #include <petsc/private/isimpl.h> 8 #include <petsc/private/vecimpl.h> 9 10 /* Logging support */ 11 PetscClassId MAT_CLASSID; 12 PetscClassId MAT_COLORING_CLASSID; 13 PetscClassId MAT_FDCOLORING_CLASSID; 14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 15 16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch; 36 PetscLogEvent MAT_ViennaCLCopyToGPU; 37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 39 40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 41 42 /*@ 43 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations 44 45 Logically Collective on Mat 46 47 Input Parameters: 48 + x - the matrix 49 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 50 it will create one internally. 51 52 Output Parameter: 53 . x - the matrix 54 55 Example of Usage: 56 .vb 57 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 58 MatSetRandom(x,rctx); 59 PetscRandomDestroy(rctx); 60 .ve 61 62 Level: intermediate 63 64 Concepts: matrix^setting to random 65 Concepts: random^matrix 66 67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 68 @*/ 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 x->assembled = PETSC_TRUE; 94 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 95 PetscFunctionReturn(0); 96 } 97 98 /*@ 99 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 100 101 Logically Collective on Mat 102 103 Input Parameters: 104 . mat - the factored matrix 105 106 Output Parameter: 107 + pivot - the pivot value computed 108 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 109 the share the matrix 110 111 Level: advanced 112 113 Notes: 114 This routine does not work for factorizations done with external packages. 115 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 116 117 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 118 119 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 120 @*/ 121 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 122 { 123 PetscFunctionBegin; 124 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 125 *pivot = mat->factorerror_zeropivot_value; 126 *row = mat->factorerror_zeropivot_row; 127 PetscFunctionReturn(0); 128 } 129 130 /*@ 131 MatFactorGetError - gets the error code from a factorization 132 133 Logically Collective on Mat 134 135 Input Parameters: 136 . mat - the factored matrix 137 138 Output Parameter: 139 . err - the error code 140 141 Level: advanced 142 143 Notes: 144 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 145 146 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 147 @*/ 148 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 149 { 150 PetscFunctionBegin; 151 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 152 *err = mat->factorerrortype; 153 PetscFunctionReturn(0); 154 } 155 156 /*@ 157 MatFactorClearError - clears the error code in a factorization 158 159 Logically Collective on Mat 160 161 Input Parameter: 162 . mat - the factored matrix 163 164 Level: developer 165 166 Notes: 167 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 168 169 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 170 @*/ 171 PetscErrorCode MatFactorClearError(Mat mat) 172 { 173 PetscFunctionBegin; 174 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 175 mat->factorerrortype = MAT_FACTOR_NOERROR; 176 mat->factorerror_zeropivot_value = 0.0; 177 mat->factorerror_zeropivot_row = 0; 178 PetscFunctionReturn(0); 179 } 180 181 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 182 { 183 PetscErrorCode ierr; 184 Vec r,l; 185 const PetscScalar *al; 186 PetscInt i,nz,gnz,N,n; 187 188 PetscFunctionBegin; 189 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 190 if (!cols) { /* nonzero rows */ 191 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 192 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 193 ierr = VecSet(l,0.0);CHKERRQ(ierr); 194 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 195 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 196 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 197 } else { /* nonzero columns */ 198 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 199 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 200 ierr = VecSet(r,0.0);CHKERRQ(ierr); 201 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 202 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 203 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 204 } 205 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 206 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 207 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 208 if (gnz != N) { 209 PetscInt *nzr; 210 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 211 if (nz) { 212 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 213 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 214 } 215 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 216 } else *nonzero = NULL; 217 if (!cols) { /* nonzero rows */ 218 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 219 } else { 220 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 221 } 222 ierr = VecDestroy(&l);CHKERRQ(ierr); 223 ierr = VecDestroy(&r);CHKERRQ(ierr); 224 PetscFunctionReturn(0); 225 } 226 227 /*@ 228 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 229 230 Input Parameter: 231 . A - the matrix 232 233 Output Parameter: 234 . keptrows - the rows that are not completely zero 235 236 Notes: 237 keptrows is set to NULL if all rows are nonzero. 238 239 Level: intermediate 240 241 @*/ 242 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 243 { 244 PetscErrorCode ierr; 245 246 PetscFunctionBegin; 247 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 248 PetscValidType(mat,1); 249 PetscValidPointer(keptrows,2); 250 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 251 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 252 if (!mat->ops->findnonzerorows) { 253 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 254 } else { 255 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 256 } 257 PetscFunctionReturn(0); 258 } 259 260 /*@ 261 MatFindZeroRows - Locate all rows that are completely zero in the matrix 262 263 Input Parameter: 264 . A - the matrix 265 266 Output Parameter: 267 . zerorows - the rows that are completely zero 268 269 Notes: 270 zerorows is set to NULL if no rows are zero. 271 272 Level: intermediate 273 274 @*/ 275 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 276 { 277 PetscErrorCode ierr; 278 IS keptrows; 279 PetscInt m, n; 280 281 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 282 PetscValidType(mat,1); 283 284 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 285 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 286 In keeping with this convention, we set zerorows to NULL if there are no zero 287 rows. */ 288 if (keptrows == NULL) { 289 *zerorows = NULL; 290 } else { 291 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 292 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 293 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 294 } 295 PetscFunctionReturn(0); 296 } 297 298 /*@ 299 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 300 301 Not Collective 302 303 Input Parameters: 304 . A - the matrix 305 306 Output Parameters: 307 . a - the diagonal part (which is a SEQUENTIAL matrix) 308 309 Notes: 310 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 311 Use caution, as the reference count on the returned matrix is not incremented and it is used as 312 part of the containing MPI Mat's normal operation. 313 314 Level: advanced 315 316 @*/ 317 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 318 { 319 PetscErrorCode ierr; 320 321 PetscFunctionBegin; 322 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 323 PetscValidType(A,1); 324 PetscValidPointer(a,3); 325 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 326 if (!A->ops->getdiagonalblock) { 327 PetscMPIInt size; 328 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 329 if (size == 1) { 330 *a = A; 331 PetscFunctionReturn(0); 332 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type"); 333 } 334 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 335 PetscFunctionReturn(0); 336 } 337 338 /*@ 339 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 340 341 Collective on Mat 342 343 Input Parameters: 344 . mat - the matrix 345 346 Output Parameter: 347 . trace - the sum of the diagonal entries 348 349 Level: advanced 350 351 @*/ 352 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 353 { 354 PetscErrorCode ierr; 355 Vec diag; 356 357 PetscFunctionBegin; 358 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 359 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 360 ierr = VecSum(diag,trace);CHKERRQ(ierr); 361 ierr = VecDestroy(&diag);CHKERRQ(ierr); 362 PetscFunctionReturn(0); 363 } 364 365 /*@ 366 MatRealPart - Zeros out the imaginary part of the matrix 367 368 Logically Collective on Mat 369 370 Input Parameters: 371 . mat - the matrix 372 373 Level: advanced 374 375 376 .seealso: MatImaginaryPart() 377 @*/ 378 PetscErrorCode MatRealPart(Mat mat) 379 { 380 PetscErrorCode ierr; 381 382 PetscFunctionBegin; 383 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 384 PetscValidType(mat,1); 385 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 386 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 387 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 388 MatCheckPreallocated(mat,1); 389 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 390 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 391 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 392 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 393 } 394 #endif 395 PetscFunctionReturn(0); 396 } 397 398 /*@C 399 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 400 401 Collective on Mat 402 403 Input Parameter: 404 . mat - the matrix 405 406 Output Parameters: 407 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 408 - ghosts - the global indices of the ghost points 409 410 Notes: 411 the nghosts and ghosts are suitable to pass into VecCreateGhost() 412 413 Level: advanced 414 415 @*/ 416 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 417 { 418 PetscErrorCode ierr; 419 420 PetscFunctionBegin; 421 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 422 PetscValidType(mat,1); 423 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 424 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 425 if (!mat->ops->getghosts) { 426 if (nghosts) *nghosts = 0; 427 if (ghosts) *ghosts = 0; 428 } else { 429 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 430 } 431 PetscFunctionReturn(0); 432 } 433 434 435 /*@ 436 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 437 438 Logically Collective on Mat 439 440 Input Parameters: 441 . mat - the matrix 442 443 Level: advanced 444 445 446 .seealso: MatRealPart() 447 @*/ 448 PetscErrorCode MatImaginaryPart(Mat mat) 449 { 450 PetscErrorCode ierr; 451 452 PetscFunctionBegin; 453 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 454 PetscValidType(mat,1); 455 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 456 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 457 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 458 MatCheckPreallocated(mat,1); 459 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 460 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 461 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 462 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 463 } 464 #endif 465 PetscFunctionReturn(0); 466 } 467 468 /*@ 469 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 470 471 Not Collective 472 473 Input Parameter: 474 . mat - the matrix 475 476 Output Parameters: 477 + missing - is any diagonal missing 478 - dd - first diagonal entry that is missing (optional) on this process 479 480 Level: advanced 481 482 483 .seealso: MatRealPart() 484 @*/ 485 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 486 { 487 PetscErrorCode ierr; 488 489 PetscFunctionBegin; 490 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 491 PetscValidType(mat,1); 492 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 493 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 494 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 495 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 496 PetscFunctionReturn(0); 497 } 498 499 /*@C 500 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 501 for each row that you get to ensure that your application does 502 not bleed memory. 503 504 Not Collective 505 506 Input Parameters: 507 + mat - the matrix 508 - row - the row to get 509 510 Output Parameters: 511 + ncols - if not NULL, the number of nonzeros in the row 512 . cols - if not NULL, the column numbers 513 - vals - if not NULL, the values 514 515 Notes: 516 This routine is provided for people who need to have direct access 517 to the structure of a matrix. We hope that we provide enough 518 high-level matrix routines that few users will need it. 519 520 MatGetRow() always returns 0-based column indices, regardless of 521 whether the internal representation is 0-based (default) or 1-based. 522 523 For better efficiency, set cols and/or vals to NULL if you do 524 not wish to extract these quantities. 525 526 The user can only examine the values extracted with MatGetRow(); 527 the values cannot be altered. To change the matrix entries, one 528 must use MatSetValues(). 529 530 You can only have one call to MatGetRow() outstanding for a particular 531 matrix at a time, per processor. MatGetRow() can only obtain rows 532 associated with the given processor, it cannot get rows from the 533 other processors; for that we suggest using MatCreateSubMatrices(), then 534 MatGetRow() on the submatrix. The row index passed to MatGetRows() 535 is in the global number of rows. 536 537 Fortran Notes: 538 The calling sequence from Fortran is 539 .vb 540 MatGetRow(matrix,row,ncols,cols,values,ierr) 541 Mat matrix (input) 542 integer row (input) 543 integer ncols (output) 544 integer cols(maxcols) (output) 545 double precision (or double complex) values(maxcols) output 546 .ve 547 where maxcols >= maximum nonzeros in any row of the matrix. 548 549 550 Caution: 551 Do not try to change the contents of the output arrays (cols and vals). 552 In some cases, this may corrupt the matrix. 553 554 Level: advanced 555 556 Concepts: matrices^row access 557 558 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 559 @*/ 560 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 561 { 562 PetscErrorCode ierr; 563 PetscInt incols; 564 565 PetscFunctionBegin; 566 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 567 PetscValidType(mat,1); 568 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 569 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 570 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 571 MatCheckPreallocated(mat,1); 572 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 573 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 574 if (ncols) *ncols = incols; 575 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 576 PetscFunctionReturn(0); 577 } 578 579 /*@ 580 MatConjugate - replaces the matrix values with their complex conjugates 581 582 Logically Collective on Mat 583 584 Input Parameters: 585 . mat - the matrix 586 587 Level: advanced 588 589 .seealso: VecConjugate() 590 @*/ 591 PetscErrorCode MatConjugate(Mat mat) 592 { 593 #if defined(PETSC_USE_COMPLEX) 594 PetscErrorCode ierr; 595 596 PetscFunctionBegin; 597 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 598 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 599 if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov"); 600 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 601 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 602 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 603 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 604 } 605 #endif 606 PetscFunctionReturn(0); 607 #else 608 return 0; 609 #endif 610 } 611 612 /*@C 613 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 614 615 Not Collective 616 617 Input Parameters: 618 + mat - the matrix 619 . row - the row to get 620 . ncols, cols - the number of nonzeros and their columns 621 - vals - if nonzero the column values 622 623 Notes: 624 This routine should be called after you have finished examining the entries. 625 626 This routine zeros out ncols, cols, and vals. This is to prevent accidental 627 us of the array after it has been restored. If you pass NULL, it will 628 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 629 630 Fortran Notes: 631 The calling sequence from Fortran is 632 .vb 633 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 634 Mat matrix (input) 635 integer row (input) 636 integer ncols (output) 637 integer cols(maxcols) (output) 638 double precision (or double complex) values(maxcols) output 639 .ve 640 Where maxcols >= maximum nonzeros in any row of the matrix. 641 642 In Fortran MatRestoreRow() MUST be called after MatGetRow() 643 before another call to MatGetRow() can be made. 644 645 Level: advanced 646 647 .seealso: MatGetRow() 648 @*/ 649 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 650 { 651 PetscErrorCode ierr; 652 653 PetscFunctionBegin; 654 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 655 if (ncols) PetscValidIntPointer(ncols,3); 656 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 657 if (!mat->ops->restorerow) PetscFunctionReturn(0); 658 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 659 if (ncols) *ncols = 0; 660 if (cols) *cols = NULL; 661 if (vals) *vals = NULL; 662 PetscFunctionReturn(0); 663 } 664 665 /*@ 666 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 667 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 668 669 Not Collective 670 671 Input Parameters: 672 + mat - the matrix 673 674 Notes: 675 The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format. 676 677 Level: advanced 678 679 Concepts: matrices^row access 680 681 .seealso: MatRestoreRowRowUpperTriangular() 682 @*/ 683 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 684 { 685 PetscErrorCode ierr; 686 687 PetscFunctionBegin; 688 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 689 PetscValidType(mat,1); 690 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 691 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 692 if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 693 MatCheckPreallocated(mat,1); 694 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 695 PetscFunctionReturn(0); 696 } 697 698 /*@ 699 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 700 701 Not Collective 702 703 Input Parameters: 704 + mat - the matrix 705 706 Notes: 707 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 708 709 710 Level: advanced 711 712 .seealso: MatGetRowUpperTriangular() 713 @*/ 714 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 715 { 716 PetscErrorCode ierr; 717 718 PetscFunctionBegin; 719 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 720 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 721 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 722 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 723 PetscFunctionReturn(0); 724 } 725 726 /*@C 727 MatSetOptionsPrefix - Sets the prefix used for searching for all 728 Mat options in the database. 729 730 Logically Collective on Mat 731 732 Input Parameter: 733 + A - the Mat context 734 - prefix - the prefix to prepend to all option names 735 736 Notes: 737 A hyphen (-) must NOT be given at the beginning of the prefix name. 738 The first character of all runtime options is AUTOMATICALLY the hyphen. 739 740 Level: advanced 741 742 .keywords: Mat, set, options, prefix, database 743 744 .seealso: MatSetFromOptions() 745 @*/ 746 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 747 { 748 PetscErrorCode ierr; 749 750 PetscFunctionBegin; 751 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 752 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 753 PetscFunctionReturn(0); 754 } 755 756 /*@C 757 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 758 Mat options in the database. 759 760 Logically Collective on Mat 761 762 Input Parameters: 763 + A - the Mat context 764 - prefix - the prefix to prepend to all option names 765 766 Notes: 767 A hyphen (-) must NOT be given at the beginning of the prefix name. 768 The first character of all runtime options is AUTOMATICALLY the hyphen. 769 770 Level: advanced 771 772 .keywords: Mat, append, options, prefix, database 773 774 .seealso: MatGetOptionsPrefix() 775 @*/ 776 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 777 { 778 PetscErrorCode ierr; 779 780 PetscFunctionBegin; 781 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 782 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 783 PetscFunctionReturn(0); 784 } 785 786 /*@C 787 MatGetOptionsPrefix - Sets the prefix used for searching for all 788 Mat options in the database. 789 790 Not Collective 791 792 Input Parameter: 793 . A - the Mat context 794 795 Output Parameter: 796 . prefix - pointer to the prefix string used 797 798 Notes: 799 On the fortran side, the user should pass in a string 'prefix' of 800 sufficient length to hold the prefix. 801 802 Level: advanced 803 804 .keywords: Mat, get, options, prefix, database 805 806 .seealso: MatAppendOptionsPrefix() 807 @*/ 808 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 809 { 810 PetscErrorCode ierr; 811 812 PetscFunctionBegin; 813 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 814 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 815 PetscFunctionReturn(0); 816 } 817 818 /*@ 819 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 820 821 Collective on Mat 822 823 Input Parameters: 824 . A - the Mat context 825 826 Notes: 827 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 828 Currently support MPIAIJ and SEQAIJ. 829 830 Level: beginner 831 832 .keywords: Mat, ResetPreallocation 833 834 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 835 @*/ 836 PetscErrorCode MatResetPreallocation(Mat A) 837 { 838 PetscErrorCode ierr; 839 840 PetscFunctionBegin; 841 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 842 PetscValidType(A,1); 843 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 844 PetscFunctionReturn(0); 845 } 846 847 848 /*@ 849 MatSetUp - Sets up the internal matrix data structures for the later use. 850 851 Collective on Mat 852 853 Input Parameters: 854 . A - the Mat context 855 856 Notes: 857 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 858 859 If a suitable preallocation routine is used, this function does not need to be called. 860 861 See the Performance chapter of the PETSc users manual for how to preallocate matrices 862 863 Level: beginner 864 865 .keywords: Mat, setup 866 867 .seealso: MatCreate(), MatDestroy() 868 @*/ 869 PetscErrorCode MatSetUp(Mat A) 870 { 871 PetscMPIInt size; 872 PetscErrorCode ierr; 873 874 PetscFunctionBegin; 875 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 876 if (!((PetscObject)A)->type_name) { 877 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 878 if (size == 1) { 879 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 880 } else { 881 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 882 } 883 } 884 if (!A->preallocated && A->ops->setup) { 885 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 886 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 887 } 888 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 889 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 890 A->preallocated = PETSC_TRUE; 891 PetscFunctionReturn(0); 892 } 893 894 #if defined(PETSC_HAVE_SAWS) 895 #include <petscviewersaws.h> 896 #endif 897 /*@C 898 MatView - Visualizes a matrix object. 899 900 Collective on Mat 901 902 Input Parameters: 903 + mat - the matrix 904 - viewer - visualization context 905 906 Notes: 907 The available visualization contexts include 908 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 909 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 910 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 911 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 912 913 The user can open alternative visualization contexts with 914 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 915 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 916 specified file; corresponding input uses MatLoad() 917 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 918 an X window display 919 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 920 Currently only the sequential dense and AIJ 921 matrix types support the Socket viewer. 922 923 The user can call PetscViewerPushFormat() to specify the output 924 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 925 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 926 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 927 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 928 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 929 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 930 format common among all matrix types 931 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 932 format (which is in many cases the same as the default) 933 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 934 size and structure (not the matrix entries) 935 . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 936 the matrix structure 937 938 Options Database Keys: 939 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 940 . -mat_view ::ascii_info_detail - Prints more detailed info 941 . -mat_view - Prints matrix in ASCII format 942 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 943 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 944 . -display <name> - Sets display name (default is host) 945 . -draw_pause <sec> - Sets number of seconds to pause after display 946 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 947 . -viewer_socket_machine <machine> - 948 . -viewer_socket_port <port> - 949 . -mat_view binary - save matrix to file in binary format 950 - -viewer_binary_filename <name> - 951 Level: beginner 952 953 Notes: 954 see the manual page for MatLoad() for the exact format of the binary file when the binary 955 viewer is used. 956 957 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 958 viewer is used. 959 960 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure. 961 And then use the following mouse functions: 962 left mouse: zoom in 963 middle mouse: zoom out 964 right mouse: continue with the simulation 965 966 Concepts: matrices^viewing 967 Concepts: matrices^plotting 968 Concepts: matrices^printing 969 970 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 971 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 972 @*/ 973 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 974 { 975 PetscErrorCode ierr; 976 PetscInt rows,cols,rbs,cbs; 977 PetscBool iascii,ibinary; 978 PetscViewerFormat format; 979 PetscMPIInt size; 980 #if defined(PETSC_HAVE_SAWS) 981 PetscBool issaws; 982 #endif 983 984 PetscFunctionBegin; 985 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 986 PetscValidType(mat,1); 987 if (!viewer) { 988 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 989 } 990 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 991 PetscCheckSameComm(mat,1,viewer,2); 992 MatCheckPreallocated(mat,1); 993 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 994 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 995 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 996 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 997 if (ibinary) { 998 PetscBool mpiio; 999 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 1000 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 1001 } 1002 1003 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1004 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1005 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1006 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 1007 } 1008 1009 #if defined(PETSC_HAVE_SAWS) 1010 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 1011 #endif 1012 if (iascii) { 1013 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1014 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 1015 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1016 MatNullSpace nullsp,transnullsp; 1017 1018 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1019 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1020 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1021 if (rbs != 1 || cbs != 1) { 1022 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 1023 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 1024 } else { 1025 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1026 } 1027 if (mat->factortype) { 1028 MatSolverType solver; 1029 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1030 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1031 } 1032 if (mat->ops->getinfo) { 1033 MatInfo info; 1034 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1035 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1036 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1037 } 1038 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1039 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1040 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1041 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1042 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1043 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1044 } 1045 #if defined(PETSC_HAVE_SAWS) 1046 } else if (issaws) { 1047 PetscMPIInt rank; 1048 1049 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1050 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1051 if (!((PetscObject)mat)->amsmem && !rank) { 1052 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1053 } 1054 #endif 1055 } 1056 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1057 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1058 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1059 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1060 } else if (mat->ops->view) { 1061 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1062 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1063 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1064 } 1065 if (iascii) { 1066 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1067 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1068 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1069 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1070 } 1071 } 1072 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1073 PetscFunctionReturn(0); 1074 } 1075 1076 #if defined(PETSC_USE_DEBUG) 1077 #include <../src/sys/totalview/tv_data_display.h> 1078 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1079 { 1080 TV_add_row("Local rows", "int", &mat->rmap->n); 1081 TV_add_row("Local columns", "int", &mat->cmap->n); 1082 TV_add_row("Global rows", "int", &mat->rmap->N); 1083 TV_add_row("Global columns", "int", &mat->cmap->N); 1084 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1085 return TV_format_OK; 1086 } 1087 #endif 1088 1089 /*@C 1090 MatLoad - Loads a matrix that has been stored in binary format 1091 with MatView(). The matrix format is determined from the options database. 1092 Generates a parallel MPI matrix if the communicator has more than one 1093 processor. The default matrix type is AIJ. 1094 1095 Collective on PetscViewer 1096 1097 Input Parameters: 1098 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1099 or some related function before a call to MatLoad() 1100 - viewer - binary file viewer, created with PetscViewerBinaryOpen() 1101 1102 Options Database Keys: 1103 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1104 block size 1105 . -matload_block_size <bs> 1106 1107 Level: beginner 1108 1109 Notes: 1110 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1111 Mat before calling this routine if you wish to set it from the options database. 1112 1113 MatLoad() automatically loads into the options database any options 1114 given in the file filename.info where filename is the name of the file 1115 that was passed to the PetscViewerBinaryOpen(). The options in the info 1116 file will be ignored if you use the -viewer_binary_skip_info option. 1117 1118 If the type or size of newmat is not set before a call to MatLoad, PETSc 1119 sets the default matrix type AIJ and sets the local and global sizes. 1120 If type and/or size is already set, then the same are used. 1121 1122 In parallel, each processor can load a subset of rows (or the 1123 entire matrix). This routine is especially useful when a large 1124 matrix is stored on disk and only part of it is desired on each 1125 processor. For example, a parallel solver may access only some of 1126 the rows from each processor. The algorithm used here reads 1127 relatively small blocks of data rather than reading the entire 1128 matrix and then subsetting it. 1129 1130 Notes for advanced users: 1131 Most users should not need to know the details of the binary storage 1132 format, since MatLoad() and MatView() completely hide these details. 1133 But for anyone who's interested, the standard binary matrix storage 1134 format is 1135 1136 $ int MAT_FILE_CLASSID 1137 $ int number of rows 1138 $ int number of columns 1139 $ int total number of nonzeros 1140 $ int *number nonzeros in each row 1141 $ int *column indices of all nonzeros (starting index is zero) 1142 $ PetscScalar *values of all nonzeros 1143 1144 PETSc automatically does the byte swapping for 1145 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1146 linux, Windows and the paragon; thus if you write your own binary 1147 read/write routines you have to swap the bytes; see PetscBinaryRead() 1148 and PetscBinaryWrite() to see how this may be done. 1149 1150 .keywords: matrix, load, binary, input 1151 1152 .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad() 1153 1154 @*/ 1155 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1156 { 1157 PetscErrorCode ierr; 1158 PetscBool isbinary,flg; 1159 1160 PetscFunctionBegin; 1161 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1162 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1163 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1164 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 1165 1166 if (!((PetscObject)newmat)->type_name) { 1167 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1168 } 1169 1170 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 1171 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1172 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1173 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1174 1175 flg = PETSC_FALSE; 1176 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1177 if (flg) { 1178 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1179 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1180 } 1181 flg = PETSC_FALSE; 1182 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1183 if (flg) { 1184 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1185 } 1186 PetscFunctionReturn(0); 1187 } 1188 1189 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1190 { 1191 PetscErrorCode ierr; 1192 Mat_Redundant *redund = *redundant; 1193 PetscInt i; 1194 1195 PetscFunctionBegin; 1196 if (redund){ 1197 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1198 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1199 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1200 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1201 } else { 1202 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1203 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1204 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1205 for (i=0; i<redund->nrecvs; i++) { 1206 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1207 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1208 } 1209 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1210 } 1211 1212 if (redund->subcomm) { 1213 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1214 } 1215 ierr = PetscFree(redund);CHKERRQ(ierr); 1216 } 1217 PetscFunctionReturn(0); 1218 } 1219 1220 /*@ 1221 MatDestroy - Frees space taken by a matrix. 1222 1223 Collective on Mat 1224 1225 Input Parameter: 1226 . A - the matrix 1227 1228 Level: beginner 1229 1230 @*/ 1231 PetscErrorCode MatDestroy(Mat *A) 1232 { 1233 PetscErrorCode ierr; 1234 1235 PetscFunctionBegin; 1236 if (!*A) PetscFunctionReturn(0); 1237 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1238 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1239 1240 /* if memory was published with SAWs then destroy it */ 1241 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1242 if ((*A)->ops->destroy) { 1243 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1244 } 1245 1246 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1247 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1248 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1249 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1250 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1251 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1252 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1253 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1254 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1255 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1256 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1257 PetscFunctionReturn(0); 1258 } 1259 1260 /*@C 1261 MatSetValues - Inserts or adds a block of values into a matrix. 1262 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1263 MUST be called after all calls to MatSetValues() have been completed. 1264 1265 Not Collective 1266 1267 Input Parameters: 1268 + mat - the matrix 1269 . v - a logically two-dimensional array of values 1270 . m, idxm - the number of rows and their global indices 1271 . n, idxn - the number of columns and their global indices 1272 - addv - either ADD_VALUES or INSERT_VALUES, where 1273 ADD_VALUES adds values to any existing entries, and 1274 INSERT_VALUES replaces existing entries with new values 1275 1276 Notes: 1277 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1278 MatSetUp() before using this routine 1279 1280 By default the values, v, are row-oriented. See MatSetOption() for other options. 1281 1282 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1283 options cannot be mixed without intervening calls to the assembly 1284 routines. 1285 1286 MatSetValues() uses 0-based row and column numbers in Fortran 1287 as well as in C. 1288 1289 Negative indices may be passed in idxm and idxn, these rows and columns are 1290 simply ignored. This allows easily inserting element stiffness matrices 1291 with homogeneous Dirchlet boundary conditions that you don't want represented 1292 in the matrix. 1293 1294 Efficiency Alert: 1295 The routine MatSetValuesBlocked() may offer much better efficiency 1296 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1297 1298 Level: beginner 1299 1300 Developer Notes: 1301 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1302 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1303 1304 Concepts: matrices^putting entries in 1305 1306 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1307 InsertMode, INSERT_VALUES, ADD_VALUES 1308 @*/ 1309 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1310 { 1311 PetscErrorCode ierr; 1312 #if defined(PETSC_USE_DEBUG) 1313 PetscInt i,j; 1314 #endif 1315 1316 PetscFunctionBeginHot; 1317 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1318 PetscValidType(mat,1); 1319 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1320 PetscValidIntPointer(idxm,3); 1321 PetscValidIntPointer(idxn,5); 1322 PetscValidScalarPointer(v,6); 1323 MatCheckPreallocated(mat,1); 1324 if (mat->insertmode == NOT_SET_VALUES) { 1325 mat->insertmode = addv; 1326 } 1327 #if defined(PETSC_USE_DEBUG) 1328 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1329 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1330 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1331 1332 for (i=0; i<m; i++) { 1333 for (j=0; j<n; j++) { 1334 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1335 #if defined(PETSC_USE_COMPLEX) 1336 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]); 1337 #else 1338 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1339 #endif 1340 } 1341 } 1342 #endif 1343 1344 if (mat->assembled) { 1345 mat->was_assembled = PETSC_TRUE; 1346 mat->assembled = PETSC_FALSE; 1347 } 1348 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1349 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1350 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1351 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 1352 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1353 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1354 } 1355 #endif 1356 PetscFunctionReturn(0); 1357 } 1358 1359 1360 /*@ 1361 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1362 values into a matrix 1363 1364 Not Collective 1365 1366 Input Parameters: 1367 + mat - the matrix 1368 . row - the (block) row to set 1369 - v - a logically two-dimensional array of values 1370 1371 Notes: 1372 By the values, v, are column-oriented (for the block version) and sorted 1373 1374 All the nonzeros in the row must be provided 1375 1376 The matrix must have previously had its column indices set 1377 1378 The row must belong to this process 1379 1380 Level: intermediate 1381 1382 Concepts: matrices^putting entries in 1383 1384 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1385 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1386 @*/ 1387 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1388 { 1389 PetscErrorCode ierr; 1390 PetscInt globalrow; 1391 1392 PetscFunctionBegin; 1393 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1394 PetscValidType(mat,1); 1395 PetscValidScalarPointer(v,2); 1396 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1397 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1398 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 1399 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1400 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1401 } 1402 #endif 1403 PetscFunctionReturn(0); 1404 } 1405 1406 /*@ 1407 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1408 values into a matrix 1409 1410 Not Collective 1411 1412 Input Parameters: 1413 + mat - the matrix 1414 . row - the (block) row to set 1415 - 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 1416 1417 Notes: 1418 The values, v, are column-oriented for the block version. 1419 1420 All the nonzeros in the row must be provided 1421 1422 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1423 1424 The row must belong to this process 1425 1426 Level: advanced 1427 1428 Concepts: matrices^putting entries in 1429 1430 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1431 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1432 @*/ 1433 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1434 { 1435 PetscErrorCode ierr; 1436 1437 PetscFunctionBeginHot; 1438 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1439 PetscValidType(mat,1); 1440 MatCheckPreallocated(mat,1); 1441 PetscValidScalarPointer(v,2); 1442 #if defined(PETSC_USE_DEBUG) 1443 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1444 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1445 #endif 1446 mat->insertmode = INSERT_VALUES; 1447 1448 if (mat->assembled) { 1449 mat->was_assembled = PETSC_TRUE; 1450 mat->assembled = PETSC_FALSE; 1451 } 1452 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1453 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1454 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1455 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1456 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 1457 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1458 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1459 } 1460 #endif 1461 PetscFunctionReturn(0); 1462 } 1463 1464 /*@ 1465 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1466 Using structured grid indexing 1467 1468 Not Collective 1469 1470 Input Parameters: 1471 + mat - the matrix 1472 . m - number of rows being entered 1473 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1474 . n - number of columns being entered 1475 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1476 . v - a logically two-dimensional array of values 1477 - addv - either ADD_VALUES or INSERT_VALUES, where 1478 ADD_VALUES adds values to any existing entries, and 1479 INSERT_VALUES replaces existing entries with new values 1480 1481 Notes: 1482 By default the values, v, are row-oriented. See MatSetOption() for other options. 1483 1484 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1485 options cannot be mixed without intervening calls to the assembly 1486 routines. 1487 1488 The grid coordinates are across the entire grid, not just the local portion 1489 1490 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1491 as well as in C. 1492 1493 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1494 1495 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1496 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1497 1498 The columns and rows in the stencil passed in MUST be contained within the 1499 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1500 if you create a DMDA with an overlap of one grid level and on a particular process its first 1501 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1502 first i index you can use in your column and row indices in MatSetStencil() is 5. 1503 1504 In Fortran idxm and idxn should be declared as 1505 $ MatStencil idxm(4,m),idxn(4,n) 1506 and the values inserted using 1507 $ idxm(MatStencil_i,1) = i 1508 $ idxm(MatStencil_j,1) = j 1509 $ idxm(MatStencil_k,1) = k 1510 $ idxm(MatStencil_c,1) = c 1511 etc 1512 1513 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1514 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1515 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1516 DM_BOUNDARY_PERIODIC boundary type. 1517 1518 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 1519 a single value per point) you can skip filling those indices. 1520 1521 Inspired by the structured grid interface to the HYPRE package 1522 (http://www.llnl.gov/CASC/hypre) 1523 1524 Efficiency Alert: 1525 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1526 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1527 1528 Level: beginner 1529 1530 Concepts: matrices^putting entries in 1531 1532 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1533 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1534 @*/ 1535 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1536 { 1537 PetscErrorCode ierr; 1538 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1539 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1540 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1541 1542 PetscFunctionBegin; 1543 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1544 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1545 PetscValidType(mat,1); 1546 PetscValidIntPointer(idxm,3); 1547 PetscValidIntPointer(idxn,5); 1548 PetscValidScalarPointer(v,6); 1549 1550 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1551 jdxm = buf; jdxn = buf+m; 1552 } else { 1553 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1554 jdxm = bufm; jdxn = bufn; 1555 } 1556 for (i=0; i<m; i++) { 1557 for (j=0; j<3-sdim; j++) dxm++; 1558 tmp = *dxm++ - starts[0]; 1559 for (j=0; j<dim-1; j++) { 1560 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1561 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1562 } 1563 if (mat->stencil.noc) dxm++; 1564 jdxm[i] = tmp; 1565 } 1566 for (i=0; i<n; i++) { 1567 for (j=0; j<3-sdim; j++) dxn++; 1568 tmp = *dxn++ - starts[0]; 1569 for (j=0; j<dim-1; j++) { 1570 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1571 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1572 } 1573 if (mat->stencil.noc) dxn++; 1574 jdxn[i] = tmp; 1575 } 1576 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1577 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1578 PetscFunctionReturn(0); 1579 } 1580 1581 /*@ 1582 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1583 Using structured grid indexing 1584 1585 Not Collective 1586 1587 Input Parameters: 1588 + mat - the matrix 1589 . m - number of rows being entered 1590 . idxm - grid coordinates for matrix rows being entered 1591 . n - number of columns being entered 1592 . idxn - grid coordinates for matrix columns being entered 1593 . v - a logically two-dimensional array of values 1594 - addv - either ADD_VALUES or INSERT_VALUES, where 1595 ADD_VALUES adds values to any existing entries, and 1596 INSERT_VALUES replaces existing entries with new values 1597 1598 Notes: 1599 By default the values, v, are row-oriented and unsorted. 1600 See MatSetOption() for other options. 1601 1602 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1603 options cannot be mixed without intervening calls to the assembly 1604 routines. 1605 1606 The grid coordinates are across the entire grid, not just the local portion 1607 1608 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1609 as well as in C. 1610 1611 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1612 1613 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1614 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1615 1616 The columns and rows in the stencil passed in MUST be contained within the 1617 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1618 if you create a DMDA with an overlap of one grid level and on a particular process its first 1619 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1620 first i index you can use in your column and row indices in MatSetStencil() is 5. 1621 1622 In Fortran idxm and idxn should be declared as 1623 $ MatStencil idxm(4,m),idxn(4,n) 1624 and the values inserted using 1625 $ idxm(MatStencil_i,1) = i 1626 $ idxm(MatStencil_j,1) = j 1627 $ idxm(MatStencil_k,1) = k 1628 etc 1629 1630 Negative indices may be passed in idxm and idxn, these rows and columns are 1631 simply ignored. This allows easily inserting element stiffness matrices 1632 with homogeneous Dirchlet boundary conditions that you don't want represented 1633 in the matrix. 1634 1635 Inspired by the structured grid interface to the HYPRE package 1636 (http://www.llnl.gov/CASC/hypre) 1637 1638 Level: beginner 1639 1640 Concepts: matrices^putting entries in 1641 1642 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1643 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1644 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1645 @*/ 1646 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1647 { 1648 PetscErrorCode ierr; 1649 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1650 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1651 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1652 1653 PetscFunctionBegin; 1654 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1655 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1656 PetscValidType(mat,1); 1657 PetscValidIntPointer(idxm,3); 1658 PetscValidIntPointer(idxn,5); 1659 PetscValidScalarPointer(v,6); 1660 1661 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1662 jdxm = buf; jdxn = buf+m; 1663 } else { 1664 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1665 jdxm = bufm; jdxn = bufn; 1666 } 1667 for (i=0; i<m; i++) { 1668 for (j=0; j<3-sdim; j++) dxm++; 1669 tmp = *dxm++ - starts[0]; 1670 for (j=0; j<sdim-1; j++) { 1671 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1672 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1673 } 1674 dxm++; 1675 jdxm[i] = tmp; 1676 } 1677 for (i=0; i<n; i++) { 1678 for (j=0; j<3-sdim; j++) dxn++; 1679 tmp = *dxn++ - starts[0]; 1680 for (j=0; j<sdim-1; j++) { 1681 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1682 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1683 } 1684 dxn++; 1685 jdxn[i] = tmp; 1686 } 1687 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1688 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1689 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 1690 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1691 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1692 } 1693 #endif 1694 PetscFunctionReturn(0); 1695 } 1696 1697 /*@ 1698 MatSetStencil - Sets the grid information for setting values into a matrix via 1699 MatSetValuesStencil() 1700 1701 Not Collective 1702 1703 Input Parameters: 1704 + mat - the matrix 1705 . dim - dimension of the grid 1, 2, or 3 1706 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1707 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1708 - dof - number of degrees of freedom per node 1709 1710 1711 Inspired by the structured grid interface to the HYPRE package 1712 (www.llnl.gov/CASC/hyper) 1713 1714 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1715 user. 1716 1717 Level: beginner 1718 1719 Concepts: matrices^putting entries in 1720 1721 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1722 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1723 @*/ 1724 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1725 { 1726 PetscInt i; 1727 1728 PetscFunctionBegin; 1729 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1730 PetscValidIntPointer(dims,3); 1731 PetscValidIntPointer(starts,4); 1732 1733 mat->stencil.dim = dim + (dof > 1); 1734 for (i=0; i<dim; i++) { 1735 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1736 mat->stencil.starts[i] = starts[dim-i-1]; 1737 } 1738 mat->stencil.dims[dim] = dof; 1739 mat->stencil.starts[dim] = 0; 1740 mat->stencil.noc = (PetscBool)(dof == 1); 1741 PetscFunctionReturn(0); 1742 } 1743 1744 /*@C 1745 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1746 1747 Not Collective 1748 1749 Input Parameters: 1750 + mat - the matrix 1751 . v - a logically two-dimensional array of values 1752 . m, idxm - the number of block rows and their global block indices 1753 . n, idxn - the number of block columns and their global block indices 1754 - addv - either ADD_VALUES or INSERT_VALUES, where 1755 ADD_VALUES adds values to any existing entries, and 1756 INSERT_VALUES replaces existing entries with new values 1757 1758 Notes: 1759 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1760 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1761 1762 The m and n count the NUMBER of blocks in the row direction and column direction, 1763 NOT the total number of rows/columns; for example, if the block size is 2 and 1764 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1765 The values in idxm would be 1 2; that is the first index for each block divided by 1766 the block size. 1767 1768 Note that you must call MatSetBlockSize() when constructing this matrix (before 1769 preallocating it). 1770 1771 By default the values, v, are row-oriented, so the layout of 1772 v is the same as for MatSetValues(). See MatSetOption() for other options. 1773 1774 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1775 options cannot be mixed without intervening calls to the assembly 1776 routines. 1777 1778 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1779 as well as in C. 1780 1781 Negative indices may be passed in idxm and idxn, these rows and columns are 1782 simply ignored. This allows easily inserting element stiffness matrices 1783 with homogeneous Dirchlet boundary conditions that you don't want represented 1784 in the matrix. 1785 1786 Each time an entry is set within a sparse matrix via MatSetValues(), 1787 internal searching must be done to determine where to place the 1788 data in the matrix storage space. By instead inserting blocks of 1789 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1790 reduced. 1791 1792 Example: 1793 $ Suppose m=n=2 and block size(bs) = 2 The array is 1794 $ 1795 $ 1 2 | 3 4 1796 $ 5 6 | 7 8 1797 $ - - - | - - - 1798 $ 9 10 | 11 12 1799 $ 13 14 | 15 16 1800 $ 1801 $ v[] should be passed in like 1802 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1803 $ 1804 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1805 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1806 1807 Level: intermediate 1808 1809 Concepts: matrices^putting entries in blocked 1810 1811 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1812 @*/ 1813 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1814 { 1815 PetscErrorCode ierr; 1816 1817 PetscFunctionBeginHot; 1818 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1819 PetscValidType(mat,1); 1820 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1821 PetscValidIntPointer(idxm,3); 1822 PetscValidIntPointer(idxn,5); 1823 PetscValidScalarPointer(v,6); 1824 MatCheckPreallocated(mat,1); 1825 if (mat->insertmode == NOT_SET_VALUES) { 1826 mat->insertmode = addv; 1827 } 1828 #if defined(PETSC_USE_DEBUG) 1829 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1830 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1831 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1832 #endif 1833 1834 if (mat->assembled) { 1835 mat->was_assembled = PETSC_TRUE; 1836 mat->assembled = PETSC_FALSE; 1837 } 1838 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1839 if (mat->ops->setvaluesblocked) { 1840 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1841 } else { 1842 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1843 PetscInt i,j,bs,cbs; 1844 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1845 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1846 iidxm = buf; iidxn = buf + m*bs; 1847 } else { 1848 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1849 iidxm = bufr; iidxn = bufc; 1850 } 1851 for (i=0; i<m; i++) { 1852 for (j=0; j<bs; j++) { 1853 iidxm[i*bs+j] = bs*idxm[i] + j; 1854 } 1855 } 1856 for (i=0; i<n; i++) { 1857 for (j=0; j<cbs; j++) { 1858 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1859 } 1860 } 1861 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1862 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1863 } 1864 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1865 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 1866 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1867 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1868 } 1869 #endif 1870 PetscFunctionReturn(0); 1871 } 1872 1873 /*@ 1874 MatGetValues - Gets a block of values from a matrix. 1875 1876 Not Collective; currently only returns a local block 1877 1878 Input Parameters: 1879 + mat - the matrix 1880 . v - a logically two-dimensional array for storing the values 1881 . m, idxm - the number of rows and their global indices 1882 - n, idxn - the number of columns and their global indices 1883 1884 Notes: 1885 The user must allocate space (m*n PetscScalars) for the values, v. 1886 The values, v, are then returned in a row-oriented format, 1887 analogous to that used by default in MatSetValues(). 1888 1889 MatGetValues() uses 0-based row and column numbers in 1890 Fortran as well as in C. 1891 1892 MatGetValues() requires that the matrix has been assembled 1893 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1894 MatSetValues() and MatGetValues() CANNOT be made in succession 1895 without intermediate matrix assembly. 1896 1897 Negative row or column indices will be ignored and those locations in v[] will be 1898 left unchanged. 1899 1900 Level: advanced 1901 1902 Concepts: matrices^accessing values 1903 1904 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1905 @*/ 1906 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1907 { 1908 PetscErrorCode ierr; 1909 1910 PetscFunctionBegin; 1911 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1912 PetscValidType(mat,1); 1913 if (!m || !n) PetscFunctionReturn(0); 1914 PetscValidIntPointer(idxm,3); 1915 PetscValidIntPointer(idxn,5); 1916 PetscValidScalarPointer(v,6); 1917 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1918 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1919 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1920 MatCheckPreallocated(mat,1); 1921 1922 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1923 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1924 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1925 PetscFunctionReturn(0); 1926 } 1927 1928 /*@ 1929 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1930 the same size. Currently, this can only be called once and creates the given matrix. 1931 1932 Not Collective 1933 1934 Input Parameters: 1935 + mat - the matrix 1936 . nb - the number of blocks 1937 . bs - the number of rows (and columns) in each block 1938 . rows - a concatenation of the rows for each block 1939 - v - a concatenation of logically two-dimensional arrays of values 1940 1941 Notes: 1942 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1943 1944 Level: advanced 1945 1946 Concepts: matrices^putting entries in 1947 1948 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1949 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1950 @*/ 1951 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 1952 { 1953 PetscErrorCode ierr; 1954 1955 PetscFunctionBegin; 1956 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1957 PetscValidType(mat,1); 1958 PetscValidScalarPointer(rows,4); 1959 PetscValidScalarPointer(v,5); 1960 #if defined(PETSC_USE_DEBUG) 1961 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1962 #endif 1963 1964 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1965 if (mat->ops->setvaluesbatch) { 1966 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 1967 } else { 1968 PetscInt b; 1969 for (b = 0; b < nb; ++b) { 1970 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 1971 } 1972 } 1973 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1974 PetscFunctionReturn(0); 1975 } 1976 1977 /*@ 1978 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 1979 the routine MatSetValuesLocal() to allow users to insert matrix entries 1980 using a local (per-processor) numbering. 1981 1982 Not Collective 1983 1984 Input Parameters: 1985 + x - the matrix 1986 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 1987 - cmapping - column mapping 1988 1989 Level: intermediate 1990 1991 Concepts: matrices^local to global mapping 1992 Concepts: local to global mapping^for matrices 1993 1994 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 1995 @*/ 1996 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1997 { 1998 PetscErrorCode ierr; 1999 2000 PetscFunctionBegin; 2001 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2002 PetscValidType(x,1); 2003 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2004 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2005 2006 if (x->ops->setlocaltoglobalmapping) { 2007 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 2008 } else { 2009 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 2010 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 2011 } 2012 PetscFunctionReturn(0); 2013 } 2014 2015 2016 /*@ 2017 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2018 2019 Not Collective 2020 2021 Input Parameters: 2022 . A - the matrix 2023 2024 Output Parameters: 2025 + rmapping - row mapping 2026 - cmapping - column mapping 2027 2028 Level: advanced 2029 2030 Concepts: matrices^local to global mapping 2031 Concepts: local to global mapping^for matrices 2032 2033 .seealso: MatSetValuesLocal() 2034 @*/ 2035 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2036 { 2037 PetscFunctionBegin; 2038 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2039 PetscValidType(A,1); 2040 if (rmapping) PetscValidPointer(rmapping,2); 2041 if (cmapping) PetscValidPointer(cmapping,3); 2042 if (rmapping) *rmapping = A->rmap->mapping; 2043 if (cmapping) *cmapping = A->cmap->mapping; 2044 PetscFunctionReturn(0); 2045 } 2046 2047 /*@ 2048 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2049 2050 Not Collective 2051 2052 Input Parameters: 2053 . A - the matrix 2054 2055 Output Parameters: 2056 + rmap - row layout 2057 - cmap - column layout 2058 2059 Level: advanced 2060 2061 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2062 @*/ 2063 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2064 { 2065 PetscFunctionBegin; 2066 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2067 PetscValidType(A,1); 2068 if (rmap) PetscValidPointer(rmap,2); 2069 if (cmap) PetscValidPointer(cmap,3); 2070 if (rmap) *rmap = A->rmap; 2071 if (cmap) *cmap = A->cmap; 2072 PetscFunctionReturn(0); 2073 } 2074 2075 /*@C 2076 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2077 using a local ordering of the nodes. 2078 2079 Not Collective 2080 2081 Input Parameters: 2082 + mat - the matrix 2083 . nrow, irow - number of rows and their local indices 2084 . ncol, icol - number of columns and their local indices 2085 . y - a logically two-dimensional array of values 2086 - addv - either INSERT_VALUES or ADD_VALUES, where 2087 ADD_VALUES adds values to any existing entries, and 2088 INSERT_VALUES replaces existing entries with new values 2089 2090 Notes: 2091 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2092 MatSetUp() before using this routine 2093 2094 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2095 2096 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2097 options cannot be mixed without intervening calls to the assembly 2098 routines. 2099 2100 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2101 MUST be called after all calls to MatSetValuesLocal() have been completed. 2102 2103 Level: intermediate 2104 2105 Concepts: matrices^putting entries in with local numbering 2106 2107 Developer Notes: 2108 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2109 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2110 2111 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2112 MatSetValueLocal() 2113 @*/ 2114 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2115 { 2116 PetscErrorCode ierr; 2117 2118 PetscFunctionBeginHot; 2119 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2120 PetscValidType(mat,1); 2121 MatCheckPreallocated(mat,1); 2122 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2123 PetscValidIntPointer(irow,3); 2124 PetscValidIntPointer(icol,5); 2125 PetscValidScalarPointer(y,6); 2126 if (mat->insertmode == NOT_SET_VALUES) { 2127 mat->insertmode = addv; 2128 } 2129 #if defined(PETSC_USE_DEBUG) 2130 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2131 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2132 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2133 #endif 2134 2135 if (mat->assembled) { 2136 mat->was_assembled = PETSC_TRUE; 2137 mat->assembled = PETSC_FALSE; 2138 } 2139 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2140 if (mat->ops->setvalueslocal) { 2141 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2142 } else { 2143 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2144 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2145 irowm = buf; icolm = buf+nrow; 2146 } else { 2147 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2148 irowm = bufr; icolm = bufc; 2149 } 2150 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2151 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2152 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2153 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2154 } 2155 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2156 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 2157 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2158 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2159 } 2160 #endif 2161 PetscFunctionReturn(0); 2162 } 2163 2164 /*@C 2165 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2166 using a local ordering of the nodes a block at a time. 2167 2168 Not Collective 2169 2170 Input Parameters: 2171 + x - the matrix 2172 . nrow, irow - number of rows and their local indices 2173 . ncol, icol - number of columns and their local indices 2174 . y - a logically two-dimensional array of values 2175 - addv - either INSERT_VALUES or ADD_VALUES, where 2176 ADD_VALUES adds values to any existing entries, and 2177 INSERT_VALUES replaces existing entries with new values 2178 2179 Notes: 2180 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2181 MatSetUp() before using this routine 2182 2183 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2184 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2185 2186 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2187 options cannot be mixed without intervening calls to the assembly 2188 routines. 2189 2190 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2191 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2192 2193 Level: intermediate 2194 2195 Developer Notes: 2196 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2197 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2198 2199 Concepts: matrices^putting blocked values in with local numbering 2200 2201 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2202 MatSetValuesLocal(), MatSetValuesBlocked() 2203 @*/ 2204 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2205 { 2206 PetscErrorCode ierr; 2207 2208 PetscFunctionBeginHot; 2209 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2210 PetscValidType(mat,1); 2211 MatCheckPreallocated(mat,1); 2212 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2213 PetscValidIntPointer(irow,3); 2214 PetscValidIntPointer(icol,5); 2215 PetscValidScalarPointer(y,6); 2216 if (mat->insertmode == NOT_SET_VALUES) { 2217 mat->insertmode = addv; 2218 } 2219 #if defined(PETSC_USE_DEBUG) 2220 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2221 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2222 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); 2223 #endif 2224 2225 if (mat->assembled) { 2226 mat->was_assembled = PETSC_TRUE; 2227 mat->assembled = PETSC_FALSE; 2228 } 2229 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2230 if (mat->ops->setvaluesblockedlocal) { 2231 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2232 } else { 2233 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2234 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2235 irowm = buf; icolm = buf + nrow; 2236 } else { 2237 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2238 irowm = bufr; icolm = bufc; 2239 } 2240 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2241 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2242 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2243 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2244 } 2245 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2246 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 2247 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2248 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2249 } 2250 #endif 2251 PetscFunctionReturn(0); 2252 } 2253 2254 /*@ 2255 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2256 2257 Collective on Mat and Vec 2258 2259 Input Parameters: 2260 + mat - the matrix 2261 - x - the vector to be multiplied 2262 2263 Output Parameters: 2264 . y - the result 2265 2266 Notes: 2267 The vectors x and y cannot be the same. I.e., one cannot 2268 call MatMult(A,y,y). 2269 2270 Level: developer 2271 2272 Concepts: matrix-vector product 2273 2274 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2275 @*/ 2276 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2277 { 2278 PetscErrorCode ierr; 2279 2280 PetscFunctionBegin; 2281 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2282 PetscValidType(mat,1); 2283 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2284 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2285 2286 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2287 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2288 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2289 MatCheckPreallocated(mat,1); 2290 2291 if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2292 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2293 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2294 PetscFunctionReturn(0); 2295 } 2296 2297 /* --------------------------------------------------------*/ 2298 /*@ 2299 MatMult - Computes the matrix-vector product, y = Ax. 2300 2301 Neighbor-wise Collective on Mat and Vec 2302 2303 Input Parameters: 2304 + mat - the matrix 2305 - x - the vector to be multiplied 2306 2307 Output Parameters: 2308 . y - the result 2309 2310 Notes: 2311 The vectors x and y cannot be the same. I.e., one cannot 2312 call MatMult(A,y,y). 2313 2314 Level: beginner 2315 2316 Concepts: matrix-vector product 2317 2318 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2319 @*/ 2320 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2321 { 2322 PetscErrorCode ierr; 2323 2324 PetscFunctionBegin; 2325 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2326 PetscValidType(mat,1); 2327 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2328 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2329 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2330 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2331 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2332 #if !defined(PETSC_HAVE_CONSTRAINTS) 2333 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); 2334 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); 2335 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); 2336 #endif 2337 VecLocked(y,3); 2338 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2339 MatCheckPreallocated(mat,1); 2340 2341 ierr = VecLockPush(x);CHKERRQ(ierr); 2342 if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2343 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2344 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2345 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2346 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2347 ierr = VecLockPop(x);CHKERRQ(ierr); 2348 PetscFunctionReturn(0); 2349 } 2350 2351 /*@ 2352 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2353 2354 Neighbor-wise Collective on Mat and Vec 2355 2356 Input Parameters: 2357 + mat - the matrix 2358 - x - the vector to be multiplied 2359 2360 Output Parameters: 2361 . y - the result 2362 2363 Notes: 2364 The vectors x and y cannot be the same. I.e., one cannot 2365 call MatMultTranspose(A,y,y). 2366 2367 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2368 use MatMultHermitianTranspose() 2369 2370 Level: beginner 2371 2372 Concepts: matrix vector product^transpose 2373 2374 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2375 @*/ 2376 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2377 { 2378 PetscErrorCode ierr; 2379 2380 PetscFunctionBegin; 2381 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2382 PetscValidType(mat,1); 2383 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2384 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2385 2386 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2387 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2388 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2389 #if !defined(PETSC_HAVE_CONSTRAINTS) 2390 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); 2391 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); 2392 #endif 2393 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2394 MatCheckPreallocated(mat,1); 2395 2396 if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined"); 2397 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2398 ierr = VecLockPush(x);CHKERRQ(ierr); 2399 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2400 ierr = VecLockPop(x);CHKERRQ(ierr); 2401 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2402 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2403 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2404 PetscFunctionReturn(0); 2405 } 2406 2407 /*@ 2408 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2409 2410 Neighbor-wise Collective on Mat and Vec 2411 2412 Input Parameters: 2413 + mat - the matrix 2414 - x - the vector to be multilplied 2415 2416 Output Parameters: 2417 . y - the result 2418 2419 Notes: 2420 The vectors x and y cannot be the same. I.e., one cannot 2421 call MatMultHermitianTranspose(A,y,y). 2422 2423 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2424 2425 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2426 2427 Level: beginner 2428 2429 Concepts: matrix vector product^transpose 2430 2431 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2432 @*/ 2433 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2434 { 2435 PetscErrorCode ierr; 2436 Vec w; 2437 2438 PetscFunctionBegin; 2439 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2440 PetscValidType(mat,1); 2441 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2442 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2443 2444 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2445 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2446 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2447 #if !defined(PETSC_HAVE_CONSTRAINTS) 2448 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); 2449 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); 2450 #endif 2451 MatCheckPreallocated(mat,1); 2452 2453 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2454 if (mat->ops->multhermitiantranspose) { 2455 ierr = VecLockPush(x);CHKERRQ(ierr); 2456 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2457 ierr = VecLockPop(x);CHKERRQ(ierr); 2458 } else { 2459 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2460 ierr = VecCopy(x,w);CHKERRQ(ierr); 2461 ierr = VecConjugate(w);CHKERRQ(ierr); 2462 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2463 ierr = VecDestroy(&w);CHKERRQ(ierr); 2464 ierr = VecConjugate(y);CHKERRQ(ierr); 2465 } 2466 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2467 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2468 PetscFunctionReturn(0); 2469 } 2470 2471 /*@ 2472 MatMultAdd - Computes v3 = v2 + A * v1. 2473 2474 Neighbor-wise Collective on Mat and Vec 2475 2476 Input Parameters: 2477 + mat - the matrix 2478 - v1, v2 - the vectors 2479 2480 Output Parameters: 2481 . v3 - the result 2482 2483 Notes: 2484 The vectors v1 and v3 cannot be the same. I.e., one cannot 2485 call MatMultAdd(A,v1,v2,v1). 2486 2487 Level: beginner 2488 2489 Concepts: matrix vector product^addition 2490 2491 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2492 @*/ 2493 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2494 { 2495 PetscErrorCode ierr; 2496 2497 PetscFunctionBegin; 2498 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2499 PetscValidType(mat,1); 2500 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2501 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2502 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2503 2504 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2505 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2506 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); 2507 /* 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); 2508 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); */ 2509 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); 2510 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); 2511 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2512 MatCheckPreallocated(mat,1); 2513 2514 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2515 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2516 ierr = VecLockPush(v1);CHKERRQ(ierr); 2517 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2518 ierr = VecLockPop(v1);CHKERRQ(ierr); 2519 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2520 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2521 PetscFunctionReturn(0); 2522 } 2523 2524 /*@ 2525 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2526 2527 Neighbor-wise Collective on Mat and Vec 2528 2529 Input Parameters: 2530 + mat - the matrix 2531 - v1, v2 - the vectors 2532 2533 Output Parameters: 2534 . v3 - the result 2535 2536 Notes: 2537 The vectors v1 and v3 cannot be the same. I.e., one cannot 2538 call MatMultTransposeAdd(A,v1,v2,v1). 2539 2540 Level: beginner 2541 2542 Concepts: matrix vector product^transpose and addition 2543 2544 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2545 @*/ 2546 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2547 { 2548 PetscErrorCode ierr; 2549 2550 PetscFunctionBegin; 2551 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2552 PetscValidType(mat,1); 2553 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2554 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2555 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2556 2557 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2558 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2559 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2560 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2561 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); 2562 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); 2563 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); 2564 MatCheckPreallocated(mat,1); 2565 2566 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2567 ierr = VecLockPush(v1);CHKERRQ(ierr); 2568 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2569 ierr = VecLockPop(v1);CHKERRQ(ierr); 2570 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2571 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2572 PetscFunctionReturn(0); 2573 } 2574 2575 /*@ 2576 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2577 2578 Neighbor-wise Collective on Mat and Vec 2579 2580 Input Parameters: 2581 + mat - the matrix 2582 - v1, v2 - the vectors 2583 2584 Output Parameters: 2585 . v3 - the result 2586 2587 Notes: 2588 The vectors v1 and v3 cannot be the same. I.e., one cannot 2589 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2590 2591 Level: beginner 2592 2593 Concepts: matrix vector product^transpose and addition 2594 2595 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2596 @*/ 2597 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2598 { 2599 PetscErrorCode ierr; 2600 2601 PetscFunctionBegin; 2602 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2603 PetscValidType(mat,1); 2604 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2605 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2606 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2607 2608 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2609 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2610 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2611 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); 2612 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); 2613 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); 2614 MatCheckPreallocated(mat,1); 2615 2616 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2617 ierr = VecLockPush(v1);CHKERRQ(ierr); 2618 if (mat->ops->multhermitiantransposeadd) { 2619 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2620 } else { 2621 Vec w,z; 2622 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2623 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2624 ierr = VecConjugate(w);CHKERRQ(ierr); 2625 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2626 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2627 ierr = VecDestroy(&w);CHKERRQ(ierr); 2628 ierr = VecConjugate(z);CHKERRQ(ierr); 2629 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2630 ierr = VecDestroy(&z);CHKERRQ(ierr); 2631 } 2632 ierr = VecLockPop(v1);CHKERRQ(ierr); 2633 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2634 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2635 PetscFunctionReturn(0); 2636 } 2637 2638 /*@ 2639 MatMultConstrained - The inner multiplication routine for a 2640 constrained matrix P^T A P. 2641 2642 Neighbor-wise Collective on Mat and Vec 2643 2644 Input Parameters: 2645 + mat - the matrix 2646 - x - the vector to be multilplied 2647 2648 Output Parameters: 2649 . y - the result 2650 2651 Notes: 2652 The vectors x and y cannot be the same. I.e., one cannot 2653 call MatMult(A,y,y). 2654 2655 Level: beginner 2656 2657 .keywords: matrix, multiply, matrix-vector product, constraint 2658 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2659 @*/ 2660 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2661 { 2662 PetscErrorCode ierr; 2663 2664 PetscFunctionBegin; 2665 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2666 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2667 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2668 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2669 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2670 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2671 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); 2672 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); 2673 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); 2674 2675 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2676 ierr = VecLockPush(x);CHKERRQ(ierr); 2677 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2678 ierr = VecLockPop(x);CHKERRQ(ierr); 2679 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2680 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2681 PetscFunctionReturn(0); 2682 } 2683 2684 /*@ 2685 MatMultTransposeConstrained - The inner multiplication routine for a 2686 constrained matrix P^T A^T P. 2687 2688 Neighbor-wise Collective on Mat and Vec 2689 2690 Input Parameters: 2691 + mat - the matrix 2692 - x - the vector to be multilplied 2693 2694 Output Parameters: 2695 . y - the result 2696 2697 Notes: 2698 The vectors x and y cannot be the same. I.e., one cannot 2699 call MatMult(A,y,y). 2700 2701 Level: beginner 2702 2703 .keywords: matrix, multiply, matrix-vector product, constraint 2704 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2705 @*/ 2706 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2707 { 2708 PetscErrorCode ierr; 2709 2710 PetscFunctionBegin; 2711 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2712 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2713 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2714 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2715 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2716 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2717 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); 2718 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); 2719 2720 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2721 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2722 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2723 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2724 PetscFunctionReturn(0); 2725 } 2726 2727 /*@C 2728 MatGetFactorType - gets the type of factorization it is 2729 2730 Note Collective 2731 as the flag 2732 2733 Input Parameters: 2734 . mat - the matrix 2735 2736 Output Parameters: 2737 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2738 2739 Level: intermediate 2740 2741 .seealso: MatFactorType, MatGetFactor() 2742 @*/ 2743 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2744 { 2745 PetscFunctionBegin; 2746 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2747 PetscValidType(mat,1); 2748 *t = mat->factortype; 2749 PetscFunctionReturn(0); 2750 } 2751 2752 /* ------------------------------------------------------------*/ 2753 /*@C 2754 MatGetInfo - Returns information about matrix storage (number of 2755 nonzeros, memory, etc.). 2756 2757 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2758 2759 Input Parameters: 2760 . mat - the matrix 2761 2762 Output Parameters: 2763 + flag - flag indicating the type of parameters to be returned 2764 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2765 MAT_GLOBAL_SUM - sum over all processors) 2766 - info - matrix information context 2767 2768 Notes: 2769 The MatInfo context contains a variety of matrix data, including 2770 number of nonzeros allocated and used, number of mallocs during 2771 matrix assembly, etc. Additional information for factored matrices 2772 is provided (such as the fill ratio, number of mallocs during 2773 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2774 when using the runtime options 2775 $ -info -mat_view ::ascii_info 2776 2777 Example for C/C++ Users: 2778 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2779 data within the MatInfo context. For example, 2780 .vb 2781 MatInfo info; 2782 Mat A; 2783 double mal, nz_a, nz_u; 2784 2785 MatGetInfo(A,MAT_LOCAL,&info); 2786 mal = info.mallocs; 2787 nz_a = info.nz_allocated; 2788 .ve 2789 2790 Example for Fortran Users: 2791 Fortran users should declare info as a double precision 2792 array of dimension MAT_INFO_SIZE, and then extract the parameters 2793 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2794 a complete list of parameter names. 2795 .vb 2796 double precision info(MAT_INFO_SIZE) 2797 double precision mal, nz_a 2798 Mat A 2799 integer ierr 2800 2801 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2802 mal = info(MAT_INFO_MALLOCS) 2803 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2804 .ve 2805 2806 Level: intermediate 2807 2808 Concepts: matrices^getting information on 2809 2810 Developer Note: fortran interface is not autogenerated as the f90 2811 interface defintion cannot be generated correctly [due to MatInfo] 2812 2813 .seealso: MatStashGetInfo() 2814 2815 @*/ 2816 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2817 { 2818 PetscErrorCode ierr; 2819 2820 PetscFunctionBegin; 2821 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2822 PetscValidType(mat,1); 2823 PetscValidPointer(info,3); 2824 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2825 MatCheckPreallocated(mat,1); 2826 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2827 PetscFunctionReturn(0); 2828 } 2829 2830 /* 2831 This is used by external packages where it is not easy to get the info from the actual 2832 matrix factorization. 2833 */ 2834 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2835 { 2836 PetscErrorCode ierr; 2837 2838 PetscFunctionBegin; 2839 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2840 PetscFunctionReturn(0); 2841 } 2842 2843 /* ----------------------------------------------------------*/ 2844 2845 /*@C 2846 MatLUFactor - Performs in-place LU factorization of matrix. 2847 2848 Collective on Mat 2849 2850 Input Parameters: 2851 + mat - the matrix 2852 . row - row permutation 2853 . col - column permutation 2854 - info - options for factorization, includes 2855 $ fill - expected fill as ratio of original fill. 2856 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2857 $ Run with the option -info to determine an optimal value to use 2858 2859 Notes: 2860 Most users should employ the simplified KSP interface for linear solvers 2861 instead of working directly with matrix algebra routines such as this. 2862 See, e.g., KSPCreate(). 2863 2864 This changes the state of the matrix to a factored matrix; it cannot be used 2865 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2866 2867 Level: developer 2868 2869 Concepts: matrices^LU factorization 2870 2871 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2872 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2873 2874 Developer Note: fortran interface is not autogenerated as the f90 2875 interface defintion cannot be generated correctly [due to MatFactorInfo] 2876 2877 @*/ 2878 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2879 { 2880 PetscErrorCode ierr; 2881 MatFactorInfo tinfo; 2882 2883 PetscFunctionBegin; 2884 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2885 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2886 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2887 if (info) PetscValidPointer(info,4); 2888 PetscValidType(mat,1); 2889 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2890 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2891 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2892 MatCheckPreallocated(mat,1); 2893 if (!info) { 2894 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2895 info = &tinfo; 2896 } 2897 2898 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2899 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2900 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2901 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2902 PetscFunctionReturn(0); 2903 } 2904 2905 /*@C 2906 MatILUFactor - Performs in-place ILU factorization of matrix. 2907 2908 Collective on Mat 2909 2910 Input Parameters: 2911 + mat - the matrix 2912 . row - row permutation 2913 . col - column permutation 2914 - info - structure containing 2915 $ levels - number of levels of fill. 2916 $ expected fill - as ratio of original fill. 2917 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2918 missing diagonal entries) 2919 2920 Notes: 2921 Probably really in-place only when level of fill is zero, otherwise allocates 2922 new space to store factored matrix and deletes previous memory. 2923 2924 Most users should employ the simplified KSP interface for linear solvers 2925 instead of working directly with matrix algebra routines such as this. 2926 See, e.g., KSPCreate(). 2927 2928 Level: developer 2929 2930 Concepts: matrices^ILU factorization 2931 2932 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 2933 2934 Developer Note: fortran interface is not autogenerated as the f90 2935 interface defintion cannot be generated correctly [due to MatFactorInfo] 2936 2937 @*/ 2938 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2939 { 2940 PetscErrorCode ierr; 2941 2942 PetscFunctionBegin; 2943 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2944 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2945 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2946 PetscValidPointer(info,4); 2947 PetscValidType(mat,1); 2948 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 2949 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2950 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2951 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2952 MatCheckPreallocated(mat,1); 2953 2954 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2955 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 2956 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2957 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2958 PetscFunctionReturn(0); 2959 } 2960 2961 /*@C 2962 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 2963 Call this routine before calling MatLUFactorNumeric(). 2964 2965 Collective on Mat 2966 2967 Input Parameters: 2968 + fact - the factor matrix obtained with MatGetFactor() 2969 . mat - the matrix 2970 . row, col - row and column permutations 2971 - info - options for factorization, includes 2972 $ fill - expected fill as ratio of original fill. 2973 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2974 $ Run with the option -info to determine an optimal value to use 2975 2976 2977 Notes: 2978 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 2979 2980 Most users should employ the simplified KSP interface for linear solvers 2981 instead of working directly with matrix algebra routines such as this. 2982 See, e.g., KSPCreate(). 2983 2984 Level: developer 2985 2986 Concepts: matrices^LU symbolic factorization 2987 2988 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 2989 2990 Developer Note: fortran interface is not autogenerated as the f90 2991 interface defintion cannot be generated correctly [due to MatFactorInfo] 2992 2993 @*/ 2994 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 2995 { 2996 PetscErrorCode ierr; 2997 2998 PetscFunctionBegin; 2999 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3000 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3001 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3002 if (info) PetscValidPointer(info,4); 3003 PetscValidType(mat,1); 3004 PetscValidPointer(fact,5); 3005 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3006 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3007 if (!(fact)->ops->lufactorsymbolic) { 3008 MatSolverType spackage; 3009 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3010 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 3011 } 3012 MatCheckPreallocated(mat,2); 3013 3014 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3015 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3016 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3017 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3018 PetscFunctionReturn(0); 3019 } 3020 3021 /*@C 3022 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3023 Call this routine after first calling MatLUFactorSymbolic(). 3024 3025 Collective on Mat 3026 3027 Input Parameters: 3028 + fact - the factor matrix obtained with MatGetFactor() 3029 . mat - the matrix 3030 - info - options for factorization 3031 3032 Notes: 3033 See MatLUFactor() for in-place factorization. See 3034 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3035 3036 Most users should employ the simplified KSP interface for linear solvers 3037 instead of working directly with matrix algebra routines such as this. 3038 See, e.g., KSPCreate(). 3039 3040 Level: developer 3041 3042 Concepts: matrices^LU numeric factorization 3043 3044 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3045 3046 Developer Note: fortran interface is not autogenerated as the f90 3047 interface defintion cannot be generated correctly [due to MatFactorInfo] 3048 3049 @*/ 3050 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3051 { 3052 PetscErrorCode ierr; 3053 3054 PetscFunctionBegin; 3055 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3056 PetscValidType(mat,1); 3057 PetscValidPointer(fact,2); 3058 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3059 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3060 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); 3061 3062 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3063 MatCheckPreallocated(mat,2); 3064 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3065 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3066 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3067 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3068 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3069 PetscFunctionReturn(0); 3070 } 3071 3072 /*@C 3073 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3074 symmetric matrix. 3075 3076 Collective on Mat 3077 3078 Input Parameters: 3079 + mat - the matrix 3080 . perm - row and column permutations 3081 - f - expected fill as ratio of original fill 3082 3083 Notes: 3084 See MatLUFactor() for the nonsymmetric case. See also 3085 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3086 3087 Most users should employ the simplified KSP interface for linear solvers 3088 instead of working directly with matrix algebra routines such as this. 3089 See, e.g., KSPCreate(). 3090 3091 Level: developer 3092 3093 Concepts: matrices^Cholesky factorization 3094 3095 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3096 MatGetOrdering() 3097 3098 Developer Note: fortran interface is not autogenerated as the f90 3099 interface defintion cannot be generated correctly [due to MatFactorInfo] 3100 3101 @*/ 3102 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3103 { 3104 PetscErrorCode ierr; 3105 3106 PetscFunctionBegin; 3107 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3108 PetscValidType(mat,1); 3109 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3110 if (info) PetscValidPointer(info,3); 3111 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3112 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3113 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3114 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); 3115 MatCheckPreallocated(mat,1); 3116 3117 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3118 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3119 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3120 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3121 PetscFunctionReturn(0); 3122 } 3123 3124 /*@C 3125 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3126 of a symmetric matrix. 3127 3128 Collective on Mat 3129 3130 Input Parameters: 3131 + fact - the factor matrix obtained with MatGetFactor() 3132 . mat - the matrix 3133 . perm - row and column permutations 3134 - info - options for factorization, includes 3135 $ fill - expected fill as ratio of original fill. 3136 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3137 $ Run with the option -info to determine an optimal value to use 3138 3139 Notes: 3140 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3141 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3142 3143 Most users should employ the simplified KSP interface for linear solvers 3144 instead of working directly with matrix algebra routines such as this. 3145 See, e.g., KSPCreate(). 3146 3147 Level: developer 3148 3149 Concepts: matrices^Cholesky symbolic factorization 3150 3151 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3152 MatGetOrdering() 3153 3154 Developer Note: fortran interface is not autogenerated as the f90 3155 interface defintion cannot be generated correctly [due to MatFactorInfo] 3156 3157 @*/ 3158 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3159 { 3160 PetscErrorCode ierr; 3161 3162 PetscFunctionBegin; 3163 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3164 PetscValidType(mat,1); 3165 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3166 if (info) PetscValidPointer(info,3); 3167 PetscValidPointer(fact,4); 3168 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3169 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3170 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3171 if (!(fact)->ops->choleskyfactorsymbolic) { 3172 MatSolverType spackage; 3173 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3174 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3175 } 3176 MatCheckPreallocated(mat,2); 3177 3178 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3179 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3180 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3181 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3182 PetscFunctionReturn(0); 3183 } 3184 3185 /*@C 3186 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3187 of a symmetric matrix. Call this routine after first calling 3188 MatCholeskyFactorSymbolic(). 3189 3190 Collective on Mat 3191 3192 Input Parameters: 3193 + fact - the factor matrix obtained with MatGetFactor() 3194 . mat - the initial matrix 3195 . info - options for factorization 3196 - fact - the symbolic factor of mat 3197 3198 3199 Notes: 3200 Most users should employ the simplified KSP interface for linear solvers 3201 instead of working directly with matrix algebra routines such as this. 3202 See, e.g., KSPCreate(). 3203 3204 Level: developer 3205 3206 Concepts: matrices^Cholesky numeric factorization 3207 3208 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3209 3210 Developer Note: fortran interface is not autogenerated as the f90 3211 interface defintion cannot be generated correctly [due to MatFactorInfo] 3212 3213 @*/ 3214 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3215 { 3216 PetscErrorCode ierr; 3217 3218 PetscFunctionBegin; 3219 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3220 PetscValidType(mat,1); 3221 PetscValidPointer(fact,2); 3222 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3223 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3224 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3225 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); 3226 MatCheckPreallocated(mat,2); 3227 3228 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3229 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3230 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3231 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3232 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3233 PetscFunctionReturn(0); 3234 } 3235 3236 /* ----------------------------------------------------------------*/ 3237 /*@ 3238 MatSolve - Solves A x = b, given a factored matrix. 3239 3240 Neighbor-wise Collective on Mat and Vec 3241 3242 Input Parameters: 3243 + mat - the factored matrix 3244 - b - the right-hand-side vector 3245 3246 Output Parameter: 3247 . x - the result vector 3248 3249 Notes: 3250 The vectors b and x cannot be the same. I.e., one cannot 3251 call MatSolve(A,x,x). 3252 3253 Notes: 3254 Most users should employ the simplified KSP interface for linear solvers 3255 instead of working directly with matrix algebra routines such as this. 3256 See, e.g., KSPCreate(). 3257 3258 Level: developer 3259 3260 Concepts: matrices^triangular solves 3261 3262 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3263 @*/ 3264 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3265 { 3266 PetscErrorCode ierr; 3267 3268 PetscFunctionBegin; 3269 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3270 PetscValidType(mat,1); 3271 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3272 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3273 PetscCheckSameComm(mat,1,b,2); 3274 PetscCheckSameComm(mat,1,x,3); 3275 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3276 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); 3277 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); 3278 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); 3279 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3280 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3281 MatCheckPreallocated(mat,1); 3282 3283 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3284 if (mat->factorerrortype) { 3285 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3286 ierr = VecSetInf(x);CHKERRQ(ierr); 3287 } else { 3288 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3289 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3290 } 3291 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3292 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3293 PetscFunctionReturn(0); 3294 } 3295 3296 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans) 3297 { 3298 PetscErrorCode ierr; 3299 Vec b,x; 3300 PetscInt m,N,i; 3301 PetscScalar *bb,*xx; 3302 PetscBool flg; 3303 3304 PetscFunctionBegin; 3305 ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3306 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 3307 ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3308 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); 3309 3310 ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr); 3311 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3312 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3313 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3314 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3315 for (i=0; i<N; i++) { 3316 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3317 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3318 if (trans) { 3319 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3320 } else { 3321 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3322 } 3323 ierr = VecResetArray(x);CHKERRQ(ierr); 3324 ierr = VecResetArray(b);CHKERRQ(ierr); 3325 } 3326 ierr = VecDestroy(&b);CHKERRQ(ierr); 3327 ierr = VecDestroy(&x);CHKERRQ(ierr); 3328 ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr); 3329 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3330 PetscFunctionReturn(0); 3331 } 3332 3333 /*@ 3334 MatMatSolve - Solves A X = B, given a factored matrix. 3335 3336 Neighbor-wise Collective on Mat 3337 3338 Input Parameters: 3339 + A - the factored matrix 3340 - B - the right-hand-side matrix (dense matrix) 3341 3342 Output Parameter: 3343 . X - the result matrix (dense matrix) 3344 3345 Notes: 3346 The matrices b and x cannot be the same. I.e., one cannot 3347 call MatMatSolve(A,x,x). 3348 3349 Notes: 3350 Most users should usually employ the simplified KSP interface for linear solvers 3351 instead of working directly with matrix algebra routines such as this. 3352 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3353 at a time. 3354 3355 When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 3356 it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides. 3357 3358 Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B. 3359 3360 Level: developer 3361 3362 Concepts: matrices^triangular solves 3363 3364 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3365 @*/ 3366 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3367 { 3368 PetscErrorCode ierr; 3369 3370 PetscFunctionBegin; 3371 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3372 PetscValidType(A,1); 3373 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3374 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3375 PetscCheckSameComm(A,1,B,2); 3376 PetscCheckSameComm(A,1,X,3); 3377 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3378 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); 3379 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); 3380 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"); 3381 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3382 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3383 MatCheckPreallocated(A,1); 3384 3385 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3386 if (!A->ops->matsolve) { 3387 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3388 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3389 } else { 3390 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3391 } 3392 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3393 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3394 PetscFunctionReturn(0); 3395 } 3396 3397 /*@ 3398 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3399 3400 Neighbor-wise Collective on Mat 3401 3402 Input Parameters: 3403 + A - the factored matrix 3404 - B - the right-hand-side matrix (dense matrix) 3405 3406 Output Parameter: 3407 . X - the result matrix (dense matrix) 3408 3409 Notes: 3410 The matrices B and X cannot be the same. I.e., one cannot 3411 call MatMatSolveTranspose(A,X,X). 3412 3413 Notes: 3414 Most users should usually employ the simplified KSP interface for linear solvers 3415 instead of working directly with matrix algebra routines such as this. 3416 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3417 at a time. 3418 3419 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3420 3421 Level: developer 3422 3423 Concepts: matrices^triangular solves 3424 3425 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3426 @*/ 3427 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3428 { 3429 PetscErrorCode ierr; 3430 3431 PetscFunctionBegin; 3432 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3433 PetscValidType(A,1); 3434 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3435 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3436 PetscCheckSameComm(A,1,B,2); 3437 PetscCheckSameComm(A,1,X,3); 3438 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3439 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); 3440 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); 3441 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); 3442 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"); 3443 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3444 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3445 MatCheckPreallocated(A,1); 3446 3447 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3448 if (!A->ops->matsolvetranspose) { 3449 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3450 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3451 } else { 3452 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3453 } 3454 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3455 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3456 PetscFunctionReturn(0); 3457 } 3458 3459 /*@ 3460 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3461 3462 Neighbor-wise Collective on Mat 3463 3464 Input Parameters: 3465 + A - the factored matrix 3466 - Bt - the transpose of right-hand-side matrix 3467 3468 Output Parameter: 3469 . X - the result matrix (dense matrix) 3470 3471 Notes: 3472 Most users should usually employ the simplified KSP interface for linear solvers 3473 instead of working directly with matrix algebra routines such as this. 3474 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3475 at a time. 3476 3477 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(). 3478 3479 Level: developer 3480 3481 Concepts: matrices^triangular solves 3482 3483 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3484 @*/ 3485 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3486 { 3487 PetscErrorCode ierr; 3488 3489 PetscFunctionBegin; 3490 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3491 PetscValidType(A,1); 3492 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3493 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3494 PetscCheckSameComm(A,1,Bt,2); 3495 PetscCheckSameComm(A,1,X,3); 3496 3497 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3498 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); 3499 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); 3500 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"); 3501 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3502 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3503 MatCheckPreallocated(A,1); 3504 3505 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3506 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3507 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3508 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3509 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3510 PetscFunctionReturn(0); 3511 } 3512 3513 /*@ 3514 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3515 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3516 3517 Neighbor-wise Collective on Mat and Vec 3518 3519 Input Parameters: 3520 + mat - the factored matrix 3521 - b - the right-hand-side vector 3522 3523 Output Parameter: 3524 . x - the result vector 3525 3526 Notes: 3527 MatSolve() should be used for most applications, as it performs 3528 a forward solve followed by a backward solve. 3529 3530 The vectors b and x cannot be the same, i.e., one cannot 3531 call MatForwardSolve(A,x,x). 3532 3533 For matrix in seqsbaij format with block size larger than 1, 3534 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3535 MatForwardSolve() solves U^T*D y = b, and 3536 MatBackwardSolve() solves U x = y. 3537 Thus they do not provide a symmetric preconditioner. 3538 3539 Most users should employ the simplified KSP interface for linear solvers 3540 instead of working directly with matrix algebra routines such as this. 3541 See, e.g., KSPCreate(). 3542 3543 Level: developer 3544 3545 Concepts: matrices^forward solves 3546 3547 .seealso: MatSolve(), MatBackwardSolve() 3548 @*/ 3549 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3550 { 3551 PetscErrorCode ierr; 3552 3553 PetscFunctionBegin; 3554 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3555 PetscValidType(mat,1); 3556 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3557 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3558 PetscCheckSameComm(mat,1,b,2); 3559 PetscCheckSameComm(mat,1,x,3); 3560 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3561 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); 3562 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); 3563 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); 3564 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3565 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3566 MatCheckPreallocated(mat,1); 3567 3568 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3569 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3570 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3571 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3572 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3573 PetscFunctionReturn(0); 3574 } 3575 3576 /*@ 3577 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3578 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3579 3580 Neighbor-wise Collective on Mat and Vec 3581 3582 Input Parameters: 3583 + mat - the factored matrix 3584 - b - the right-hand-side vector 3585 3586 Output Parameter: 3587 . x - the result vector 3588 3589 Notes: 3590 MatSolve() should be used for most applications, as it performs 3591 a forward solve followed by a backward solve. 3592 3593 The vectors b and x cannot be the same. I.e., one cannot 3594 call MatBackwardSolve(A,x,x). 3595 3596 For matrix in seqsbaij format with block size larger than 1, 3597 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3598 MatForwardSolve() solves U^T*D y = b, and 3599 MatBackwardSolve() solves U x = y. 3600 Thus they do not provide a symmetric preconditioner. 3601 3602 Most users should employ the simplified KSP interface for linear solvers 3603 instead of working directly with matrix algebra routines such as this. 3604 See, e.g., KSPCreate(). 3605 3606 Level: developer 3607 3608 Concepts: matrices^backward solves 3609 3610 .seealso: MatSolve(), MatForwardSolve() 3611 @*/ 3612 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3613 { 3614 PetscErrorCode ierr; 3615 3616 PetscFunctionBegin; 3617 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3618 PetscValidType(mat,1); 3619 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3620 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3621 PetscCheckSameComm(mat,1,b,2); 3622 PetscCheckSameComm(mat,1,x,3); 3623 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3624 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); 3625 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); 3626 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); 3627 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3628 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3629 MatCheckPreallocated(mat,1); 3630 3631 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3632 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3633 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3634 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3635 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3636 PetscFunctionReturn(0); 3637 } 3638 3639 /*@ 3640 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3641 3642 Neighbor-wise Collective on Mat and Vec 3643 3644 Input Parameters: 3645 + mat - the factored matrix 3646 . b - the right-hand-side vector 3647 - y - the vector to be added to 3648 3649 Output Parameter: 3650 . x - the result vector 3651 3652 Notes: 3653 The vectors b and x cannot be the same. I.e., one cannot 3654 call MatSolveAdd(A,x,y,x). 3655 3656 Most users should employ the simplified KSP interface for linear solvers 3657 instead of working directly with matrix algebra routines such as this. 3658 See, e.g., KSPCreate(). 3659 3660 Level: developer 3661 3662 Concepts: matrices^triangular solves 3663 3664 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3665 @*/ 3666 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3667 { 3668 PetscScalar one = 1.0; 3669 Vec tmp; 3670 PetscErrorCode ierr; 3671 3672 PetscFunctionBegin; 3673 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3674 PetscValidType(mat,1); 3675 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3676 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3677 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3678 PetscCheckSameComm(mat,1,b,2); 3679 PetscCheckSameComm(mat,1,y,2); 3680 PetscCheckSameComm(mat,1,x,3); 3681 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3682 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); 3683 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); 3684 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); 3685 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); 3686 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); 3687 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3688 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3689 MatCheckPreallocated(mat,1); 3690 3691 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3692 if (mat->ops->solveadd) { 3693 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3694 } else { 3695 /* do the solve then the add manually */ 3696 if (x != y) { 3697 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3698 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3699 } else { 3700 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3701 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3702 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3703 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3704 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3705 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3706 } 3707 } 3708 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3709 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3710 PetscFunctionReturn(0); 3711 } 3712 3713 /*@ 3714 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3715 3716 Neighbor-wise Collective on Mat and Vec 3717 3718 Input Parameters: 3719 + mat - the factored matrix 3720 - b - the right-hand-side vector 3721 3722 Output Parameter: 3723 . x - the result vector 3724 3725 Notes: 3726 The vectors b and x cannot be the same. I.e., one cannot 3727 call MatSolveTranspose(A,x,x). 3728 3729 Most users should employ the simplified KSP interface for linear solvers 3730 instead of working directly with matrix algebra routines such as this. 3731 See, e.g., KSPCreate(). 3732 3733 Level: developer 3734 3735 Concepts: matrices^triangular solves 3736 3737 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3738 @*/ 3739 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3740 { 3741 PetscErrorCode ierr; 3742 3743 PetscFunctionBegin; 3744 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3745 PetscValidType(mat,1); 3746 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3747 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3748 PetscCheckSameComm(mat,1,b,2); 3749 PetscCheckSameComm(mat,1,x,3); 3750 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3751 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); 3752 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); 3753 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3754 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3755 MatCheckPreallocated(mat,1); 3756 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3757 if (mat->factorerrortype) { 3758 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3759 ierr = VecSetInf(x);CHKERRQ(ierr); 3760 } else { 3761 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3762 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3763 } 3764 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3765 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3766 PetscFunctionReturn(0); 3767 } 3768 3769 /*@ 3770 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3771 factored matrix. 3772 3773 Neighbor-wise Collective on Mat and Vec 3774 3775 Input Parameters: 3776 + mat - the factored matrix 3777 . b - the right-hand-side vector 3778 - y - the vector to be added to 3779 3780 Output Parameter: 3781 . x - the result vector 3782 3783 Notes: 3784 The vectors b and x cannot be the same. I.e., one cannot 3785 call MatSolveTransposeAdd(A,x,y,x). 3786 3787 Most users should employ the simplified KSP interface for linear solvers 3788 instead of working directly with matrix algebra routines such as this. 3789 See, e.g., KSPCreate(). 3790 3791 Level: developer 3792 3793 Concepts: matrices^triangular solves 3794 3795 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3796 @*/ 3797 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3798 { 3799 PetscScalar one = 1.0; 3800 PetscErrorCode ierr; 3801 Vec tmp; 3802 3803 PetscFunctionBegin; 3804 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3805 PetscValidType(mat,1); 3806 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3807 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3808 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3809 PetscCheckSameComm(mat,1,b,2); 3810 PetscCheckSameComm(mat,1,y,3); 3811 PetscCheckSameComm(mat,1,x,4); 3812 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3813 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); 3814 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); 3815 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); 3816 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); 3817 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3818 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3819 MatCheckPreallocated(mat,1); 3820 3821 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3822 if (mat->ops->solvetransposeadd) { 3823 if (mat->factorerrortype) { 3824 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3825 ierr = VecSetInf(x);CHKERRQ(ierr); 3826 } else { 3827 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3828 } 3829 } else { 3830 /* do the solve then the add manually */ 3831 if (x != y) { 3832 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3833 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3834 } else { 3835 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3836 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3837 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3838 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3839 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3840 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3841 } 3842 } 3843 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3844 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3845 PetscFunctionReturn(0); 3846 } 3847 /* ----------------------------------------------------------------*/ 3848 3849 /*@ 3850 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3851 3852 Neighbor-wise Collective on Mat and Vec 3853 3854 Input Parameters: 3855 + mat - the matrix 3856 . b - the right hand side 3857 . omega - the relaxation factor 3858 . flag - flag indicating the type of SOR (see below) 3859 . shift - diagonal shift 3860 . its - the number of iterations 3861 - lits - the number of local iterations 3862 3863 Output Parameters: 3864 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3865 3866 SOR Flags: 3867 . SOR_FORWARD_SWEEP - forward SOR 3868 . SOR_BACKWARD_SWEEP - backward SOR 3869 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3870 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3871 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3872 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3873 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3874 upper/lower triangular part of matrix to 3875 vector (with omega) 3876 . SOR_ZERO_INITIAL_GUESS - zero initial guess 3877 3878 Notes: 3879 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3880 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3881 on each processor. 3882 3883 Application programmers will not generally use MatSOR() directly, 3884 but instead will employ the KSP/PC interface. 3885 3886 Notes: 3887 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3888 3889 Notes for Advanced Users: 3890 The flags are implemented as bitwise inclusive or operations. 3891 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3892 to specify a zero initial guess for SSOR. 3893 3894 Most users should employ the simplified KSP interface for linear solvers 3895 instead of working directly with matrix algebra routines such as this. 3896 See, e.g., KSPCreate(). 3897 3898 Vectors x and b CANNOT be the same 3899 3900 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3901 3902 Level: developer 3903 3904 Concepts: matrices^relaxation 3905 Concepts: matrices^SOR 3906 Concepts: matrices^Gauss-Seidel 3907 3908 @*/ 3909 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3910 { 3911 PetscErrorCode ierr; 3912 3913 PetscFunctionBegin; 3914 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3915 PetscValidType(mat,1); 3916 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3917 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3918 PetscCheckSameComm(mat,1,b,2); 3919 PetscCheckSameComm(mat,1,x,8); 3920 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3921 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3922 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3923 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); 3924 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); 3925 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); 3926 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 3927 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 3928 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 3929 3930 MatCheckPreallocated(mat,1); 3931 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3932 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 3933 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3934 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3935 PetscFunctionReturn(0); 3936 } 3937 3938 /* 3939 Default matrix copy routine. 3940 */ 3941 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 3942 { 3943 PetscErrorCode ierr; 3944 PetscInt i,rstart = 0,rend = 0,nz; 3945 const PetscInt *cwork; 3946 const PetscScalar *vwork; 3947 3948 PetscFunctionBegin; 3949 if (B->assembled) { 3950 ierr = MatZeroEntries(B);CHKERRQ(ierr); 3951 } 3952 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 3953 for (i=rstart; i<rend; i++) { 3954 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3955 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 3956 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3957 } 3958 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3959 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3960 PetscFunctionReturn(0); 3961 } 3962 3963 /*@ 3964 MatCopy - Copys a matrix to another matrix. 3965 3966 Collective on Mat 3967 3968 Input Parameters: 3969 + A - the matrix 3970 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 3971 3972 Output Parameter: 3973 . B - where the copy is put 3974 3975 Notes: 3976 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 3977 same nonzero pattern or the routine will crash. 3978 3979 MatCopy() copies the matrix entries of a matrix to another existing 3980 matrix (after first zeroing the second matrix). A related routine is 3981 MatConvert(), which first creates a new matrix and then copies the data. 3982 3983 Level: intermediate 3984 3985 Concepts: matrices^copying 3986 3987 .seealso: MatConvert(), MatDuplicate() 3988 3989 @*/ 3990 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 3991 { 3992 PetscErrorCode ierr; 3993 PetscInt i; 3994 3995 PetscFunctionBegin; 3996 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3997 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3998 PetscValidType(A,1); 3999 PetscValidType(B,2); 4000 PetscCheckSameComm(A,1,B,2); 4001 MatCheckPreallocated(B,2); 4002 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4003 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4004 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); 4005 MatCheckPreallocated(A,1); 4006 if (A == B) PetscFunctionReturn(0); 4007 4008 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4009 if (A->ops->copy) { 4010 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 4011 } else { /* generic conversion */ 4012 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 4013 } 4014 4015 B->stencil.dim = A->stencil.dim; 4016 B->stencil.noc = A->stencil.noc; 4017 for (i=0; i<=A->stencil.dim; i++) { 4018 B->stencil.dims[i] = A->stencil.dims[i]; 4019 B->stencil.starts[i] = A->stencil.starts[i]; 4020 } 4021 4022 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4023 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4024 PetscFunctionReturn(0); 4025 } 4026 4027 /*@C 4028 MatConvert - Converts a matrix to another matrix, either of the same 4029 or different type. 4030 4031 Collective on Mat 4032 4033 Input Parameters: 4034 + mat - the matrix 4035 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4036 same type as the original matrix. 4037 - reuse - denotes if the destination matrix is to be created or reused. 4038 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 4039 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). 4040 4041 Output Parameter: 4042 . M - pointer to place new matrix 4043 4044 Notes: 4045 MatConvert() first creates a new matrix and then copies the data from 4046 the first matrix. A related routine is MatCopy(), which copies the matrix 4047 entries of one matrix to another already existing matrix context. 4048 4049 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4050 the MPI communicator of the generated matrix is always the same as the communicator 4051 of the input matrix. 4052 4053 Level: intermediate 4054 4055 Concepts: matrices^converting between storage formats 4056 4057 .seealso: MatCopy(), MatDuplicate() 4058 @*/ 4059 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4060 { 4061 PetscErrorCode ierr; 4062 PetscBool sametype,issame,flg; 4063 char convname[256],mtype[256]; 4064 Mat B; 4065 4066 PetscFunctionBegin; 4067 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4068 PetscValidType(mat,1); 4069 PetscValidPointer(M,3); 4070 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4071 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4072 MatCheckPreallocated(mat,1); 4073 4074 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4075 if (flg) { 4076 newtype = mtype; 4077 } 4078 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4079 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4080 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4081 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"); 4082 4083 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0); 4084 4085 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4086 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4087 } else { 4088 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4089 const char *prefix[3] = {"seq","mpi",""}; 4090 PetscInt i; 4091 /* 4092 Order of precedence: 4093 1) See if a specialized converter is known to the current matrix. 4094 2) See if a specialized converter is known to the desired matrix class. 4095 3) See if a good general converter is registered for the desired class 4096 (as of 6/27/03 only MATMPIADJ falls into this category). 4097 4) See if a good general converter is known for the current matrix. 4098 5) Use a really basic converter. 4099 */ 4100 4101 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4102 for (i=0; i<3; i++) { 4103 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4104 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4105 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4106 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4107 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4108 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4109 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4110 if (conv) goto foundconv; 4111 } 4112 4113 /* 2) See if a specialized converter is known to the desired matrix class. */ 4114 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4115 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4116 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4117 for (i=0; i<3; i++) { 4118 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4119 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4120 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4121 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4122 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4123 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4124 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4125 if (conv) { 4126 ierr = MatDestroy(&B);CHKERRQ(ierr); 4127 goto foundconv; 4128 } 4129 } 4130 4131 /* 3) See if a good general converter is registered for the desired class */ 4132 conv = B->ops->convertfrom; 4133 ierr = MatDestroy(&B);CHKERRQ(ierr); 4134 if (conv) goto foundconv; 4135 4136 /* 4) See if a good general converter is known for the current matrix */ 4137 if (mat->ops->convert) { 4138 conv = mat->ops->convert; 4139 } 4140 if (conv) goto foundconv; 4141 4142 /* 5) Use a really basic converter. */ 4143 conv = MatConvert_Basic; 4144 4145 foundconv: 4146 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4147 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4148 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4149 /* the block sizes must be same if the mappings are copied over */ 4150 (*M)->rmap->bs = mat->rmap->bs; 4151 (*M)->cmap->bs = mat->cmap->bs; 4152 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4153 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4154 (*M)->rmap->mapping = mat->rmap->mapping; 4155 (*M)->cmap->mapping = mat->cmap->mapping; 4156 } 4157 (*M)->stencil.dim = mat->stencil.dim; 4158 (*M)->stencil.noc = mat->stencil.noc; 4159 for (i=0; i<=mat->stencil.dim; i++) { 4160 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4161 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4162 } 4163 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4164 } 4165 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4166 4167 /* Copy Mat options */ 4168 if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);} 4169 if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);} 4170 PetscFunctionReturn(0); 4171 } 4172 4173 /*@C 4174 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4175 4176 Not Collective 4177 4178 Input Parameter: 4179 . mat - the matrix, must be a factored matrix 4180 4181 Output Parameter: 4182 . type - the string name of the package (do not free this string) 4183 4184 Notes: 4185 In Fortran you pass in a empty string and the package name will be copied into it. 4186 (Make sure the string is long enough) 4187 4188 Level: intermediate 4189 4190 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4191 @*/ 4192 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4193 { 4194 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4195 4196 PetscFunctionBegin; 4197 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4198 PetscValidType(mat,1); 4199 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4200 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4201 if (!conv) { 4202 *type = MATSOLVERPETSC; 4203 } else { 4204 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4205 } 4206 PetscFunctionReturn(0); 4207 } 4208 4209 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4210 struct _MatSolverTypeForSpecifcType { 4211 MatType mtype; 4212 PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*); 4213 MatSolverTypeForSpecifcType next; 4214 }; 4215 4216 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4217 struct _MatSolverTypeHolder { 4218 char *name; 4219 MatSolverTypeForSpecifcType handlers; 4220 MatSolverTypeHolder next; 4221 }; 4222 4223 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4224 4225 /*@C 4226 MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type 4227 4228 Input Parameters: 4229 + package - name of the package, for example petsc or superlu 4230 . mtype - the matrix type that works with this package 4231 . ftype - the type of factorization supported by the package 4232 - getfactor - routine that will create the factored matrix ready to be used 4233 4234 Level: intermediate 4235 4236 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4237 @*/ 4238 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*)) 4239 { 4240 PetscErrorCode ierr; 4241 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4242 PetscBool flg; 4243 MatSolverTypeForSpecifcType inext,iprev = NULL; 4244 4245 PetscFunctionBegin; 4246 if (!next) { 4247 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4248 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4249 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4250 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4251 MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor; 4252 PetscFunctionReturn(0); 4253 } 4254 while (next) { 4255 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4256 if (flg) { 4257 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4258 inext = next->handlers; 4259 while (inext) { 4260 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4261 if (flg) { 4262 inext->getfactor[(int)ftype-1] = getfactor; 4263 PetscFunctionReturn(0); 4264 } 4265 iprev = inext; 4266 inext = inext->next; 4267 } 4268 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4269 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4270 iprev->next->getfactor[(int)ftype-1] = getfactor; 4271 PetscFunctionReturn(0); 4272 } 4273 prev = next; 4274 next = next->next; 4275 } 4276 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4277 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4278 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4279 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4280 prev->next->handlers->getfactor[(int)ftype-1] = getfactor; 4281 PetscFunctionReturn(0); 4282 } 4283 4284 /*@C 4285 MatSolvePackageGet - Get's the function that creates the factor matrix if it exist 4286 4287 Input Parameters: 4288 + package - name of the package, for example petsc or superlu 4289 . ftype - the type of factorization supported by the package 4290 - mtype - the matrix type that works with this package 4291 4292 Output Parameters: 4293 + foundpackage - PETSC_TRUE if the package was registered 4294 . foundmtype - PETSC_TRUE if the package supports the requested mtype 4295 - getfactor - routine that will create the factored matrix ready to be used or NULL if not found 4296 4297 Level: intermediate 4298 4299 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4300 @*/ 4301 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*)) 4302 { 4303 PetscErrorCode ierr; 4304 MatSolverTypeHolder next = MatSolverTypeHolders; 4305 PetscBool flg; 4306 MatSolverTypeForSpecifcType inext; 4307 4308 PetscFunctionBegin; 4309 if (foundpackage) *foundpackage = PETSC_FALSE; 4310 if (foundmtype) *foundmtype = PETSC_FALSE; 4311 if (getfactor) *getfactor = NULL; 4312 4313 if (package) { 4314 while (next) { 4315 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4316 if (flg) { 4317 if (foundpackage) *foundpackage = PETSC_TRUE; 4318 inext = next->handlers; 4319 while (inext) { 4320 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4321 if (flg) { 4322 if (foundmtype) *foundmtype = PETSC_TRUE; 4323 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4324 PetscFunctionReturn(0); 4325 } 4326 inext = inext->next; 4327 } 4328 } 4329 next = next->next; 4330 } 4331 } else { 4332 while (next) { 4333 inext = next->handlers; 4334 while (inext) { 4335 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4336 if (flg && inext->getfactor[(int)ftype-1]) { 4337 if (foundpackage) *foundpackage = PETSC_TRUE; 4338 if (foundmtype) *foundmtype = PETSC_TRUE; 4339 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4340 PetscFunctionReturn(0); 4341 } 4342 inext = inext->next; 4343 } 4344 next = next->next; 4345 } 4346 } 4347 PetscFunctionReturn(0); 4348 } 4349 4350 PetscErrorCode MatSolverTypeDestroy(void) 4351 { 4352 PetscErrorCode ierr; 4353 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4354 MatSolverTypeForSpecifcType inext,iprev; 4355 4356 PetscFunctionBegin; 4357 while (next) { 4358 ierr = PetscFree(next->name);CHKERRQ(ierr); 4359 inext = next->handlers; 4360 while (inext) { 4361 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4362 iprev = inext; 4363 inext = inext->next; 4364 ierr = PetscFree(iprev);CHKERRQ(ierr); 4365 } 4366 prev = next; 4367 next = next->next; 4368 ierr = PetscFree(prev);CHKERRQ(ierr); 4369 } 4370 MatSolverTypeHolders = NULL; 4371 PetscFunctionReturn(0); 4372 } 4373 4374 /*@C 4375 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4376 4377 Collective on Mat 4378 4379 Input Parameters: 4380 + mat - the matrix 4381 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4382 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4383 4384 Output Parameters: 4385 . f - the factor matrix used with MatXXFactorSymbolic() calls 4386 4387 Notes: 4388 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4389 such as pastix, superlu, mumps etc. 4390 4391 PETSc must have been ./configure to use the external solver, using the option --download-package 4392 4393 Level: intermediate 4394 4395 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4396 @*/ 4397 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4398 { 4399 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4400 PetscBool foundpackage,foundmtype; 4401 4402 PetscFunctionBegin; 4403 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4404 PetscValidType(mat,1); 4405 4406 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4407 MatCheckPreallocated(mat,1); 4408 4409 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr); 4410 if (!foundpackage) { 4411 if (type) { 4412 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4413 } else { 4414 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>"); 4415 } 4416 } 4417 4418 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4419 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); 4420 4421 #if defined(PETSC_USE_COMPLEX) 4422 if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported"); 4423 #endif 4424 4425 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4426 PetscFunctionReturn(0); 4427 } 4428 4429 /*@C 4430 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4431 4432 Not Collective 4433 4434 Input Parameters: 4435 + mat - the matrix 4436 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4437 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4438 4439 Output Parameter: 4440 . flg - PETSC_TRUE if the factorization is available 4441 4442 Notes: 4443 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4444 such as pastix, superlu, mumps etc. 4445 4446 PETSc must have been ./configure to use the external solver, using the option --download-package 4447 4448 Level: intermediate 4449 4450 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4451 @*/ 4452 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4453 { 4454 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4455 4456 PetscFunctionBegin; 4457 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4458 PetscValidType(mat,1); 4459 4460 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4461 MatCheckPreallocated(mat,1); 4462 4463 *flg = PETSC_FALSE; 4464 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4465 if (gconv) { 4466 *flg = PETSC_TRUE; 4467 } 4468 PetscFunctionReturn(0); 4469 } 4470 4471 #include <petscdmtypes.h> 4472 4473 /*@ 4474 MatDuplicate - Duplicates a matrix including the non-zero structure. 4475 4476 Collective on Mat 4477 4478 Input Parameters: 4479 + mat - the matrix 4480 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4481 See the manual page for MatDuplicateOption for an explanation of these options. 4482 4483 Output Parameter: 4484 . M - pointer to place new matrix 4485 4486 Level: intermediate 4487 4488 Concepts: matrices^duplicating 4489 4490 Notes: 4491 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4492 4493 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4494 @*/ 4495 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4496 { 4497 PetscErrorCode ierr; 4498 Mat B; 4499 PetscInt i; 4500 DM dm; 4501 void (*viewf)(void); 4502 4503 PetscFunctionBegin; 4504 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4505 PetscValidType(mat,1); 4506 PetscValidPointer(M,3); 4507 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4508 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4509 MatCheckPreallocated(mat,1); 4510 4511 *M = 0; 4512 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4513 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4514 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4515 B = *M; 4516 4517 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4518 if (viewf) { 4519 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4520 } 4521 4522 B->stencil.dim = mat->stencil.dim; 4523 B->stencil.noc = mat->stencil.noc; 4524 for (i=0; i<=mat->stencil.dim; i++) { 4525 B->stencil.dims[i] = mat->stencil.dims[i]; 4526 B->stencil.starts[i] = mat->stencil.starts[i]; 4527 } 4528 4529 B->nooffproczerorows = mat->nooffproczerorows; 4530 B->nooffprocentries = mat->nooffprocentries; 4531 4532 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4533 if (dm) { 4534 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4535 } 4536 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4537 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4538 PetscFunctionReturn(0); 4539 } 4540 4541 /*@ 4542 MatGetDiagonal - Gets the diagonal of a matrix. 4543 4544 Logically Collective on Mat and Vec 4545 4546 Input Parameters: 4547 + mat - the matrix 4548 - v - the vector for storing the diagonal 4549 4550 Output Parameter: 4551 . v - the diagonal of the matrix 4552 4553 Level: intermediate 4554 4555 Note: 4556 Currently only correct in parallel for square matrices. 4557 4558 Concepts: matrices^accessing diagonals 4559 4560 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4561 @*/ 4562 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4563 { 4564 PetscErrorCode ierr; 4565 4566 PetscFunctionBegin; 4567 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4568 PetscValidType(mat,1); 4569 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4570 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4571 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4572 MatCheckPreallocated(mat,1); 4573 4574 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4575 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4576 PetscFunctionReturn(0); 4577 } 4578 4579 /*@C 4580 MatGetRowMin - Gets the minimum value (of the real part) of each 4581 row of the matrix 4582 4583 Logically Collective on Mat and Vec 4584 4585 Input Parameters: 4586 . mat - the matrix 4587 4588 Output Parameter: 4589 + v - the vector for storing the maximums 4590 - idx - the indices of the column found for each row (optional) 4591 4592 Level: intermediate 4593 4594 Notes: 4595 The result of this call are the same as if one converted the matrix to dense format 4596 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4597 4598 This code is only implemented for a couple of matrix formats. 4599 4600 Concepts: matrices^getting row maximums 4601 4602 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4603 MatGetRowMax() 4604 @*/ 4605 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4606 { 4607 PetscErrorCode ierr; 4608 4609 PetscFunctionBegin; 4610 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4611 PetscValidType(mat,1); 4612 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4613 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4614 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4615 MatCheckPreallocated(mat,1); 4616 4617 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4618 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4619 PetscFunctionReturn(0); 4620 } 4621 4622 /*@C 4623 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4624 row of the matrix 4625 4626 Logically Collective on Mat and Vec 4627 4628 Input Parameters: 4629 . mat - the matrix 4630 4631 Output Parameter: 4632 + v - the vector for storing the minimums 4633 - idx - the indices of the column found for each row (or NULL if not needed) 4634 4635 Level: intermediate 4636 4637 Notes: 4638 if a row is completely empty or has only 0.0 values then the idx[] value for that 4639 row is 0 (the first column). 4640 4641 This code is only implemented for a couple of matrix formats. 4642 4643 Concepts: matrices^getting row maximums 4644 4645 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4646 @*/ 4647 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4648 { 4649 PetscErrorCode ierr; 4650 4651 PetscFunctionBegin; 4652 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4653 PetscValidType(mat,1); 4654 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4655 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4656 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4657 MatCheckPreallocated(mat,1); 4658 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4659 4660 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4661 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4662 PetscFunctionReturn(0); 4663 } 4664 4665 /*@C 4666 MatGetRowMax - Gets the maximum value (of the real part) of each 4667 row of the matrix 4668 4669 Logically Collective on Mat and Vec 4670 4671 Input Parameters: 4672 . mat - the matrix 4673 4674 Output Parameter: 4675 + v - the vector for storing the maximums 4676 - idx - the indices of the column found for each row (optional) 4677 4678 Level: intermediate 4679 4680 Notes: 4681 The result of this call are the same as if one converted the matrix to dense format 4682 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4683 4684 This code is only implemented for a couple of matrix formats. 4685 4686 Concepts: matrices^getting row maximums 4687 4688 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4689 @*/ 4690 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4691 { 4692 PetscErrorCode ierr; 4693 4694 PetscFunctionBegin; 4695 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4696 PetscValidType(mat,1); 4697 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4698 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4699 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4700 MatCheckPreallocated(mat,1); 4701 4702 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4703 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4704 PetscFunctionReturn(0); 4705 } 4706 4707 /*@C 4708 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4709 row of the matrix 4710 4711 Logically Collective on Mat and Vec 4712 4713 Input Parameters: 4714 . mat - the matrix 4715 4716 Output Parameter: 4717 + v - the vector for storing the maximums 4718 - idx - the indices of the column found for each row (or NULL if not needed) 4719 4720 Level: intermediate 4721 4722 Notes: 4723 if a row is completely empty or has only 0.0 values then the idx[] value for that 4724 row is 0 (the first column). 4725 4726 This code is only implemented for a couple of matrix formats. 4727 4728 Concepts: matrices^getting row maximums 4729 4730 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4731 @*/ 4732 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4733 { 4734 PetscErrorCode ierr; 4735 4736 PetscFunctionBegin; 4737 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4738 PetscValidType(mat,1); 4739 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4740 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4741 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4742 MatCheckPreallocated(mat,1); 4743 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4744 4745 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4746 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4747 PetscFunctionReturn(0); 4748 } 4749 4750 /*@ 4751 MatGetRowSum - Gets the sum of each row of the matrix 4752 4753 Logically or Neighborhood Collective on Mat and Vec 4754 4755 Input Parameters: 4756 . mat - the matrix 4757 4758 Output Parameter: 4759 . v - the vector for storing the sum of rows 4760 4761 Level: intermediate 4762 4763 Notes: 4764 This code is slow since it is not currently specialized for different formats 4765 4766 Concepts: matrices^getting row sums 4767 4768 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4769 @*/ 4770 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4771 { 4772 Vec ones; 4773 PetscErrorCode ierr; 4774 4775 PetscFunctionBegin; 4776 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4777 PetscValidType(mat,1); 4778 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4779 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4780 MatCheckPreallocated(mat,1); 4781 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4782 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4783 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4784 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4785 PetscFunctionReturn(0); 4786 } 4787 4788 /*@ 4789 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4790 4791 Collective on Mat 4792 4793 Input Parameter: 4794 + mat - the matrix to transpose 4795 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4796 4797 Output Parameters: 4798 . B - the transpose 4799 4800 Notes: 4801 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4802 4803 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4804 4805 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4806 4807 Level: intermediate 4808 4809 Concepts: matrices^transposing 4810 4811 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4812 @*/ 4813 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4814 { 4815 PetscErrorCode ierr; 4816 4817 PetscFunctionBegin; 4818 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4819 PetscValidType(mat,1); 4820 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4821 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4822 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4823 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4824 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4825 MatCheckPreallocated(mat,1); 4826 4827 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4828 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4829 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4830 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4831 PetscFunctionReturn(0); 4832 } 4833 4834 /*@ 4835 MatIsTranspose - Test whether a matrix is another one's transpose, 4836 or its own, in which case it tests symmetry. 4837 4838 Collective on Mat 4839 4840 Input Parameter: 4841 + A - the matrix to test 4842 - B - the matrix to test against, this can equal the first parameter 4843 4844 Output Parameters: 4845 . flg - the result 4846 4847 Notes: 4848 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4849 has a running time of the order of the number of nonzeros; the parallel 4850 test involves parallel copies of the block-offdiagonal parts of the matrix. 4851 4852 Level: intermediate 4853 4854 Concepts: matrices^transposing, matrix^symmetry 4855 4856 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4857 @*/ 4858 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4859 { 4860 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4861 4862 PetscFunctionBegin; 4863 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4864 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4865 PetscValidPointer(flg,3); 4866 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4867 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4868 *flg = PETSC_FALSE; 4869 if (f && g) { 4870 if (f == g) { 4871 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4872 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4873 } else { 4874 MatType mattype; 4875 if (!f) { 4876 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4877 } else { 4878 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4879 } 4880 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4881 } 4882 PetscFunctionReturn(0); 4883 } 4884 4885 /*@ 4886 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4887 4888 Collective on Mat 4889 4890 Input Parameter: 4891 + mat - the matrix to transpose and complex conjugate 4892 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 4893 4894 Output Parameters: 4895 . B - the Hermitian 4896 4897 Level: intermediate 4898 4899 Concepts: matrices^transposing, complex conjugatex 4900 4901 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4902 @*/ 4903 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 4904 { 4905 PetscErrorCode ierr; 4906 4907 PetscFunctionBegin; 4908 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 4909 #if defined(PETSC_USE_COMPLEX) 4910 ierr = MatConjugate(*B);CHKERRQ(ierr); 4911 #endif 4912 PetscFunctionReturn(0); 4913 } 4914 4915 /*@ 4916 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 4917 4918 Collective on Mat 4919 4920 Input Parameter: 4921 + A - the matrix to test 4922 - B - the matrix to test against, this can equal the first parameter 4923 4924 Output Parameters: 4925 . flg - the result 4926 4927 Notes: 4928 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4929 has a running time of the order of the number of nonzeros; the parallel 4930 test involves parallel copies of the block-offdiagonal parts of the matrix. 4931 4932 Level: intermediate 4933 4934 Concepts: matrices^transposing, matrix^symmetry 4935 4936 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 4937 @*/ 4938 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4939 { 4940 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4941 4942 PetscFunctionBegin; 4943 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4944 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4945 PetscValidPointer(flg,3); 4946 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 4947 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 4948 if (f && g) { 4949 if (f==g) { 4950 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4951 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 4952 } 4953 PetscFunctionReturn(0); 4954 } 4955 4956 /*@ 4957 MatPermute - Creates a new matrix with rows and columns permuted from the 4958 original. 4959 4960 Collective on Mat 4961 4962 Input Parameters: 4963 + mat - the matrix to permute 4964 . row - row permutation, each processor supplies only the permutation for its rows 4965 - col - column permutation, each processor supplies only the permutation for its columns 4966 4967 Output Parameters: 4968 . B - the permuted matrix 4969 4970 Level: advanced 4971 4972 Note: 4973 The index sets map from row/col of permuted matrix to row/col of original matrix. 4974 The index sets should be on the same communicator as Mat and have the same local sizes. 4975 4976 Concepts: matrices^permuting 4977 4978 .seealso: MatGetOrdering(), ISAllGather() 4979 4980 @*/ 4981 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 4982 { 4983 PetscErrorCode ierr; 4984 4985 PetscFunctionBegin; 4986 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4987 PetscValidType(mat,1); 4988 PetscValidHeaderSpecific(row,IS_CLASSID,2); 4989 PetscValidHeaderSpecific(col,IS_CLASSID,3); 4990 PetscValidPointer(B,4); 4991 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4992 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4993 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 4994 MatCheckPreallocated(mat,1); 4995 4996 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 4997 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 4998 PetscFunctionReturn(0); 4999 } 5000 5001 /*@ 5002 MatEqual - Compares two matrices. 5003 5004 Collective on Mat 5005 5006 Input Parameters: 5007 + A - the first matrix 5008 - B - the second matrix 5009 5010 Output Parameter: 5011 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5012 5013 Level: intermediate 5014 5015 Concepts: matrices^equality between 5016 @*/ 5017 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5018 { 5019 PetscErrorCode ierr; 5020 5021 PetscFunctionBegin; 5022 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5023 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5024 PetscValidType(A,1); 5025 PetscValidType(B,2); 5026 PetscValidIntPointer(flg,3); 5027 PetscCheckSameComm(A,1,B,2); 5028 MatCheckPreallocated(B,2); 5029 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5030 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5031 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); 5032 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5033 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5034 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); 5035 MatCheckPreallocated(A,1); 5036 5037 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5038 PetscFunctionReturn(0); 5039 } 5040 5041 /*@ 5042 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5043 matrices that are stored as vectors. Either of the two scaling 5044 matrices can be NULL. 5045 5046 Collective on Mat 5047 5048 Input Parameters: 5049 + mat - the matrix to be scaled 5050 . l - the left scaling vector (or NULL) 5051 - r - the right scaling vector (or NULL) 5052 5053 Notes: 5054 MatDiagonalScale() computes A = LAR, where 5055 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5056 The L scales the rows of the matrix, the R scales the columns of the matrix. 5057 5058 Level: intermediate 5059 5060 Concepts: matrices^diagonal scaling 5061 Concepts: diagonal scaling of matrices 5062 5063 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5064 @*/ 5065 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5066 { 5067 PetscErrorCode ierr; 5068 5069 PetscFunctionBegin; 5070 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5071 PetscValidType(mat,1); 5072 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5073 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5074 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5075 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5076 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5077 MatCheckPreallocated(mat,1); 5078 5079 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5080 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5081 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5082 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5083 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 5084 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5085 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5086 } 5087 #endif 5088 PetscFunctionReturn(0); 5089 } 5090 5091 /*@ 5092 MatScale - Scales all elements of a matrix by a given number. 5093 5094 Logically Collective on Mat 5095 5096 Input Parameters: 5097 + mat - the matrix to be scaled 5098 - a - the scaling value 5099 5100 Output Parameter: 5101 . mat - the scaled matrix 5102 5103 Level: intermediate 5104 5105 Concepts: matrices^scaling all entries 5106 5107 .seealso: MatDiagonalScale() 5108 @*/ 5109 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5110 { 5111 PetscErrorCode ierr; 5112 5113 PetscFunctionBegin; 5114 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5115 PetscValidType(mat,1); 5116 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5117 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5118 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5119 PetscValidLogicalCollectiveScalar(mat,a,2); 5120 MatCheckPreallocated(mat,1); 5121 5122 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5123 if (a != (PetscScalar)1.0) { 5124 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5125 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5126 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 5127 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5128 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5129 } 5130 #endif 5131 } 5132 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5133 PetscFunctionReturn(0); 5134 } 5135 5136 static PetscErrorCode MatNorm_Basic(Mat A,NormType type,PetscReal *nrm) 5137 { 5138 PetscErrorCode ierr; 5139 5140 PetscFunctionBegin; 5141 if (type == NORM_1 || type == NORM_INFINITY) { 5142 Vec l,r; 5143 5144 ierr = MatCreateVecs(A,&r,&l);CHKERRQ(ierr); 5145 if (type == NORM_INFINITY) { 5146 ierr = VecSet(r,1.);CHKERRQ(ierr); 5147 ierr = MatMult(A,r,l);CHKERRQ(ierr); 5148 ierr = VecNorm(l,NORM_INFINITY,nrm);CHKERRQ(ierr); 5149 } else { 5150 ierr = VecSet(l,1.);CHKERRQ(ierr); 5151 ierr = MatMultTranspose(A,l,r);CHKERRQ(ierr); 5152 ierr = VecNorm(r,NORM_INFINITY,nrm);CHKERRQ(ierr); 5153 } 5154 ierr = VecDestroy(&l);CHKERRQ(ierr); 5155 ierr = VecDestroy(&r);CHKERRQ(ierr); 5156 } else SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix class %s, norm type %d",((PetscObject)A)->type_name,type); 5157 PetscFunctionReturn(0); 5158 } 5159 5160 /*@ 5161 MatNorm - Calculates various norms of a matrix. 5162 5163 Collective on Mat 5164 5165 Input Parameters: 5166 + mat - the matrix 5167 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5168 5169 Output Parameters: 5170 . nrm - the resulting norm 5171 5172 Level: intermediate 5173 5174 Concepts: matrices^norm 5175 Concepts: norm^of matrix 5176 @*/ 5177 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5178 { 5179 PetscErrorCode ierr; 5180 5181 PetscFunctionBegin; 5182 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5183 PetscValidType(mat,1); 5184 PetscValidLogicalCollectiveEnum(mat,type,2); 5185 PetscValidScalarPointer(nrm,3); 5186 5187 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5188 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5189 MatCheckPreallocated(mat,1); 5190 5191 if (!mat->ops->norm) { 5192 ierr = MatNorm_Basic(mat,type,nrm);CHKERRQ(ierr); 5193 } else { 5194 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5195 } 5196 PetscFunctionReturn(0); 5197 } 5198 5199 /* 5200 This variable is used to prevent counting of MatAssemblyBegin() that 5201 are called from within a MatAssemblyEnd(). 5202 */ 5203 static PetscInt MatAssemblyEnd_InUse = 0; 5204 /*@ 5205 MatAssemblyBegin - Begins assembling the matrix. This routine should 5206 be called after completing all calls to MatSetValues(). 5207 5208 Collective on Mat 5209 5210 Input Parameters: 5211 + mat - the matrix 5212 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5213 5214 Notes: 5215 MatSetValues() generally caches the values. The matrix is ready to 5216 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5217 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5218 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5219 using the matrix. 5220 5221 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5222 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 5223 a global collective operation requring all processes that share the matrix. 5224 5225 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5226 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5227 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5228 5229 Level: beginner 5230 5231 Concepts: matrices^assembling 5232 5233 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5234 @*/ 5235 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5236 { 5237 PetscErrorCode ierr; 5238 5239 PetscFunctionBegin; 5240 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5241 PetscValidType(mat,1); 5242 MatCheckPreallocated(mat,1); 5243 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5244 if (mat->assembled) { 5245 mat->was_assembled = PETSC_TRUE; 5246 mat->assembled = PETSC_FALSE; 5247 } 5248 if (!MatAssemblyEnd_InUse) { 5249 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5250 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5251 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5252 } else if (mat->ops->assemblybegin) { 5253 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5254 } 5255 PetscFunctionReturn(0); 5256 } 5257 5258 /*@ 5259 MatAssembled - Indicates if a matrix has been assembled and is ready for 5260 use; for example, in matrix-vector product. 5261 5262 Not Collective 5263 5264 Input Parameter: 5265 . mat - the matrix 5266 5267 Output Parameter: 5268 . assembled - PETSC_TRUE or PETSC_FALSE 5269 5270 Level: advanced 5271 5272 Concepts: matrices^assembled? 5273 5274 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5275 @*/ 5276 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5277 { 5278 PetscFunctionBegin; 5279 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5280 PetscValidType(mat,1); 5281 PetscValidPointer(assembled,2); 5282 *assembled = mat->assembled; 5283 PetscFunctionReturn(0); 5284 } 5285 5286 /*@ 5287 MatAssemblyEnd - Completes assembling the matrix. This routine should 5288 be called after MatAssemblyBegin(). 5289 5290 Collective on Mat 5291 5292 Input Parameters: 5293 + mat - the matrix 5294 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5295 5296 Options Database Keys: 5297 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5298 . -mat_view ::ascii_info_detail - Prints more detailed info 5299 . -mat_view - Prints matrix in ASCII format 5300 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5301 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5302 . -display <name> - Sets display name (default is host) 5303 . -draw_pause <sec> - Sets number of seconds to pause after display 5304 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5305 . -viewer_socket_machine <machine> - Machine to use for socket 5306 . -viewer_socket_port <port> - Port number to use for socket 5307 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5308 5309 Notes: 5310 MatSetValues() generally caches the values. The matrix is ready to 5311 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5312 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5313 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5314 using the matrix. 5315 5316 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5317 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5318 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5319 5320 Level: beginner 5321 5322 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5323 @*/ 5324 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5325 { 5326 PetscErrorCode ierr; 5327 static PetscInt inassm = 0; 5328 PetscBool flg = PETSC_FALSE; 5329 5330 PetscFunctionBegin; 5331 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5332 PetscValidType(mat,1); 5333 5334 inassm++; 5335 MatAssemblyEnd_InUse++; 5336 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5337 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5338 if (mat->ops->assemblyend) { 5339 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5340 } 5341 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5342 } else if (mat->ops->assemblyend) { 5343 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5344 } 5345 5346 /* Flush assembly is not a true assembly */ 5347 if (type != MAT_FLUSH_ASSEMBLY) { 5348 mat->assembled = PETSC_TRUE; mat->num_ass++; 5349 } 5350 mat->insertmode = NOT_SET_VALUES; 5351 MatAssemblyEnd_InUse--; 5352 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5353 if (!mat->symmetric_eternal) { 5354 mat->symmetric_set = PETSC_FALSE; 5355 mat->hermitian_set = PETSC_FALSE; 5356 mat->structurally_symmetric_set = PETSC_FALSE; 5357 } 5358 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 5359 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5360 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5361 } 5362 #endif 5363 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5364 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5365 5366 if (mat->checksymmetryonassembly) { 5367 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5368 if (flg) { 5369 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5370 } else { 5371 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5372 } 5373 } 5374 if (mat->nullsp && mat->checknullspaceonassembly) { 5375 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5376 } 5377 } 5378 inassm--; 5379 PetscFunctionReturn(0); 5380 } 5381 5382 /*@ 5383 MatSetOption - Sets a parameter option for a matrix. Some options 5384 may be specific to certain storage formats. Some options 5385 determine how values will be inserted (or added). Sorted, 5386 row-oriented input will generally assemble the fastest. The default 5387 is row-oriented. 5388 5389 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5390 5391 Input Parameters: 5392 + mat - the matrix 5393 . option - the option, one of those listed below (and possibly others), 5394 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5395 5396 Options Describing Matrix Structure: 5397 + MAT_SPD - symmetric positive definite 5398 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5399 . MAT_HERMITIAN - transpose is the complex conjugation 5400 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5401 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5402 you set to be kept with all future use of the matrix 5403 including after MatAssemblyBegin/End() which could 5404 potentially change the symmetry structure, i.e. you 5405 KNOW the matrix will ALWAYS have the property you set. 5406 5407 5408 Options For Use with MatSetValues(): 5409 Insert a logically dense subblock, which can be 5410 . MAT_ROW_ORIENTED - row-oriented (default) 5411 5412 Note these options reflect the data you pass in with MatSetValues(); it has 5413 nothing to do with how the data is stored internally in the matrix 5414 data structure. 5415 5416 When (re)assembling a matrix, we can restrict the input for 5417 efficiency/debugging purposes. These options include: 5418 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5419 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5420 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5421 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5422 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5423 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5424 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5425 performance for very large process counts. 5426 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5427 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5428 functions, instead sending only neighbor messages. 5429 5430 Notes: 5431 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5432 5433 Some options are relevant only for particular matrix types and 5434 are thus ignored by others. Other options are not supported by 5435 certain matrix types and will generate an error message if set. 5436 5437 If using a Fortran 77 module to compute a matrix, one may need to 5438 use the column-oriented option (or convert to the row-oriented 5439 format). 5440 5441 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5442 that would generate a new entry in the nonzero structure is instead 5443 ignored. Thus, if memory has not alredy been allocated for this particular 5444 data, then the insertion is ignored. For dense matrices, in which 5445 the entire array is allocated, no entries are ever ignored. 5446 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5447 5448 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5449 that would generate a new entry in the nonzero structure instead produces 5450 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 5451 5452 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5453 that would generate a new entry that has not been preallocated will 5454 instead produce an error. (Currently supported for AIJ and BAIJ formats 5455 only.) This is a useful flag when debugging matrix memory preallocation. 5456 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5457 5458 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5459 other processors should be dropped, rather than stashed. 5460 This is useful if you know that the "owning" processor is also 5461 always generating the correct matrix entries, so that PETSc need 5462 not transfer duplicate entries generated on another processor. 5463 5464 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5465 searches during matrix assembly. When this flag is set, the hash table 5466 is created during the first Matrix Assembly. This hash table is 5467 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5468 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5469 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5470 supported by MATMPIBAIJ format only. 5471 5472 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5473 are kept in the nonzero structure 5474 5475 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5476 a zero location in the matrix 5477 5478 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5479 5480 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5481 zero row routines and thus improves performance for very large process counts. 5482 5483 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5484 part of the matrix (since they should match the upper triangular part). 5485 5486 Notes: 5487 Can only be called after MatSetSizes() and MatSetType() have been set. 5488 5489 Level: intermediate 5490 5491 Concepts: matrices^setting options 5492 5493 .seealso: MatOption, Mat 5494 5495 @*/ 5496 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5497 { 5498 PetscErrorCode ierr; 5499 5500 PetscFunctionBegin; 5501 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5502 PetscValidType(mat,1); 5503 if (op > 0) { 5504 PetscValidLogicalCollectiveEnum(mat,op,2); 5505 PetscValidLogicalCollectiveBool(mat,flg,3); 5506 } 5507 5508 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); 5509 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()"); 5510 5511 switch (op) { 5512 case MAT_NO_OFF_PROC_ENTRIES: 5513 mat->nooffprocentries = flg; 5514 PetscFunctionReturn(0); 5515 break; 5516 case MAT_SUBSET_OFF_PROC_ENTRIES: 5517 mat->subsetoffprocentries = flg; 5518 PetscFunctionReturn(0); 5519 case MAT_NO_OFF_PROC_ZERO_ROWS: 5520 mat->nooffproczerorows = flg; 5521 PetscFunctionReturn(0); 5522 break; 5523 case MAT_SPD: 5524 mat->spd_set = PETSC_TRUE; 5525 mat->spd = flg; 5526 if (flg) { 5527 mat->symmetric = PETSC_TRUE; 5528 mat->structurally_symmetric = PETSC_TRUE; 5529 mat->symmetric_set = PETSC_TRUE; 5530 mat->structurally_symmetric_set = PETSC_TRUE; 5531 } 5532 break; 5533 case MAT_SYMMETRIC: 5534 mat->symmetric = flg; 5535 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5536 mat->symmetric_set = PETSC_TRUE; 5537 mat->structurally_symmetric_set = flg; 5538 #if !defined(PETSC_USE_COMPLEX) 5539 mat->hermitian = flg; 5540 mat->hermitian_set = PETSC_TRUE; 5541 #endif 5542 break; 5543 case MAT_HERMITIAN: 5544 mat->hermitian = flg; 5545 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5546 mat->hermitian_set = PETSC_TRUE; 5547 mat->structurally_symmetric_set = flg; 5548 #if !defined(PETSC_USE_COMPLEX) 5549 mat->symmetric = flg; 5550 mat->symmetric_set = PETSC_TRUE; 5551 #endif 5552 break; 5553 case MAT_STRUCTURALLY_SYMMETRIC: 5554 mat->structurally_symmetric = flg; 5555 mat->structurally_symmetric_set = PETSC_TRUE; 5556 break; 5557 case MAT_SYMMETRY_ETERNAL: 5558 mat->symmetric_eternal = flg; 5559 break; 5560 case MAT_STRUCTURE_ONLY: 5561 mat->structure_only = flg; 5562 break; 5563 default: 5564 break; 5565 } 5566 if (mat->ops->setoption) { 5567 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5568 } 5569 PetscFunctionReturn(0); 5570 } 5571 5572 /*@ 5573 MatGetOption - Gets a parameter option that has been set for a matrix. 5574 5575 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5576 5577 Input Parameters: 5578 + mat - the matrix 5579 - option - the option, this only responds to certain options, check the code for which ones 5580 5581 Output Parameter: 5582 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5583 5584 Notes: 5585 Can only be called after MatSetSizes() and MatSetType() have been set. 5586 5587 Level: intermediate 5588 5589 Concepts: matrices^setting options 5590 5591 .seealso: MatOption, MatSetOption() 5592 5593 @*/ 5594 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5595 { 5596 PetscFunctionBegin; 5597 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5598 PetscValidType(mat,1); 5599 5600 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); 5601 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()"); 5602 5603 switch (op) { 5604 case MAT_NO_OFF_PROC_ENTRIES: 5605 *flg = mat->nooffprocentries; 5606 break; 5607 case MAT_NO_OFF_PROC_ZERO_ROWS: 5608 *flg = mat->nooffproczerorows; 5609 break; 5610 case MAT_SYMMETRIC: 5611 *flg = mat->symmetric; 5612 break; 5613 case MAT_HERMITIAN: 5614 *flg = mat->hermitian; 5615 break; 5616 case MAT_STRUCTURALLY_SYMMETRIC: 5617 *flg = mat->structurally_symmetric; 5618 break; 5619 case MAT_SYMMETRY_ETERNAL: 5620 *flg = mat->symmetric_eternal; 5621 break; 5622 case MAT_SPD: 5623 *flg = mat->spd; 5624 break; 5625 default: 5626 break; 5627 } 5628 PetscFunctionReturn(0); 5629 } 5630 5631 /*@ 5632 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5633 this routine retains the old nonzero structure. 5634 5635 Logically Collective on Mat 5636 5637 Input Parameters: 5638 . mat - the matrix 5639 5640 Level: intermediate 5641 5642 Notes: 5643 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. 5644 See the Performance chapter of the users manual for information on preallocating matrices. 5645 5646 Concepts: matrices^zeroing 5647 5648 .seealso: MatZeroRows() 5649 @*/ 5650 PetscErrorCode MatZeroEntries(Mat mat) 5651 { 5652 PetscErrorCode ierr; 5653 5654 PetscFunctionBegin; 5655 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5656 PetscValidType(mat,1); 5657 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5658 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"); 5659 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5660 MatCheckPreallocated(mat,1); 5661 5662 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5663 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5664 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5665 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5666 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 5667 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5668 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5669 } 5670 #endif 5671 PetscFunctionReturn(0); 5672 } 5673 5674 /*@ 5675 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5676 of a set of rows and columns of a matrix. 5677 5678 Collective on Mat 5679 5680 Input Parameters: 5681 + mat - the matrix 5682 . numRows - the number of rows to remove 5683 . rows - the global row indices 5684 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5685 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5686 - b - optional vector of right hand side, that will be adjusted by provided solution 5687 5688 Notes: 5689 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5690 5691 The user can set a value in the diagonal entry (or for the AIJ and 5692 row formats can optionally remove the main diagonal entry from the 5693 nonzero structure as well, by passing 0.0 as the final argument). 5694 5695 For the parallel case, all processes that share the matrix (i.e., 5696 those in the communicator used for matrix creation) MUST call this 5697 routine, regardless of whether any rows being zeroed are owned by 5698 them. 5699 5700 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5701 list only rows local to itself). 5702 5703 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5704 5705 Level: intermediate 5706 5707 Concepts: matrices^zeroing rows 5708 5709 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5710 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5711 @*/ 5712 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5713 { 5714 PetscErrorCode ierr; 5715 5716 PetscFunctionBegin; 5717 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5718 PetscValidType(mat,1); 5719 if (numRows) PetscValidIntPointer(rows,3); 5720 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5721 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5722 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5723 MatCheckPreallocated(mat,1); 5724 5725 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5726 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5727 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5728 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 5729 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5730 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5731 } 5732 #endif 5733 PetscFunctionReturn(0); 5734 } 5735 5736 /*@ 5737 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5738 of a set of rows and columns of a matrix. 5739 5740 Collective on Mat 5741 5742 Input Parameters: 5743 + mat - the matrix 5744 . is - the rows to zero 5745 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5746 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5747 - b - optional vector of right hand side, that will be adjusted by provided solution 5748 5749 Notes: 5750 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5751 5752 The user can set a value in the diagonal entry (or for the AIJ and 5753 row formats can optionally remove the main diagonal entry from the 5754 nonzero structure as well, by passing 0.0 as the final argument). 5755 5756 For the parallel case, all processes that share the matrix (i.e., 5757 those in the communicator used for matrix creation) MUST call this 5758 routine, regardless of whether any rows being zeroed are owned by 5759 them. 5760 5761 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5762 list only rows local to itself). 5763 5764 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5765 5766 Level: intermediate 5767 5768 Concepts: matrices^zeroing rows 5769 5770 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5771 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5772 @*/ 5773 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5774 { 5775 PetscErrorCode ierr; 5776 PetscInt numRows; 5777 const PetscInt *rows; 5778 5779 PetscFunctionBegin; 5780 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5781 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5782 PetscValidType(mat,1); 5783 PetscValidType(is,2); 5784 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5785 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5786 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5787 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5788 PetscFunctionReturn(0); 5789 } 5790 5791 /*@ 5792 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5793 of a set of rows of a matrix. 5794 5795 Collective on Mat 5796 5797 Input Parameters: 5798 + mat - the matrix 5799 . numRows - the number of rows to remove 5800 . rows - the global row indices 5801 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5802 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5803 - b - optional vector of right hand side, that will be adjusted by provided solution 5804 5805 Notes: 5806 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5807 but does not release memory. For the dense and block diagonal 5808 formats this does not alter the nonzero structure. 5809 5810 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5811 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5812 merely zeroed. 5813 5814 The user can set a value in the diagonal entry (or for the AIJ and 5815 row formats can optionally remove the main diagonal entry from the 5816 nonzero structure as well, by passing 0.0 as the final argument). 5817 5818 For the parallel case, all processes that share the matrix (i.e., 5819 those in the communicator used for matrix creation) MUST call this 5820 routine, regardless of whether any rows being zeroed are owned by 5821 them. 5822 5823 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5824 list only rows local to itself). 5825 5826 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5827 owns that are to be zeroed. This saves a global synchronization in the implementation. 5828 5829 Level: intermediate 5830 5831 Concepts: matrices^zeroing rows 5832 5833 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5834 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5835 @*/ 5836 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5837 { 5838 PetscErrorCode ierr; 5839 5840 PetscFunctionBegin; 5841 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5842 PetscValidType(mat,1); 5843 if (numRows) PetscValidIntPointer(rows,3); 5844 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5845 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5846 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5847 MatCheckPreallocated(mat,1); 5848 5849 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5850 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5851 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5852 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 5853 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5854 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5855 } 5856 #endif 5857 PetscFunctionReturn(0); 5858 } 5859 5860 /*@ 5861 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5862 of a set of rows of a matrix. 5863 5864 Collective on Mat 5865 5866 Input Parameters: 5867 + mat - the matrix 5868 . is - index set of rows to remove 5869 . diag - value put in all diagonals of eliminated rows 5870 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5871 - b - optional vector of right hand side, that will be adjusted by provided solution 5872 5873 Notes: 5874 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5875 but does not release memory. For the dense and block diagonal 5876 formats this does not alter the nonzero structure. 5877 5878 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5879 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5880 merely zeroed. 5881 5882 The user can set a value in the diagonal entry (or for the AIJ and 5883 row formats can optionally remove the main diagonal entry from the 5884 nonzero structure as well, by passing 0.0 as the final argument). 5885 5886 For the parallel case, all processes that share the matrix (i.e., 5887 those in the communicator used for matrix creation) MUST call this 5888 routine, regardless of whether any rows being zeroed are owned by 5889 them. 5890 5891 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5892 list only rows local to itself). 5893 5894 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5895 owns that are to be zeroed. This saves a global synchronization in the implementation. 5896 5897 Level: intermediate 5898 5899 Concepts: matrices^zeroing rows 5900 5901 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5902 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5903 @*/ 5904 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5905 { 5906 PetscInt numRows; 5907 const PetscInt *rows; 5908 PetscErrorCode ierr; 5909 5910 PetscFunctionBegin; 5911 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5912 PetscValidType(mat,1); 5913 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5914 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5915 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5916 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5917 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5918 PetscFunctionReturn(0); 5919 } 5920 5921 /*@ 5922 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5923 of a set of rows of a matrix. These rows must be local to the process. 5924 5925 Collective on Mat 5926 5927 Input Parameters: 5928 + mat - the matrix 5929 . numRows - the number of rows to remove 5930 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5931 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5932 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5933 - b - optional vector of right hand side, that will be adjusted by provided solution 5934 5935 Notes: 5936 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5937 but does not release memory. For the dense and block diagonal 5938 formats this does not alter the nonzero structure. 5939 5940 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5941 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5942 merely zeroed. 5943 5944 The user can set a value in the diagonal entry (or for the AIJ and 5945 row formats can optionally remove the main diagonal entry from the 5946 nonzero structure as well, by passing 0.0 as the final argument). 5947 5948 For the parallel case, all processes that share the matrix (i.e., 5949 those in the communicator used for matrix creation) MUST call this 5950 routine, regardless of whether any rows being zeroed are owned by 5951 them. 5952 5953 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5954 list only rows local to itself). 5955 5956 The grid coordinates are across the entire grid, not just the local portion 5957 5958 In Fortran idxm and idxn should be declared as 5959 $ MatStencil idxm(4,m) 5960 and the values inserted using 5961 $ idxm(MatStencil_i,1) = i 5962 $ idxm(MatStencil_j,1) = j 5963 $ idxm(MatStencil_k,1) = k 5964 $ idxm(MatStencil_c,1) = c 5965 etc 5966 5967 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5968 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5969 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5970 DM_BOUNDARY_PERIODIC boundary type. 5971 5972 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 5973 a single value per point) you can skip filling those indices. 5974 5975 Level: intermediate 5976 5977 Concepts: matrices^zeroing rows 5978 5979 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5980 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5981 @*/ 5982 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5983 { 5984 PetscInt dim = mat->stencil.dim; 5985 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5986 PetscInt *dims = mat->stencil.dims+1; 5987 PetscInt *starts = mat->stencil.starts; 5988 PetscInt *dxm = (PetscInt*) rows; 5989 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5990 PetscErrorCode ierr; 5991 5992 PetscFunctionBegin; 5993 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5994 PetscValidType(mat,1); 5995 if (numRows) PetscValidIntPointer(rows,3); 5996 5997 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 5998 for (i = 0; i < numRows; ++i) { 5999 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6000 for (j = 0; j < 3-sdim; ++j) dxm++; 6001 /* Local index in X dir */ 6002 tmp = *dxm++ - starts[0]; 6003 /* Loop over remaining dimensions */ 6004 for (j = 0; j < dim-1; ++j) { 6005 /* If nonlocal, set index to be negative */ 6006 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6007 /* Update local index */ 6008 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6009 } 6010 /* Skip component slot if necessary */ 6011 if (mat->stencil.noc) dxm++; 6012 /* Local row number */ 6013 if (tmp >= 0) { 6014 jdxm[numNewRows++] = tmp; 6015 } 6016 } 6017 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6018 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6019 PetscFunctionReturn(0); 6020 } 6021 6022 /*@ 6023 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6024 of a set of rows and columns of a matrix. 6025 6026 Collective on Mat 6027 6028 Input Parameters: 6029 + mat - the matrix 6030 . numRows - the number of rows/columns to remove 6031 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6032 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6033 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6034 - b - optional vector of right hand side, that will be adjusted by provided solution 6035 6036 Notes: 6037 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6038 but does not release memory. For the dense and block diagonal 6039 formats this does not alter the nonzero structure. 6040 6041 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6042 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6043 merely zeroed. 6044 6045 The user can set a value in the diagonal entry (or for the AIJ and 6046 row formats can optionally remove the main diagonal entry from the 6047 nonzero structure as well, by passing 0.0 as the final argument). 6048 6049 For the parallel case, all processes that share the matrix (i.e., 6050 those in the communicator used for matrix creation) MUST call this 6051 routine, regardless of whether any rows being zeroed are owned by 6052 them. 6053 6054 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6055 list only rows local to itself, but the row/column numbers are given in local numbering). 6056 6057 The grid coordinates are across the entire grid, not just the local portion 6058 6059 In Fortran idxm and idxn should be declared as 6060 $ MatStencil idxm(4,m) 6061 and the values inserted using 6062 $ idxm(MatStencil_i,1) = i 6063 $ idxm(MatStencil_j,1) = j 6064 $ idxm(MatStencil_k,1) = k 6065 $ idxm(MatStencil_c,1) = c 6066 etc 6067 6068 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6069 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6070 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6071 DM_BOUNDARY_PERIODIC boundary type. 6072 6073 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 6074 a single value per point) you can skip filling those indices. 6075 6076 Level: intermediate 6077 6078 Concepts: matrices^zeroing rows 6079 6080 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6081 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6082 @*/ 6083 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6084 { 6085 PetscInt dim = mat->stencil.dim; 6086 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6087 PetscInt *dims = mat->stencil.dims+1; 6088 PetscInt *starts = mat->stencil.starts; 6089 PetscInt *dxm = (PetscInt*) rows; 6090 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6091 PetscErrorCode ierr; 6092 6093 PetscFunctionBegin; 6094 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6095 PetscValidType(mat,1); 6096 if (numRows) PetscValidIntPointer(rows,3); 6097 6098 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6099 for (i = 0; i < numRows; ++i) { 6100 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6101 for (j = 0; j < 3-sdim; ++j) dxm++; 6102 /* Local index in X dir */ 6103 tmp = *dxm++ - starts[0]; 6104 /* Loop over remaining dimensions */ 6105 for (j = 0; j < dim-1; ++j) { 6106 /* If nonlocal, set index to be negative */ 6107 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6108 /* Update local index */ 6109 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6110 } 6111 /* Skip component slot if necessary */ 6112 if (mat->stencil.noc) dxm++; 6113 /* Local row number */ 6114 if (tmp >= 0) { 6115 jdxm[numNewRows++] = tmp; 6116 } 6117 } 6118 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6119 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6120 PetscFunctionReturn(0); 6121 } 6122 6123 /*@ 6124 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6125 of a set of rows of a matrix; using local numbering of rows. 6126 6127 Collective on Mat 6128 6129 Input Parameters: 6130 + mat - the matrix 6131 . numRows - the number of rows to remove 6132 . rows - the global row indices 6133 . diag - value put in all diagonals of eliminated rows 6134 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6135 - b - optional vector of right hand side, that will be adjusted by provided solution 6136 6137 Notes: 6138 Before calling MatZeroRowsLocal(), the user must first set the 6139 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6140 6141 For the AIJ matrix formats this removes the old nonzero structure, 6142 but does not release memory. For the dense and block diagonal 6143 formats this does not alter the nonzero structure. 6144 6145 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6146 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6147 merely zeroed. 6148 6149 The user can set a value in the diagonal entry (or for the AIJ and 6150 row formats can optionally remove the main diagonal entry from the 6151 nonzero structure as well, by passing 0.0 as the final argument). 6152 6153 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6154 owns that are to be zeroed. This saves a global synchronization in the implementation. 6155 6156 Level: intermediate 6157 6158 Concepts: matrices^zeroing 6159 6160 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6161 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6162 @*/ 6163 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6164 { 6165 PetscErrorCode ierr; 6166 6167 PetscFunctionBegin; 6168 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6169 PetscValidType(mat,1); 6170 if (numRows) PetscValidIntPointer(rows,3); 6171 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6172 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6173 MatCheckPreallocated(mat,1); 6174 6175 if (mat->ops->zerorowslocal) { 6176 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6177 } else { 6178 IS is, newis; 6179 const PetscInt *newRows; 6180 6181 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6182 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6183 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6184 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6185 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6186 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6187 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6188 ierr = ISDestroy(&is);CHKERRQ(ierr); 6189 } 6190 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6191 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 6192 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6193 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6194 } 6195 #endif 6196 PetscFunctionReturn(0); 6197 } 6198 6199 /*@ 6200 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6201 of a set of rows of a matrix; using local numbering of rows. 6202 6203 Collective on Mat 6204 6205 Input Parameters: 6206 + mat - the matrix 6207 . is - index set of rows to remove 6208 . diag - value put in all diagonals of eliminated rows 6209 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6210 - b - optional vector of right hand side, that will be adjusted by provided solution 6211 6212 Notes: 6213 Before calling MatZeroRowsLocalIS(), the user must first set the 6214 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6215 6216 For the AIJ matrix formats this removes the old nonzero structure, 6217 but does not release memory. For the dense and block diagonal 6218 formats this does not alter the nonzero structure. 6219 6220 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6221 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6222 merely zeroed. 6223 6224 The user can set a value in the diagonal entry (or for the AIJ and 6225 row formats can optionally remove the main diagonal entry from the 6226 nonzero structure as well, by passing 0.0 as the final argument). 6227 6228 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6229 owns that are to be zeroed. This saves a global synchronization in the implementation. 6230 6231 Level: intermediate 6232 6233 Concepts: matrices^zeroing 6234 6235 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6236 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6237 @*/ 6238 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6239 { 6240 PetscErrorCode ierr; 6241 PetscInt numRows; 6242 const PetscInt *rows; 6243 6244 PetscFunctionBegin; 6245 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6246 PetscValidType(mat,1); 6247 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6248 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6249 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6250 MatCheckPreallocated(mat,1); 6251 6252 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6253 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6254 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6255 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6256 PetscFunctionReturn(0); 6257 } 6258 6259 /*@ 6260 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6261 of a set of rows and columns of a matrix; using local numbering of rows. 6262 6263 Collective on Mat 6264 6265 Input Parameters: 6266 + mat - the matrix 6267 . numRows - the number of rows to remove 6268 . rows - the global row indices 6269 . diag - value put in all diagonals of eliminated rows 6270 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6271 - b - optional vector of right hand side, that will be adjusted by provided solution 6272 6273 Notes: 6274 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6275 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6276 6277 The user can set a value in the diagonal entry (or for the AIJ and 6278 row formats can optionally remove the main diagonal entry from the 6279 nonzero structure as well, by passing 0.0 as the final argument). 6280 6281 Level: intermediate 6282 6283 Concepts: matrices^zeroing 6284 6285 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6286 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6287 @*/ 6288 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6289 { 6290 PetscErrorCode ierr; 6291 IS is, newis; 6292 const PetscInt *newRows; 6293 6294 PetscFunctionBegin; 6295 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6296 PetscValidType(mat,1); 6297 if (numRows) PetscValidIntPointer(rows,3); 6298 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6299 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6300 MatCheckPreallocated(mat,1); 6301 6302 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6303 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6304 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6305 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6306 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6307 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6308 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6309 ierr = ISDestroy(&is);CHKERRQ(ierr); 6310 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6311 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA) 6312 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6313 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6314 } 6315 #endif 6316 PetscFunctionReturn(0); 6317 } 6318 6319 /*@ 6320 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6321 of a set of rows and columns of a matrix; using local numbering of rows. 6322 6323 Collective on Mat 6324 6325 Input Parameters: 6326 + mat - the matrix 6327 . is - index set of rows to remove 6328 . diag - value put in all diagonals of eliminated rows 6329 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6330 - b - optional vector of right hand side, that will be adjusted by provided solution 6331 6332 Notes: 6333 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6334 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6335 6336 The user can set a value in the diagonal entry (or for the AIJ and 6337 row formats can optionally remove the main diagonal entry from the 6338 nonzero structure as well, by passing 0.0 as the final argument). 6339 6340 Level: intermediate 6341 6342 Concepts: matrices^zeroing 6343 6344 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6345 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6346 @*/ 6347 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6348 { 6349 PetscErrorCode ierr; 6350 PetscInt numRows; 6351 const PetscInt *rows; 6352 6353 PetscFunctionBegin; 6354 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6355 PetscValidType(mat,1); 6356 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6357 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6358 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6359 MatCheckPreallocated(mat,1); 6360 6361 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6362 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6363 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6364 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6365 PetscFunctionReturn(0); 6366 } 6367 6368 /*@C 6369 MatGetSize - Returns the numbers of rows and columns in a matrix. 6370 6371 Not Collective 6372 6373 Input Parameter: 6374 . mat - the matrix 6375 6376 Output Parameters: 6377 + m - the number of global rows 6378 - n - the number of global columns 6379 6380 Note: both output parameters can be NULL on input. 6381 6382 Level: beginner 6383 6384 Concepts: matrices^size 6385 6386 .seealso: MatGetLocalSize() 6387 @*/ 6388 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6389 { 6390 PetscFunctionBegin; 6391 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6392 if (m) *m = mat->rmap->N; 6393 if (n) *n = mat->cmap->N; 6394 PetscFunctionReturn(0); 6395 } 6396 6397 /*@C 6398 MatGetLocalSize - Returns the number of rows and columns in a matrix 6399 stored locally. This information may be implementation dependent, so 6400 use with care. 6401 6402 Not Collective 6403 6404 Input Parameters: 6405 . mat - the matrix 6406 6407 Output Parameters: 6408 + m - the number of local rows 6409 - n - the number of local columns 6410 6411 Note: both output parameters can be NULL on input. 6412 6413 Level: beginner 6414 6415 Concepts: matrices^local size 6416 6417 .seealso: MatGetSize() 6418 @*/ 6419 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6420 { 6421 PetscFunctionBegin; 6422 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6423 if (m) PetscValidIntPointer(m,2); 6424 if (n) PetscValidIntPointer(n,3); 6425 if (m) *m = mat->rmap->n; 6426 if (n) *n = mat->cmap->n; 6427 PetscFunctionReturn(0); 6428 } 6429 6430 /*@C 6431 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6432 this processor. (The columns of the "diagonal block") 6433 6434 Not Collective, unless matrix has not been allocated, then collective on Mat 6435 6436 Input Parameters: 6437 . mat - the matrix 6438 6439 Output Parameters: 6440 + m - the global index of the first local column 6441 - n - one more than the global index of the last local column 6442 6443 Notes: 6444 both output parameters can be NULL on input. 6445 6446 Level: developer 6447 6448 Concepts: matrices^column ownership 6449 6450 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6451 6452 @*/ 6453 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6454 { 6455 PetscFunctionBegin; 6456 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6457 PetscValidType(mat,1); 6458 if (m) PetscValidIntPointer(m,2); 6459 if (n) PetscValidIntPointer(n,3); 6460 MatCheckPreallocated(mat,1); 6461 if (m) *m = mat->cmap->rstart; 6462 if (n) *n = mat->cmap->rend; 6463 PetscFunctionReturn(0); 6464 } 6465 6466 /*@C 6467 MatGetOwnershipRange - Returns the range of matrix rows owned by 6468 this processor, assuming that the matrix is laid out with the first 6469 n1 rows on the first processor, the next n2 rows on the second, etc. 6470 For certain parallel layouts this range may not be well defined. 6471 6472 Not Collective 6473 6474 Input Parameters: 6475 . mat - the matrix 6476 6477 Output Parameters: 6478 + m - the global index of the first local row 6479 - n - one more than the global index of the last local row 6480 6481 Note: Both output parameters can be NULL on input. 6482 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6483 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6484 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6485 6486 Level: beginner 6487 6488 Concepts: matrices^row ownership 6489 6490 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6491 6492 @*/ 6493 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6494 { 6495 PetscFunctionBegin; 6496 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6497 PetscValidType(mat,1); 6498 if (m) PetscValidIntPointer(m,2); 6499 if (n) PetscValidIntPointer(n,3); 6500 MatCheckPreallocated(mat,1); 6501 if (m) *m = mat->rmap->rstart; 6502 if (n) *n = mat->rmap->rend; 6503 PetscFunctionReturn(0); 6504 } 6505 6506 /*@C 6507 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6508 each process 6509 6510 Not Collective, unless matrix has not been allocated, then collective on Mat 6511 6512 Input Parameters: 6513 . mat - the matrix 6514 6515 Output Parameters: 6516 . ranges - start of each processors portion plus one more than the total length at the end 6517 6518 Level: beginner 6519 6520 Concepts: matrices^row ownership 6521 6522 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6523 6524 @*/ 6525 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6526 { 6527 PetscErrorCode ierr; 6528 6529 PetscFunctionBegin; 6530 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6531 PetscValidType(mat,1); 6532 MatCheckPreallocated(mat,1); 6533 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6534 PetscFunctionReturn(0); 6535 } 6536 6537 /*@C 6538 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6539 this processor. (The columns of the "diagonal blocks" for each process) 6540 6541 Not Collective, unless matrix has not been allocated, then collective on Mat 6542 6543 Input Parameters: 6544 . mat - the matrix 6545 6546 Output Parameters: 6547 . ranges - start of each processors portion plus one more then the total length at the end 6548 6549 Level: beginner 6550 6551 Concepts: matrices^column ownership 6552 6553 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6554 6555 @*/ 6556 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6557 { 6558 PetscErrorCode ierr; 6559 6560 PetscFunctionBegin; 6561 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6562 PetscValidType(mat,1); 6563 MatCheckPreallocated(mat,1); 6564 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6565 PetscFunctionReturn(0); 6566 } 6567 6568 /*@C 6569 MatGetOwnershipIS - Get row and column ownership as index sets 6570 6571 Not Collective 6572 6573 Input Arguments: 6574 . A - matrix of type Elemental 6575 6576 Output Arguments: 6577 + rows - rows in which this process owns elements 6578 . cols - columns in which this process owns elements 6579 6580 Level: intermediate 6581 6582 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6583 @*/ 6584 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6585 { 6586 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6587 6588 PetscFunctionBegin; 6589 MatCheckPreallocated(A,1); 6590 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6591 if (f) { 6592 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6593 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6594 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6595 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6596 } 6597 PetscFunctionReturn(0); 6598 } 6599 6600 /*@C 6601 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6602 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6603 to complete the factorization. 6604 6605 Collective on Mat 6606 6607 Input Parameters: 6608 + mat - the matrix 6609 . row - row permutation 6610 . column - column permutation 6611 - info - structure containing 6612 $ levels - number of levels of fill. 6613 $ expected fill - as ratio of original fill. 6614 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6615 missing diagonal entries) 6616 6617 Output Parameters: 6618 . fact - new matrix that has been symbolically factored 6619 6620 Notes: 6621 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6622 6623 Most users should employ the simplified KSP interface for linear solvers 6624 instead of working directly with matrix algebra routines such as this. 6625 See, e.g., KSPCreate(). 6626 6627 Level: developer 6628 6629 Concepts: matrices^symbolic LU factorization 6630 Concepts: matrices^factorization 6631 Concepts: LU^symbolic factorization 6632 6633 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6634 MatGetOrdering(), MatFactorInfo 6635 6636 Developer Note: fortran interface is not autogenerated as the f90 6637 interface defintion cannot be generated correctly [due to MatFactorInfo] 6638 6639 @*/ 6640 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6641 { 6642 PetscErrorCode ierr; 6643 6644 PetscFunctionBegin; 6645 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6646 PetscValidType(mat,1); 6647 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6648 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6649 PetscValidPointer(info,4); 6650 PetscValidPointer(fact,5); 6651 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6652 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6653 if (!(fact)->ops->ilufactorsymbolic) { 6654 MatSolverType spackage; 6655 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6656 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6657 } 6658 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6659 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6660 MatCheckPreallocated(mat,2); 6661 6662 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6663 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6664 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6665 PetscFunctionReturn(0); 6666 } 6667 6668 /*@C 6669 MatICCFactorSymbolic - Performs symbolic incomplete 6670 Cholesky factorization for a symmetric matrix. Use 6671 MatCholeskyFactorNumeric() to complete the factorization. 6672 6673 Collective on Mat 6674 6675 Input Parameters: 6676 + mat - the matrix 6677 . perm - row and column permutation 6678 - info - structure containing 6679 $ levels - number of levels of fill. 6680 $ expected fill - as ratio of original fill. 6681 6682 Output Parameter: 6683 . fact - the factored matrix 6684 6685 Notes: 6686 Most users should employ the KSP interface for linear solvers 6687 instead of working directly with matrix algebra routines such as this. 6688 See, e.g., KSPCreate(). 6689 6690 Level: developer 6691 6692 Concepts: matrices^symbolic incomplete Cholesky factorization 6693 Concepts: matrices^factorization 6694 Concepts: Cholsky^symbolic factorization 6695 6696 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6697 6698 Developer Note: fortran interface is not autogenerated as the f90 6699 interface defintion cannot be generated correctly [due to MatFactorInfo] 6700 6701 @*/ 6702 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6703 { 6704 PetscErrorCode ierr; 6705 6706 PetscFunctionBegin; 6707 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6708 PetscValidType(mat,1); 6709 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6710 PetscValidPointer(info,3); 6711 PetscValidPointer(fact,4); 6712 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6713 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6714 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6715 if (!(fact)->ops->iccfactorsymbolic) { 6716 MatSolverType spackage; 6717 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6718 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6719 } 6720 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6721 MatCheckPreallocated(mat,2); 6722 6723 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6724 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6725 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6726 PetscFunctionReturn(0); 6727 } 6728 6729 /*@C 6730 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6731 points to an array of valid matrices, they may be reused to store the new 6732 submatrices. 6733 6734 Collective on Mat 6735 6736 Input Parameters: 6737 + mat - the matrix 6738 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6739 . irow, icol - index sets of rows and columns to extract 6740 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6741 6742 Output Parameter: 6743 . submat - the array of submatrices 6744 6745 Notes: 6746 MatCreateSubMatrices() can extract ONLY sequential submatrices 6747 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6748 to extract a parallel submatrix. 6749 6750 Some matrix types place restrictions on the row and column 6751 indices, such as that they be sorted or that they be equal to each other. 6752 6753 The index sets may not have duplicate entries. 6754 6755 When extracting submatrices from a parallel matrix, each processor can 6756 form a different submatrix by setting the rows and columns of its 6757 individual index sets according to the local submatrix desired. 6758 6759 When finished using the submatrices, the user should destroy 6760 them with MatDestroySubMatrices(). 6761 6762 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6763 original matrix has not changed from that last call to MatCreateSubMatrices(). 6764 6765 This routine creates the matrices in submat; you should NOT create them before 6766 calling it. It also allocates the array of matrix pointers submat. 6767 6768 For BAIJ matrices the index sets must respect the block structure, that is if they 6769 request one row/column in a block, they must request all rows/columns that are in 6770 that block. For example, if the block size is 2 you cannot request just row 0 and 6771 column 0. 6772 6773 Fortran Note: 6774 The Fortran interface is slightly different from that given below; it 6775 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6776 6777 Level: advanced 6778 6779 Concepts: matrices^accessing submatrices 6780 Concepts: submatrices 6781 6782 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6783 @*/ 6784 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6785 { 6786 PetscErrorCode ierr; 6787 PetscInt i; 6788 PetscBool eq; 6789 6790 PetscFunctionBegin; 6791 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6792 PetscValidType(mat,1); 6793 if (n) { 6794 PetscValidPointer(irow,3); 6795 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6796 PetscValidPointer(icol,4); 6797 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6798 } 6799 PetscValidPointer(submat,6); 6800 if (n && scall == MAT_REUSE_MATRIX) { 6801 PetscValidPointer(*submat,6); 6802 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6803 } 6804 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6805 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6806 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6807 MatCheckPreallocated(mat,1); 6808 6809 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6810 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6811 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6812 for (i=0; i<n; i++) { 6813 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6814 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6815 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6816 if (eq) { 6817 if (mat->symmetric) { 6818 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6819 } else if (mat->hermitian) { 6820 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6821 } else if (mat->structurally_symmetric) { 6822 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6823 } 6824 } 6825 } 6826 } 6827 PetscFunctionReturn(0); 6828 } 6829 6830 /*@C 6831 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6832 6833 Collective on Mat 6834 6835 Input Parameters: 6836 + mat - the matrix 6837 . n - the number of submatrixes to be extracted 6838 . irow, icol - index sets of rows and columns to extract 6839 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6840 6841 Output Parameter: 6842 . submat - the array of submatrices 6843 6844 Level: advanced 6845 6846 Concepts: matrices^accessing submatrices 6847 Concepts: submatrices 6848 6849 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6850 @*/ 6851 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6852 { 6853 PetscErrorCode ierr; 6854 PetscInt i; 6855 PetscBool eq; 6856 6857 PetscFunctionBegin; 6858 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6859 PetscValidType(mat,1); 6860 if (n) { 6861 PetscValidPointer(irow,3); 6862 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6863 PetscValidPointer(icol,4); 6864 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6865 } 6866 PetscValidPointer(submat,6); 6867 if (n && scall == MAT_REUSE_MATRIX) { 6868 PetscValidPointer(*submat,6); 6869 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6870 } 6871 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6872 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6873 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6874 MatCheckPreallocated(mat,1); 6875 6876 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6877 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6878 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6879 for (i=0; i<n; i++) { 6880 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6881 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6882 if (eq) { 6883 if (mat->symmetric) { 6884 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6885 } else if (mat->hermitian) { 6886 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6887 } else if (mat->structurally_symmetric) { 6888 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6889 } 6890 } 6891 } 6892 } 6893 PetscFunctionReturn(0); 6894 } 6895 6896 /*@C 6897 MatDestroyMatrices - Destroys an array of matrices. 6898 6899 Collective on Mat 6900 6901 Input Parameters: 6902 + n - the number of local matrices 6903 - mat - the matrices (note that this is a pointer to the array of matrices) 6904 6905 Level: advanced 6906 6907 Notes: 6908 Frees not only the matrices, but also the array that contains the matrices 6909 In Fortran will not free the array. 6910 6911 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6912 @*/ 6913 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6914 { 6915 PetscErrorCode ierr; 6916 PetscInt i; 6917 6918 PetscFunctionBegin; 6919 if (!*mat) PetscFunctionReturn(0); 6920 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6921 PetscValidPointer(mat,2); 6922 6923 for (i=0; i<n; i++) { 6924 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6925 } 6926 6927 /* memory is allocated even if n = 0 */ 6928 ierr = PetscFree(*mat);CHKERRQ(ierr); 6929 PetscFunctionReturn(0); 6930 } 6931 6932 /*@C 6933 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 6934 6935 Collective on Mat 6936 6937 Input Parameters: 6938 + n - the number of local matrices 6939 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6940 sequence of MatCreateSubMatrices()) 6941 6942 Level: advanced 6943 6944 Notes: 6945 Frees not only the matrices, but also the array that contains the matrices 6946 In Fortran will not free the array. 6947 6948 .seealso: MatCreateSubMatrices() 6949 @*/ 6950 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 6951 { 6952 PetscErrorCode ierr; 6953 Mat mat0; 6954 6955 PetscFunctionBegin; 6956 if (!*mat) PetscFunctionReturn(0); 6957 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6958 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6959 PetscValidPointer(mat,2); 6960 6961 mat0 = (*mat)[0]; 6962 if (mat0 && mat0->ops->destroysubmatrices) { 6963 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 6964 } else { 6965 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 6966 } 6967 PetscFunctionReturn(0); 6968 } 6969 6970 /*@C 6971 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6972 6973 Collective on Mat 6974 6975 Input Parameters: 6976 . mat - the matrix 6977 6978 Output Parameter: 6979 . matstruct - the sequential matrix with the nonzero structure of mat 6980 6981 Level: intermediate 6982 6983 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 6984 @*/ 6985 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6986 { 6987 PetscErrorCode ierr; 6988 6989 PetscFunctionBegin; 6990 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6991 PetscValidPointer(matstruct,2); 6992 6993 PetscValidType(mat,1); 6994 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6995 MatCheckPreallocated(mat,1); 6996 6997 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 6998 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6999 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 7000 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7001 PetscFunctionReturn(0); 7002 } 7003 7004 /*@C 7005 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7006 7007 Collective on Mat 7008 7009 Input Parameters: 7010 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7011 sequence of MatGetSequentialNonzeroStructure()) 7012 7013 Level: advanced 7014 7015 Notes: 7016 Frees not only the matrices, but also the array that contains the matrices 7017 7018 .seealso: MatGetSeqNonzeroStructure() 7019 @*/ 7020 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7021 { 7022 PetscErrorCode ierr; 7023 7024 PetscFunctionBegin; 7025 PetscValidPointer(mat,1); 7026 ierr = MatDestroy(mat);CHKERRQ(ierr); 7027 PetscFunctionReturn(0); 7028 } 7029 7030 /*@ 7031 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7032 replaces the index sets by larger ones that represent submatrices with 7033 additional overlap. 7034 7035 Collective on Mat 7036 7037 Input Parameters: 7038 + mat - the matrix 7039 . n - the number of index sets 7040 . is - the array of index sets (these index sets will changed during the call) 7041 - ov - the additional overlap requested 7042 7043 Options Database: 7044 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7045 7046 Level: developer 7047 7048 Concepts: overlap 7049 Concepts: ASM^computing overlap 7050 7051 .seealso: MatCreateSubMatrices() 7052 @*/ 7053 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7054 { 7055 PetscErrorCode ierr; 7056 7057 PetscFunctionBegin; 7058 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7059 PetscValidType(mat,1); 7060 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7061 if (n) { 7062 PetscValidPointer(is,3); 7063 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7064 } 7065 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7066 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7067 MatCheckPreallocated(mat,1); 7068 7069 if (!ov) PetscFunctionReturn(0); 7070 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7071 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7072 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 7073 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7074 PetscFunctionReturn(0); 7075 } 7076 7077 7078 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7079 7080 /*@ 7081 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7082 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7083 additional overlap. 7084 7085 Collective on Mat 7086 7087 Input Parameters: 7088 + mat - the matrix 7089 . n - the number of index sets 7090 . is - the array of index sets (these index sets will changed during the call) 7091 - ov - the additional overlap requested 7092 7093 Options Database: 7094 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7095 7096 Level: developer 7097 7098 Concepts: overlap 7099 Concepts: ASM^computing overlap 7100 7101 .seealso: MatCreateSubMatrices() 7102 @*/ 7103 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7104 { 7105 PetscInt i; 7106 PetscErrorCode ierr; 7107 7108 PetscFunctionBegin; 7109 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7110 PetscValidType(mat,1); 7111 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7112 if (n) { 7113 PetscValidPointer(is,3); 7114 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7115 } 7116 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7117 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7118 MatCheckPreallocated(mat,1); 7119 if (!ov) PetscFunctionReturn(0); 7120 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7121 for(i=0; i<n; i++){ 7122 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7123 } 7124 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7125 PetscFunctionReturn(0); 7126 } 7127 7128 7129 7130 7131 /*@ 7132 MatGetBlockSize - Returns the matrix block size. 7133 7134 Not Collective 7135 7136 Input Parameter: 7137 . mat - the matrix 7138 7139 Output Parameter: 7140 . bs - block size 7141 7142 Notes: 7143 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7144 7145 If the block size has not been set yet this routine returns 1. 7146 7147 Level: intermediate 7148 7149 Concepts: matrices^block size 7150 7151 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7152 @*/ 7153 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7154 { 7155 PetscFunctionBegin; 7156 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7157 PetscValidIntPointer(bs,2); 7158 *bs = PetscAbs(mat->rmap->bs); 7159 PetscFunctionReturn(0); 7160 } 7161 7162 /*@ 7163 MatGetBlockSizes - Returns the matrix block row and column sizes. 7164 7165 Not Collective 7166 7167 Input Parameter: 7168 . mat - the matrix 7169 7170 Output Parameter: 7171 . rbs - row block size 7172 . cbs - column block size 7173 7174 Notes: 7175 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7176 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7177 7178 If a block size has not been set yet this routine returns 1. 7179 7180 Level: intermediate 7181 7182 Concepts: matrices^block size 7183 7184 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7185 @*/ 7186 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7187 { 7188 PetscFunctionBegin; 7189 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7190 if (rbs) PetscValidIntPointer(rbs,2); 7191 if (cbs) PetscValidIntPointer(cbs,3); 7192 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7193 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7194 PetscFunctionReturn(0); 7195 } 7196 7197 /*@ 7198 MatSetBlockSize - Sets the matrix block size. 7199 7200 Logically Collective on Mat 7201 7202 Input Parameters: 7203 + mat - the matrix 7204 - bs - block size 7205 7206 Notes: 7207 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7208 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7209 7210 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7211 is compatible with the matrix local sizes. 7212 7213 Level: intermediate 7214 7215 Concepts: matrices^block size 7216 7217 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7218 @*/ 7219 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7220 { 7221 PetscErrorCode ierr; 7222 7223 PetscFunctionBegin; 7224 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7225 PetscValidLogicalCollectiveInt(mat,bs,2); 7226 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7227 PetscFunctionReturn(0); 7228 } 7229 7230 /*@ 7231 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7232 7233 Logically Collective on Mat 7234 7235 Input Parameters: 7236 + mat - the matrix 7237 . nblocks - the number of blocks on this process 7238 - bsizes - the block sizes 7239 7240 Notes: 7241 Currently used by PCVPBJACOBI for SeqAIJ matrices 7242 7243 Level: intermediate 7244 7245 Concepts: matrices^block size 7246 7247 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7248 @*/ 7249 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7250 { 7251 PetscErrorCode ierr; 7252 PetscInt i,ncnt = 0, nlocal; 7253 7254 PetscFunctionBegin; 7255 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7256 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7257 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7258 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7259 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); 7260 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7261 mat->nblocks = nblocks; 7262 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7263 ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr); 7264 PetscFunctionReturn(0); 7265 } 7266 7267 /*@C 7268 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7269 7270 Logically Collective on Mat 7271 7272 Input Parameters: 7273 . mat - the matrix 7274 7275 Output Parameters: 7276 + nblocks - the number of blocks on this process 7277 - bsizes - the block sizes 7278 7279 Notes: Currently not supported from Fortran 7280 7281 Level: intermediate 7282 7283 Concepts: matrices^block size 7284 7285 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7286 @*/ 7287 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7288 { 7289 PetscFunctionBegin; 7290 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7291 *nblocks = mat->nblocks; 7292 *bsizes = mat->bsizes; 7293 PetscFunctionReturn(0); 7294 } 7295 7296 /*@ 7297 MatSetBlockSizes - Sets the matrix block row and column sizes. 7298 7299 Logically Collective on Mat 7300 7301 Input Parameters: 7302 + mat - the matrix 7303 - rbs - row block size 7304 - cbs - column block size 7305 7306 Notes: 7307 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7308 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7309 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7310 7311 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7312 are compatible with the matrix local sizes. 7313 7314 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7315 7316 Level: intermediate 7317 7318 Concepts: matrices^block size 7319 7320 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7321 @*/ 7322 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7323 { 7324 PetscErrorCode ierr; 7325 7326 PetscFunctionBegin; 7327 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7328 PetscValidLogicalCollectiveInt(mat,rbs,2); 7329 PetscValidLogicalCollectiveInt(mat,cbs,3); 7330 if (mat->ops->setblocksizes) { 7331 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7332 } 7333 if (mat->rmap->refcnt) { 7334 ISLocalToGlobalMapping l2g = NULL; 7335 PetscLayout nmap = NULL; 7336 7337 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7338 if (mat->rmap->mapping) { 7339 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7340 } 7341 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7342 mat->rmap = nmap; 7343 mat->rmap->mapping = l2g; 7344 } 7345 if (mat->cmap->refcnt) { 7346 ISLocalToGlobalMapping l2g = NULL; 7347 PetscLayout nmap = NULL; 7348 7349 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7350 if (mat->cmap->mapping) { 7351 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7352 } 7353 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7354 mat->cmap = nmap; 7355 mat->cmap->mapping = l2g; 7356 } 7357 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7358 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7359 PetscFunctionReturn(0); 7360 } 7361 7362 /*@ 7363 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7364 7365 Logically Collective on Mat 7366 7367 Input Parameters: 7368 + mat - the matrix 7369 . fromRow - matrix from which to copy row block size 7370 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7371 7372 Level: developer 7373 7374 Concepts: matrices^block size 7375 7376 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7377 @*/ 7378 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7379 { 7380 PetscErrorCode ierr; 7381 7382 PetscFunctionBegin; 7383 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7384 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7385 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7386 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7387 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7388 PetscFunctionReturn(0); 7389 } 7390 7391 /*@ 7392 MatResidual - Default routine to calculate the residual. 7393 7394 Collective on Mat and Vec 7395 7396 Input Parameters: 7397 + mat - the matrix 7398 . b - the right-hand-side 7399 - x - the approximate solution 7400 7401 Output Parameter: 7402 . r - location to store the residual 7403 7404 Level: developer 7405 7406 .keywords: MG, default, multigrid, residual 7407 7408 .seealso: PCMGSetResidual() 7409 @*/ 7410 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7411 { 7412 PetscErrorCode ierr; 7413 7414 PetscFunctionBegin; 7415 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7416 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7417 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7418 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7419 PetscValidType(mat,1); 7420 MatCheckPreallocated(mat,1); 7421 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7422 if (!mat->ops->residual) { 7423 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7424 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7425 } else { 7426 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7427 } 7428 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7429 PetscFunctionReturn(0); 7430 } 7431 7432 /*@C 7433 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7434 7435 Collective on Mat 7436 7437 Input Parameters: 7438 + mat - the matrix 7439 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7440 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7441 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7442 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7443 always used. 7444 7445 Output Parameters: 7446 + n - number of rows in the (possibly compressed) matrix 7447 . ia - the row pointers [of length n+1] 7448 . ja - the column indices 7449 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7450 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7451 7452 Level: developer 7453 7454 Notes: 7455 You CANNOT change any of the ia[] or ja[] values. 7456 7457 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7458 7459 Fortran Notes: 7460 In Fortran use 7461 $ 7462 $ PetscInt ia(1), ja(1) 7463 $ PetscOffset iia, jja 7464 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7465 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7466 7467 or 7468 $ 7469 $ PetscInt, pointer :: ia(:),ja(:) 7470 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7471 $ ! Access the ith and jth entries via ia(i) and ja(j) 7472 7473 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7474 @*/ 7475 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7476 { 7477 PetscErrorCode ierr; 7478 7479 PetscFunctionBegin; 7480 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7481 PetscValidType(mat,1); 7482 PetscValidIntPointer(n,5); 7483 if (ia) PetscValidIntPointer(ia,6); 7484 if (ja) PetscValidIntPointer(ja,7); 7485 PetscValidIntPointer(done,8); 7486 MatCheckPreallocated(mat,1); 7487 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7488 else { 7489 *done = PETSC_TRUE; 7490 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7491 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7492 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7493 } 7494 PetscFunctionReturn(0); 7495 } 7496 7497 /*@C 7498 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7499 7500 Collective on Mat 7501 7502 Input Parameters: 7503 + mat - the matrix 7504 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7505 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7506 symmetrized 7507 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7508 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7509 always used. 7510 . n - number of columns in the (possibly compressed) matrix 7511 . ia - the column pointers 7512 - ja - the row indices 7513 7514 Output Parameters: 7515 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7516 7517 Note: 7518 This routine zeros out n, ia, and ja. This is to prevent accidental 7519 us of the array after it has been restored. If you pass NULL, it will 7520 not zero the pointers. Use of ia or ja after MatRestoreColumnIJ() is invalid. 7521 7522 Level: developer 7523 7524 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7525 @*/ 7526 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7527 { 7528 PetscErrorCode ierr; 7529 7530 PetscFunctionBegin; 7531 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7532 PetscValidType(mat,1); 7533 PetscValidIntPointer(n,4); 7534 if (ia) PetscValidIntPointer(ia,5); 7535 if (ja) PetscValidIntPointer(ja,6); 7536 PetscValidIntPointer(done,7); 7537 MatCheckPreallocated(mat,1); 7538 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7539 else { 7540 *done = PETSC_TRUE; 7541 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7542 } 7543 PetscFunctionReturn(0); 7544 } 7545 7546 /*@C 7547 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7548 MatGetRowIJ(). 7549 7550 Collective on Mat 7551 7552 Input Parameters: 7553 + mat - the matrix 7554 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7555 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7556 symmetrized 7557 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7558 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7559 always used. 7560 . n - size of (possibly compressed) matrix 7561 . ia - the row pointers 7562 - ja - the column indices 7563 7564 Output Parameters: 7565 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7566 7567 Note: 7568 This routine zeros out n, ia, and ja. This is to prevent accidental 7569 us of the array after it has been restored. If you pass NULL, it will 7570 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7571 7572 Level: developer 7573 7574 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7575 @*/ 7576 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7577 { 7578 PetscErrorCode ierr; 7579 7580 PetscFunctionBegin; 7581 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7582 PetscValidType(mat,1); 7583 if (ia) PetscValidIntPointer(ia,6); 7584 if (ja) PetscValidIntPointer(ja,7); 7585 PetscValidIntPointer(done,8); 7586 MatCheckPreallocated(mat,1); 7587 7588 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7589 else { 7590 *done = PETSC_TRUE; 7591 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7592 if (n) *n = 0; 7593 if (ia) *ia = NULL; 7594 if (ja) *ja = NULL; 7595 } 7596 PetscFunctionReturn(0); 7597 } 7598 7599 /*@C 7600 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7601 MatGetColumnIJ(). 7602 7603 Collective on Mat 7604 7605 Input Parameters: 7606 + mat - the matrix 7607 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7608 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7609 symmetrized 7610 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7611 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7612 always used. 7613 7614 Output Parameters: 7615 + n - size of (possibly compressed) matrix 7616 . ia - the column pointers 7617 . ja - the row indices 7618 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7619 7620 Level: developer 7621 7622 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7623 @*/ 7624 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7625 { 7626 PetscErrorCode ierr; 7627 7628 PetscFunctionBegin; 7629 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7630 PetscValidType(mat,1); 7631 if (ia) PetscValidIntPointer(ia,5); 7632 if (ja) PetscValidIntPointer(ja,6); 7633 PetscValidIntPointer(done,7); 7634 MatCheckPreallocated(mat,1); 7635 7636 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7637 else { 7638 *done = PETSC_TRUE; 7639 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7640 if (n) *n = 0; 7641 if (ia) *ia = NULL; 7642 if (ja) *ja = NULL; 7643 } 7644 PetscFunctionReturn(0); 7645 } 7646 7647 /*@C 7648 MatColoringPatch -Used inside matrix coloring routines that 7649 use MatGetRowIJ() and/or MatGetColumnIJ(). 7650 7651 Collective on Mat 7652 7653 Input Parameters: 7654 + mat - the matrix 7655 . ncolors - max color value 7656 . n - number of entries in colorarray 7657 - colorarray - array indicating color for each column 7658 7659 Output Parameters: 7660 . iscoloring - coloring generated using colorarray information 7661 7662 Level: developer 7663 7664 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7665 7666 @*/ 7667 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7668 { 7669 PetscErrorCode ierr; 7670 7671 PetscFunctionBegin; 7672 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7673 PetscValidType(mat,1); 7674 PetscValidIntPointer(colorarray,4); 7675 PetscValidPointer(iscoloring,5); 7676 MatCheckPreallocated(mat,1); 7677 7678 if (!mat->ops->coloringpatch) { 7679 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7680 } else { 7681 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7682 } 7683 PetscFunctionReturn(0); 7684 } 7685 7686 7687 /*@ 7688 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7689 7690 Logically Collective on Mat 7691 7692 Input Parameter: 7693 . mat - the factored matrix to be reset 7694 7695 Notes: 7696 This routine should be used only with factored matrices formed by in-place 7697 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7698 format). This option can save memory, for example, when solving nonlinear 7699 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7700 ILU(0) preconditioner. 7701 7702 Note that one can specify in-place ILU(0) factorization by calling 7703 .vb 7704 PCType(pc,PCILU); 7705 PCFactorSeUseInPlace(pc); 7706 .ve 7707 or by using the options -pc_type ilu -pc_factor_in_place 7708 7709 In-place factorization ILU(0) can also be used as a local 7710 solver for the blocks within the block Jacobi or additive Schwarz 7711 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7712 for details on setting local solver options. 7713 7714 Most users should employ the simplified KSP interface for linear solvers 7715 instead of working directly with matrix algebra routines such as this. 7716 See, e.g., KSPCreate(). 7717 7718 Level: developer 7719 7720 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7721 7722 Concepts: matrices^unfactored 7723 7724 @*/ 7725 PetscErrorCode MatSetUnfactored(Mat mat) 7726 { 7727 PetscErrorCode ierr; 7728 7729 PetscFunctionBegin; 7730 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7731 PetscValidType(mat,1); 7732 MatCheckPreallocated(mat,1); 7733 mat->factortype = MAT_FACTOR_NONE; 7734 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7735 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7736 PetscFunctionReturn(0); 7737 } 7738 7739 /*MC 7740 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7741 7742 Synopsis: 7743 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7744 7745 Not collective 7746 7747 Input Parameter: 7748 . x - matrix 7749 7750 Output Parameters: 7751 + xx_v - the Fortran90 pointer to the array 7752 - ierr - error code 7753 7754 Example of Usage: 7755 .vb 7756 PetscScalar, pointer xx_v(:,:) 7757 .... 7758 call MatDenseGetArrayF90(x,xx_v,ierr) 7759 a = xx_v(3) 7760 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7761 .ve 7762 7763 Level: advanced 7764 7765 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7766 7767 Concepts: matrices^accessing array 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 Concepts: matrices^accessing array 7832 7833 M*/ 7834 7835 /*MC 7836 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7837 accessed with MatSeqAIJGetArrayF90(). 7838 7839 Synopsis: 7840 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7841 7842 Not collective 7843 7844 Input Parameters: 7845 + x - matrix 7846 - xx_v - the Fortran90 pointer to the array 7847 7848 Output Parameter: 7849 . ierr - error code 7850 7851 Example of Usage: 7852 .vb 7853 PetscScalar, pointer xx_v(:) 7854 .... 7855 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7856 a = xx_v(3) 7857 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7858 .ve 7859 7860 Level: advanced 7861 7862 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7863 7864 M*/ 7865 7866 7867 /*@ 7868 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7869 as the original matrix. 7870 7871 Collective on Mat 7872 7873 Input Parameters: 7874 + mat - the original matrix 7875 . isrow - parallel IS containing the rows this processor should obtain 7876 . 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. 7877 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7878 7879 Output Parameter: 7880 . newmat - the new submatrix, of the same type as the old 7881 7882 Level: advanced 7883 7884 Notes: 7885 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7886 7887 Some matrix types place restrictions on the row and column indices, such 7888 as that they be sorted or that they be equal to each other. 7889 7890 The index sets may not have duplicate entries. 7891 7892 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7893 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7894 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7895 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7896 you are finished using it. 7897 7898 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7899 the input matrix. 7900 7901 If iscol is NULL then all columns are obtained (not supported in Fortran). 7902 7903 Example usage: 7904 Consider the following 8x8 matrix with 34 non-zero values, that is 7905 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7906 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7907 as follows: 7908 7909 .vb 7910 1 2 0 | 0 3 0 | 0 4 7911 Proc0 0 5 6 | 7 0 0 | 8 0 7912 9 0 10 | 11 0 0 | 12 0 7913 ------------------------------------- 7914 13 0 14 | 15 16 17 | 0 0 7915 Proc1 0 18 0 | 19 20 21 | 0 0 7916 0 0 0 | 22 23 0 | 24 0 7917 ------------------------------------- 7918 Proc2 25 26 27 | 0 0 28 | 29 0 7919 30 0 0 | 31 32 33 | 0 34 7920 .ve 7921 7922 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7923 7924 .vb 7925 2 0 | 0 3 0 | 0 7926 Proc0 5 6 | 7 0 0 | 8 7927 ------------------------------- 7928 Proc1 18 0 | 19 20 21 | 0 7929 ------------------------------- 7930 Proc2 26 27 | 0 0 28 | 29 7931 0 0 | 31 32 33 | 0 7932 .ve 7933 7934 7935 Concepts: matrices^submatrices 7936 7937 .seealso: MatCreateSubMatrices() 7938 @*/ 7939 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7940 { 7941 PetscErrorCode ierr; 7942 PetscMPIInt size; 7943 Mat *local; 7944 IS iscoltmp; 7945 7946 PetscFunctionBegin; 7947 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7948 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7949 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7950 PetscValidPointer(newmat,5); 7951 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7952 PetscValidType(mat,1); 7953 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7954 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7955 7956 MatCheckPreallocated(mat,1); 7957 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7958 7959 if (!iscol || isrow == iscol) { 7960 PetscBool stride; 7961 PetscMPIInt grabentirematrix = 0,grab; 7962 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7963 if (stride) { 7964 PetscInt first,step,n,rstart,rend; 7965 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7966 if (step == 1) { 7967 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7968 if (rstart == first) { 7969 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7970 if (n == rend-rstart) { 7971 grabentirematrix = 1; 7972 } 7973 } 7974 } 7975 } 7976 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 7977 if (grab) { 7978 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 7979 if (cll == MAT_INITIAL_MATRIX) { 7980 *newmat = mat; 7981 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 7982 } 7983 PetscFunctionReturn(0); 7984 } 7985 } 7986 7987 if (!iscol) { 7988 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7989 } else { 7990 iscoltmp = iscol; 7991 } 7992 7993 /* if original matrix is on just one processor then use submatrix generated */ 7994 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7995 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7996 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7997 PetscFunctionReturn(0); 7998 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 7999 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 8000 *newmat = *local; 8001 ierr = PetscFree(local);CHKERRQ(ierr); 8002 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8003 PetscFunctionReturn(0); 8004 } else if (!mat->ops->createsubmatrix) { 8005 /* Create a new matrix type that implements the operation using the full matrix */ 8006 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8007 switch (cll) { 8008 case MAT_INITIAL_MATRIX: 8009 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 8010 break; 8011 case MAT_REUSE_MATRIX: 8012 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 8013 break; 8014 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8015 } 8016 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8017 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8018 PetscFunctionReturn(0); 8019 } 8020 8021 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8022 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8023 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 8024 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8025 8026 /* Propagate symmetry information for diagonal blocks */ 8027 if (isrow == iscoltmp) { 8028 if (mat->symmetric_set && mat->symmetric) { 8029 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8030 } 8031 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 8032 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8033 } 8034 if (mat->hermitian_set && mat->hermitian) { 8035 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 8036 } 8037 if (mat->spd_set && mat->spd) { 8038 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 8039 } 8040 } 8041 8042 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8043 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 8044 PetscFunctionReturn(0); 8045 } 8046 8047 /*@ 8048 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8049 used during the assembly process to store values that belong to 8050 other processors. 8051 8052 Not Collective 8053 8054 Input Parameters: 8055 + mat - the matrix 8056 . size - the initial size of the stash. 8057 - bsize - the initial size of the block-stash(if used). 8058 8059 Options Database Keys: 8060 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8061 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8062 8063 Level: intermediate 8064 8065 Notes: 8066 The block-stash is used for values set with MatSetValuesBlocked() while 8067 the stash is used for values set with MatSetValues() 8068 8069 Run with the option -info and look for output of the form 8070 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8071 to determine the appropriate value, MM, to use for size and 8072 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8073 to determine the value, BMM to use for bsize 8074 8075 Concepts: stash^setting matrix size 8076 Concepts: matrices^stash 8077 8078 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 8079 8080 @*/ 8081 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8082 { 8083 PetscErrorCode ierr; 8084 8085 PetscFunctionBegin; 8086 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8087 PetscValidType(mat,1); 8088 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 8089 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 8090 PetscFunctionReturn(0); 8091 } 8092 8093 /*@ 8094 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8095 the matrix 8096 8097 Neighbor-wise Collective on Mat 8098 8099 Input Parameters: 8100 + mat - the matrix 8101 . x,y - the vectors 8102 - w - where the result is stored 8103 8104 Level: intermediate 8105 8106 Notes: 8107 w may be the same vector as y. 8108 8109 This allows one to use either the restriction or interpolation (its transpose) 8110 matrix to do the interpolation 8111 8112 Concepts: interpolation 8113 8114 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8115 8116 @*/ 8117 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8118 { 8119 PetscErrorCode ierr; 8120 PetscInt M,N,Ny; 8121 8122 PetscFunctionBegin; 8123 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8124 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8125 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8126 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8127 PetscValidType(A,1); 8128 MatCheckPreallocated(A,1); 8129 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8130 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8131 if (M == Ny) { 8132 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8133 } else { 8134 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8135 } 8136 PetscFunctionReturn(0); 8137 } 8138 8139 /*@ 8140 MatInterpolate - y = A*x or A'*x depending on the shape of 8141 the matrix 8142 8143 Neighbor-wise Collective on Mat 8144 8145 Input Parameters: 8146 + mat - the matrix 8147 - x,y - the vectors 8148 8149 Level: intermediate 8150 8151 Notes: 8152 This allows one to use either the restriction or interpolation (its transpose) 8153 matrix to do the interpolation 8154 8155 Concepts: matrices^interpolation 8156 8157 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8158 8159 @*/ 8160 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8161 { 8162 PetscErrorCode ierr; 8163 PetscInt M,N,Ny; 8164 8165 PetscFunctionBegin; 8166 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8167 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8168 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8169 PetscValidType(A,1); 8170 MatCheckPreallocated(A,1); 8171 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8172 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8173 if (M == Ny) { 8174 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8175 } else { 8176 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8177 } 8178 PetscFunctionReturn(0); 8179 } 8180 8181 /*@ 8182 MatRestrict - y = A*x or A'*x 8183 8184 Neighbor-wise Collective on Mat 8185 8186 Input Parameters: 8187 + mat - the matrix 8188 - x,y - the vectors 8189 8190 Level: intermediate 8191 8192 Notes: 8193 This allows one to use either the restriction or interpolation (its transpose) 8194 matrix to do the restriction 8195 8196 Concepts: matrices^restriction 8197 8198 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8199 8200 @*/ 8201 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8202 { 8203 PetscErrorCode ierr; 8204 PetscInt M,N,Ny; 8205 8206 PetscFunctionBegin; 8207 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8208 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8209 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8210 PetscValidType(A,1); 8211 MatCheckPreallocated(A,1); 8212 8213 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8214 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8215 if (M == Ny) { 8216 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8217 } else { 8218 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8219 } 8220 PetscFunctionReturn(0); 8221 } 8222 8223 /*@ 8224 MatGetNullSpace - retrieves the null space of a matrix. 8225 8226 Logically Collective on Mat and MatNullSpace 8227 8228 Input Parameters: 8229 + mat - the matrix 8230 - nullsp - the null space object 8231 8232 Level: developer 8233 8234 Concepts: null space^attaching to matrix 8235 8236 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8237 @*/ 8238 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8239 { 8240 PetscFunctionBegin; 8241 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8242 PetscValidPointer(nullsp,2); 8243 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8244 PetscFunctionReturn(0); 8245 } 8246 8247 /*@ 8248 MatSetNullSpace - attaches a null space to a matrix. 8249 8250 Logically Collective on Mat and MatNullSpace 8251 8252 Input Parameters: 8253 + mat - the matrix 8254 - nullsp - the null space object 8255 8256 Level: advanced 8257 8258 Notes: 8259 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8260 8261 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8262 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8263 8264 You can remove the null space by calling this routine with an nullsp of NULL 8265 8266 8267 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8268 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). 8269 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 8270 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 8271 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). 8272 8273 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8274 8275 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 8276 routine also automatically calls MatSetTransposeNullSpace(). 8277 8278 Concepts: null space^attaching to matrix 8279 8280 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8281 @*/ 8282 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8283 { 8284 PetscErrorCode ierr; 8285 8286 PetscFunctionBegin; 8287 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8288 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8289 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8290 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8291 mat->nullsp = nullsp; 8292 if (mat->symmetric_set && mat->symmetric) { 8293 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8294 } 8295 PetscFunctionReturn(0); 8296 } 8297 8298 /*@ 8299 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8300 8301 Logically Collective on Mat and MatNullSpace 8302 8303 Input Parameters: 8304 + mat - the matrix 8305 - nullsp - the null space object 8306 8307 Level: developer 8308 8309 Concepts: null space^attaching to matrix 8310 8311 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8312 @*/ 8313 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8314 { 8315 PetscFunctionBegin; 8316 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8317 PetscValidType(mat,1); 8318 PetscValidPointer(nullsp,2); 8319 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8320 PetscFunctionReturn(0); 8321 } 8322 8323 /*@ 8324 MatSetTransposeNullSpace - attaches a null space to a matrix. 8325 8326 Logically Collective on Mat and MatNullSpace 8327 8328 Input Parameters: 8329 + mat - the matrix 8330 - nullsp - the null space object 8331 8332 Level: advanced 8333 8334 Notes: 8335 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. 8336 You must also call MatSetNullSpace() 8337 8338 8339 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8340 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). 8341 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 8342 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 8343 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). 8344 8345 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8346 8347 Concepts: null space^attaching to matrix 8348 8349 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8350 @*/ 8351 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8352 { 8353 PetscErrorCode ierr; 8354 8355 PetscFunctionBegin; 8356 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8357 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8358 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8359 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8360 mat->transnullsp = nullsp; 8361 PetscFunctionReturn(0); 8362 } 8363 8364 /*@ 8365 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8366 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8367 8368 Logically Collective on Mat and MatNullSpace 8369 8370 Input Parameters: 8371 + mat - the matrix 8372 - nullsp - the null space object 8373 8374 Level: advanced 8375 8376 Notes: 8377 Overwrites any previous near null space that may have been attached 8378 8379 You can remove the null space by calling this routine with an nullsp of NULL 8380 8381 Concepts: null space^attaching to matrix 8382 8383 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8384 @*/ 8385 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8386 { 8387 PetscErrorCode ierr; 8388 8389 PetscFunctionBegin; 8390 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8391 PetscValidType(mat,1); 8392 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8393 MatCheckPreallocated(mat,1); 8394 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8395 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8396 mat->nearnullsp = nullsp; 8397 PetscFunctionReturn(0); 8398 } 8399 8400 /*@ 8401 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8402 8403 Not Collective 8404 8405 Input Parameters: 8406 . mat - the matrix 8407 8408 Output Parameters: 8409 . nullsp - the null space object, NULL if not set 8410 8411 Level: developer 8412 8413 Concepts: null space^attaching to matrix 8414 8415 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8416 @*/ 8417 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8418 { 8419 PetscFunctionBegin; 8420 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8421 PetscValidType(mat,1); 8422 PetscValidPointer(nullsp,2); 8423 MatCheckPreallocated(mat,1); 8424 *nullsp = mat->nearnullsp; 8425 PetscFunctionReturn(0); 8426 } 8427 8428 /*@C 8429 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8430 8431 Collective on Mat 8432 8433 Input Parameters: 8434 + mat - the matrix 8435 . row - row/column permutation 8436 . fill - expected fill factor >= 1.0 8437 - level - level of fill, for ICC(k) 8438 8439 Notes: 8440 Probably really in-place only when level of fill is zero, otherwise allocates 8441 new space to store factored matrix and deletes previous memory. 8442 8443 Most users should employ the simplified KSP interface for linear solvers 8444 instead of working directly with matrix algebra routines such as this. 8445 See, e.g., KSPCreate(). 8446 8447 Level: developer 8448 8449 Concepts: matrices^incomplete Cholesky factorization 8450 Concepts: Cholesky factorization 8451 8452 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8453 8454 Developer Note: fortran interface is not autogenerated as the f90 8455 interface defintion cannot be generated correctly [due to MatFactorInfo] 8456 8457 @*/ 8458 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8459 { 8460 PetscErrorCode ierr; 8461 8462 PetscFunctionBegin; 8463 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8464 PetscValidType(mat,1); 8465 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8466 PetscValidPointer(info,3); 8467 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8468 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8469 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8470 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8471 MatCheckPreallocated(mat,1); 8472 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8473 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8474 PetscFunctionReturn(0); 8475 } 8476 8477 /*@ 8478 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8479 ghosted ones. 8480 8481 Not Collective 8482 8483 Input Parameters: 8484 + mat - the matrix 8485 - diag = the diagonal values, including ghost ones 8486 8487 Level: developer 8488 8489 Notes: 8490 Works only for MPIAIJ and MPIBAIJ matrices 8491 8492 .seealso: MatDiagonalScale() 8493 @*/ 8494 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8495 { 8496 PetscErrorCode ierr; 8497 PetscMPIInt size; 8498 8499 PetscFunctionBegin; 8500 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8501 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8502 PetscValidType(mat,1); 8503 8504 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8505 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8506 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8507 if (size == 1) { 8508 PetscInt n,m; 8509 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8510 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8511 if (m == n) { 8512 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8513 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8514 } else { 8515 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8516 } 8517 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8518 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8519 PetscFunctionReturn(0); 8520 } 8521 8522 /*@ 8523 MatGetInertia - Gets the inertia from a factored matrix 8524 8525 Collective on Mat 8526 8527 Input Parameter: 8528 . mat - the matrix 8529 8530 Output Parameters: 8531 + nneg - number of negative eigenvalues 8532 . nzero - number of zero eigenvalues 8533 - npos - number of positive eigenvalues 8534 8535 Level: advanced 8536 8537 Notes: 8538 Matrix must have been factored by MatCholeskyFactor() 8539 8540 8541 @*/ 8542 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8543 { 8544 PetscErrorCode ierr; 8545 8546 PetscFunctionBegin; 8547 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8548 PetscValidType(mat,1); 8549 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8550 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8551 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8552 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8553 PetscFunctionReturn(0); 8554 } 8555 8556 /* ----------------------------------------------------------------*/ 8557 /*@C 8558 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8559 8560 Neighbor-wise Collective on Mat and Vecs 8561 8562 Input Parameters: 8563 + mat - the factored matrix 8564 - b - the right-hand-side vectors 8565 8566 Output Parameter: 8567 . x - the result vectors 8568 8569 Notes: 8570 The vectors b and x cannot be the same. I.e., one cannot 8571 call MatSolves(A,x,x). 8572 8573 Notes: 8574 Most users should employ the simplified KSP interface for linear solvers 8575 instead of working directly with matrix algebra routines such as this. 8576 See, e.g., KSPCreate(). 8577 8578 Level: developer 8579 8580 Concepts: matrices^triangular solves 8581 8582 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8583 @*/ 8584 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8585 { 8586 PetscErrorCode ierr; 8587 8588 PetscFunctionBegin; 8589 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8590 PetscValidType(mat,1); 8591 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8592 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8593 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8594 8595 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8596 MatCheckPreallocated(mat,1); 8597 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8598 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8599 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8600 PetscFunctionReturn(0); 8601 } 8602 8603 /*@ 8604 MatIsSymmetric - Test whether a matrix is symmetric 8605 8606 Collective on Mat 8607 8608 Input Parameter: 8609 + A - the matrix to test 8610 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8611 8612 Output Parameters: 8613 . flg - the result 8614 8615 Notes: 8616 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8617 8618 Level: intermediate 8619 8620 Concepts: matrix^symmetry 8621 8622 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8623 @*/ 8624 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8625 { 8626 PetscErrorCode ierr; 8627 8628 PetscFunctionBegin; 8629 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8630 PetscValidPointer(flg,2); 8631 8632 if (!A->symmetric_set) { 8633 if (!A->ops->issymmetric) { 8634 MatType mattype; 8635 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8636 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8637 } 8638 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8639 if (!tol) { 8640 A->symmetric_set = PETSC_TRUE; 8641 A->symmetric = *flg; 8642 if (A->symmetric) { 8643 A->structurally_symmetric_set = PETSC_TRUE; 8644 A->structurally_symmetric = PETSC_TRUE; 8645 } 8646 } 8647 } else if (A->symmetric) { 8648 *flg = PETSC_TRUE; 8649 } else if (!tol) { 8650 *flg = PETSC_FALSE; 8651 } else { 8652 if (!A->ops->issymmetric) { 8653 MatType mattype; 8654 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8655 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8656 } 8657 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8658 } 8659 PetscFunctionReturn(0); 8660 } 8661 8662 /*@ 8663 MatIsHermitian - Test whether a matrix is Hermitian 8664 8665 Collective on Mat 8666 8667 Input Parameter: 8668 + A - the matrix to test 8669 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8670 8671 Output Parameters: 8672 . flg - the result 8673 8674 Level: intermediate 8675 8676 Concepts: matrix^symmetry 8677 8678 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8679 MatIsSymmetricKnown(), MatIsSymmetric() 8680 @*/ 8681 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8682 { 8683 PetscErrorCode ierr; 8684 8685 PetscFunctionBegin; 8686 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8687 PetscValidPointer(flg,2); 8688 8689 if (!A->hermitian_set) { 8690 if (!A->ops->ishermitian) { 8691 MatType mattype; 8692 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8693 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8694 } 8695 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8696 if (!tol) { 8697 A->hermitian_set = PETSC_TRUE; 8698 A->hermitian = *flg; 8699 if (A->hermitian) { 8700 A->structurally_symmetric_set = PETSC_TRUE; 8701 A->structurally_symmetric = PETSC_TRUE; 8702 } 8703 } 8704 } else if (A->hermitian) { 8705 *flg = PETSC_TRUE; 8706 } else if (!tol) { 8707 *flg = PETSC_FALSE; 8708 } else { 8709 if (!A->ops->ishermitian) { 8710 MatType mattype; 8711 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8712 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8713 } 8714 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8715 } 8716 PetscFunctionReturn(0); 8717 } 8718 8719 /*@ 8720 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8721 8722 Not Collective 8723 8724 Input Parameter: 8725 . A - the matrix to check 8726 8727 Output Parameters: 8728 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8729 - flg - the result 8730 8731 Level: advanced 8732 8733 Concepts: matrix^symmetry 8734 8735 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8736 if you want it explicitly checked 8737 8738 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8739 @*/ 8740 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8741 { 8742 PetscFunctionBegin; 8743 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8744 PetscValidPointer(set,2); 8745 PetscValidPointer(flg,3); 8746 if (A->symmetric_set) { 8747 *set = PETSC_TRUE; 8748 *flg = A->symmetric; 8749 } else { 8750 *set = PETSC_FALSE; 8751 } 8752 PetscFunctionReturn(0); 8753 } 8754 8755 /*@ 8756 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8757 8758 Not Collective 8759 8760 Input Parameter: 8761 . A - the matrix to check 8762 8763 Output Parameters: 8764 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8765 - flg - the result 8766 8767 Level: advanced 8768 8769 Concepts: matrix^symmetry 8770 8771 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8772 if you want it explicitly checked 8773 8774 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8775 @*/ 8776 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8777 { 8778 PetscFunctionBegin; 8779 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8780 PetscValidPointer(set,2); 8781 PetscValidPointer(flg,3); 8782 if (A->hermitian_set) { 8783 *set = PETSC_TRUE; 8784 *flg = A->hermitian; 8785 } else { 8786 *set = PETSC_FALSE; 8787 } 8788 PetscFunctionReturn(0); 8789 } 8790 8791 /*@ 8792 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8793 8794 Collective on Mat 8795 8796 Input Parameter: 8797 . A - the matrix to test 8798 8799 Output Parameters: 8800 . flg - the result 8801 8802 Level: intermediate 8803 8804 Concepts: matrix^symmetry 8805 8806 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8807 @*/ 8808 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8809 { 8810 PetscErrorCode ierr; 8811 8812 PetscFunctionBegin; 8813 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8814 PetscValidPointer(flg,2); 8815 if (!A->structurally_symmetric_set) { 8816 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8817 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8818 8819 A->structurally_symmetric_set = PETSC_TRUE; 8820 } 8821 *flg = A->structurally_symmetric; 8822 PetscFunctionReturn(0); 8823 } 8824 8825 /*@ 8826 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8827 to be communicated to other processors during the MatAssemblyBegin/End() process 8828 8829 Not collective 8830 8831 Input Parameter: 8832 . vec - the vector 8833 8834 Output Parameters: 8835 + nstash - the size of the stash 8836 . reallocs - the number of additional mallocs incurred. 8837 . bnstash - the size of the block stash 8838 - breallocs - the number of additional mallocs incurred.in the block stash 8839 8840 Level: advanced 8841 8842 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8843 8844 @*/ 8845 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8846 { 8847 PetscErrorCode ierr; 8848 8849 PetscFunctionBegin; 8850 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8851 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8852 PetscFunctionReturn(0); 8853 } 8854 8855 /*@C 8856 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8857 parallel layout 8858 8859 Collective on Mat 8860 8861 Input Parameter: 8862 . mat - the matrix 8863 8864 Output Parameter: 8865 + right - (optional) vector that the matrix can be multiplied against 8866 - left - (optional) vector that the matrix vector product can be stored in 8867 8868 Notes: 8869 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(). 8870 8871 Notes: 8872 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8873 8874 Level: advanced 8875 8876 .seealso: MatCreate(), VecDestroy() 8877 @*/ 8878 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8879 { 8880 PetscErrorCode ierr; 8881 8882 PetscFunctionBegin; 8883 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8884 PetscValidType(mat,1); 8885 if (mat->ops->getvecs) { 8886 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8887 } else { 8888 PetscInt rbs,cbs; 8889 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8890 if (right) { 8891 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8892 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8893 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8894 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8895 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8896 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8897 } 8898 if (left) { 8899 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8900 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8901 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8902 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8903 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8904 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8905 } 8906 } 8907 PetscFunctionReturn(0); 8908 } 8909 8910 /*@C 8911 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8912 with default values. 8913 8914 Not Collective 8915 8916 Input Parameters: 8917 . info - the MatFactorInfo data structure 8918 8919 8920 Notes: 8921 The solvers are generally used through the KSP and PC objects, for example 8922 PCLU, PCILU, PCCHOLESKY, PCICC 8923 8924 Level: developer 8925 8926 .seealso: MatFactorInfo 8927 8928 Developer Note: fortran interface is not autogenerated as the f90 8929 interface defintion cannot be generated correctly [due to MatFactorInfo] 8930 8931 @*/ 8932 8933 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8934 { 8935 PetscErrorCode ierr; 8936 8937 PetscFunctionBegin; 8938 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8939 PetscFunctionReturn(0); 8940 } 8941 8942 /*@ 8943 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 8944 8945 Collective on Mat 8946 8947 Input Parameters: 8948 + mat - the factored matrix 8949 - is - the index set defining the Schur indices (0-based) 8950 8951 Notes: 8952 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 8953 8954 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 8955 8956 Level: developer 8957 8958 Concepts: 8959 8960 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 8961 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 8962 8963 @*/ 8964 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8965 { 8966 PetscErrorCode ierr,(*f)(Mat,IS); 8967 8968 PetscFunctionBegin; 8969 PetscValidType(mat,1); 8970 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8971 PetscValidType(is,2); 8972 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8973 PetscCheckSameComm(mat,1,is,2); 8974 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8975 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8976 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"); 8977 if (mat->schur) { 8978 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 8979 } 8980 ierr = (*f)(mat,is);CHKERRQ(ierr); 8981 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 8982 ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr); 8983 PetscFunctionReturn(0); 8984 } 8985 8986 /*@ 8987 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8988 8989 Logically Collective on Mat 8990 8991 Input Parameters: 8992 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8993 . S - location where to return the Schur complement, can be NULL 8994 - status - the status of the Schur complement matrix, can be NULL 8995 8996 Notes: 8997 You must call MatFactorSetSchurIS() before calling this routine. 8998 8999 The routine provides a copy of the Schur matrix stored within the solver data structures. 9000 The caller must destroy the object when it is no longer needed. 9001 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9002 9003 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) 9004 9005 Developer Notes: 9006 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9007 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9008 9009 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9010 9011 Level: advanced 9012 9013 References: 9014 9015 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 9016 @*/ 9017 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9018 { 9019 PetscErrorCode ierr; 9020 9021 PetscFunctionBegin; 9022 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9023 if (S) PetscValidPointer(S,2); 9024 if (status) PetscValidPointer(status,3); 9025 if (S) { 9026 PetscErrorCode (*f)(Mat,Mat*); 9027 9028 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 9029 if (f) { 9030 ierr = (*f)(F,S);CHKERRQ(ierr); 9031 } else { 9032 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 9033 } 9034 } 9035 if (status) *status = F->schur_status; 9036 PetscFunctionReturn(0); 9037 } 9038 9039 /*@ 9040 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9041 9042 Logically Collective on Mat 9043 9044 Input Parameters: 9045 + F - the factored matrix obtained by calling MatGetFactor() 9046 . *S - location where to return the Schur complement, can be NULL 9047 - status - the status of the Schur complement matrix, can be NULL 9048 9049 Notes: 9050 You must call MatFactorSetSchurIS() before calling this routine. 9051 9052 Schur complement mode is currently implemented for sequential matrices. 9053 The routine returns a the Schur Complement stored within the data strutures of the solver. 9054 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9055 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9056 9057 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9058 9059 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9060 9061 Level: advanced 9062 9063 References: 9064 9065 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9066 @*/ 9067 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9068 { 9069 PetscFunctionBegin; 9070 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9071 if (S) PetscValidPointer(S,2); 9072 if (status) PetscValidPointer(status,3); 9073 if (S) *S = F->schur; 9074 if (status) *status = F->schur_status; 9075 PetscFunctionReturn(0); 9076 } 9077 9078 /*@ 9079 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9080 9081 Logically Collective on Mat 9082 9083 Input Parameters: 9084 + F - the factored matrix obtained by calling MatGetFactor() 9085 . *S - location where the Schur complement is stored 9086 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9087 9088 Notes: 9089 9090 Level: advanced 9091 9092 References: 9093 9094 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9095 @*/ 9096 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9097 { 9098 PetscErrorCode ierr; 9099 9100 PetscFunctionBegin; 9101 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9102 if (S) { 9103 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9104 *S = NULL; 9105 } 9106 F->schur_status = status; 9107 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 9108 PetscFunctionReturn(0); 9109 } 9110 9111 /*@ 9112 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9113 9114 Logically Collective on Mat 9115 9116 Input Parameters: 9117 + F - the factored matrix obtained by calling MatGetFactor() 9118 . rhs - location where the right hand side of the Schur complement system is stored 9119 - sol - location where the solution of the Schur complement system has to be returned 9120 9121 Notes: 9122 The sizes of the vectors should match the size of the Schur complement 9123 9124 Must be called after MatFactorSetSchurIS() 9125 9126 Level: advanced 9127 9128 References: 9129 9130 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 9131 @*/ 9132 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9133 { 9134 PetscErrorCode ierr; 9135 9136 PetscFunctionBegin; 9137 PetscValidType(F,1); 9138 PetscValidType(rhs,2); 9139 PetscValidType(sol,3); 9140 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9141 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9142 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9143 PetscCheckSameComm(F,1,rhs,2); 9144 PetscCheckSameComm(F,1,sol,3); 9145 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9146 switch (F->schur_status) { 9147 case MAT_FACTOR_SCHUR_FACTORED: 9148 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9149 break; 9150 case MAT_FACTOR_SCHUR_INVERTED: 9151 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9152 break; 9153 default: 9154 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9155 break; 9156 } 9157 PetscFunctionReturn(0); 9158 } 9159 9160 /*@ 9161 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9162 9163 Logically Collective on Mat 9164 9165 Input Parameters: 9166 + F - the factored matrix obtained by calling MatGetFactor() 9167 . rhs - location where the right hand side of the Schur complement system is stored 9168 - sol - location where the solution of the Schur complement system has to be returned 9169 9170 Notes: 9171 The sizes of the vectors should match the size of the Schur complement 9172 9173 Must be called after MatFactorSetSchurIS() 9174 9175 Level: advanced 9176 9177 References: 9178 9179 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9180 @*/ 9181 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9182 { 9183 PetscErrorCode ierr; 9184 9185 PetscFunctionBegin; 9186 PetscValidType(F,1); 9187 PetscValidType(rhs,2); 9188 PetscValidType(sol,3); 9189 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9190 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9191 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9192 PetscCheckSameComm(F,1,rhs,2); 9193 PetscCheckSameComm(F,1,sol,3); 9194 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9195 switch (F->schur_status) { 9196 case MAT_FACTOR_SCHUR_FACTORED: 9197 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9198 break; 9199 case MAT_FACTOR_SCHUR_INVERTED: 9200 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9201 break; 9202 default: 9203 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9204 break; 9205 } 9206 PetscFunctionReturn(0); 9207 } 9208 9209 /*@ 9210 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9211 9212 Logically Collective on Mat 9213 9214 Input Parameters: 9215 + F - the factored matrix obtained by calling MatGetFactor() 9216 9217 Notes: 9218 Must be called after MatFactorSetSchurIS(). 9219 9220 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9221 9222 Level: advanced 9223 9224 References: 9225 9226 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9227 @*/ 9228 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9229 { 9230 PetscErrorCode ierr; 9231 9232 PetscFunctionBegin; 9233 PetscValidType(F,1); 9234 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9235 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9236 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9237 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9238 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9239 PetscFunctionReturn(0); 9240 } 9241 9242 /*@ 9243 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9244 9245 Logically Collective on Mat 9246 9247 Input Parameters: 9248 + F - the factored matrix obtained by calling MatGetFactor() 9249 9250 Notes: 9251 Must be called after MatFactorSetSchurIS(). 9252 9253 Level: advanced 9254 9255 References: 9256 9257 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9258 @*/ 9259 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9260 { 9261 PetscErrorCode ierr; 9262 9263 PetscFunctionBegin; 9264 PetscValidType(F,1); 9265 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9266 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9267 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9268 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9269 PetscFunctionReturn(0); 9270 } 9271 9272 /*@ 9273 MatPtAP - Creates the matrix product C = P^T * A * P 9274 9275 Neighbor-wise Collective on Mat 9276 9277 Input Parameters: 9278 + A - the matrix 9279 . P - the projection matrix 9280 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9281 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9282 if the result is a dense matrix this is irrelevent 9283 9284 Output Parameters: 9285 . C - the product matrix 9286 9287 Notes: 9288 C will be created and must be destroyed by the user with MatDestroy(). 9289 9290 This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes 9291 which inherit from AIJ. 9292 9293 Level: intermediate 9294 9295 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9296 @*/ 9297 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9298 { 9299 PetscErrorCode ierr; 9300 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9301 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9302 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9303 PetscBool sametype; 9304 9305 PetscFunctionBegin; 9306 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9307 PetscValidType(A,1); 9308 MatCheckPreallocated(A,1); 9309 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9310 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9311 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9312 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9313 PetscValidType(P,2); 9314 MatCheckPreallocated(P,2); 9315 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9316 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9317 9318 if (A->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N); 9319 if (P->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 9320 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9321 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9322 9323 if (scall == MAT_REUSE_MATRIX) { 9324 PetscValidPointer(*C,5); 9325 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9326 9327 if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX"); 9328 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9329 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9330 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9331 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9332 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9333 PetscFunctionReturn(0); 9334 } 9335 9336 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9337 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9338 9339 fA = A->ops->ptap; 9340 fP = P->ops->ptap; 9341 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9342 if (fP == fA && sametype) { 9343 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 9344 ptap = fA; 9345 } else { 9346 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9347 char ptapname[256]; 9348 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9349 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9350 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9351 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9352 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9353 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9354 if (!ptap) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s (Misses composed function %s)",((PetscObject)A)->type_name,((PetscObject)P)->type_name,ptapname); 9355 } 9356 9357 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9358 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9359 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9360 if (A->symmetric_set && A->symmetric) { 9361 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9362 } 9363 PetscFunctionReturn(0); 9364 } 9365 9366 /*@ 9367 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9368 9369 Neighbor-wise Collective on Mat 9370 9371 Input Parameters: 9372 + A - the matrix 9373 - P - the projection matrix 9374 9375 Output Parameters: 9376 . C - the product matrix 9377 9378 Notes: 9379 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9380 the user using MatDeatroy(). 9381 9382 This routine is currently only implemented for pairs of AIJ matrices and classes 9383 which inherit from AIJ. C will be of type MATAIJ. 9384 9385 Level: intermediate 9386 9387 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9388 @*/ 9389 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9390 { 9391 PetscErrorCode ierr; 9392 9393 PetscFunctionBegin; 9394 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9395 PetscValidType(A,1); 9396 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9397 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9398 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9399 PetscValidType(P,2); 9400 MatCheckPreallocated(P,2); 9401 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9402 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9403 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9404 PetscValidType(C,3); 9405 MatCheckPreallocated(C,3); 9406 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9407 if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N); 9408 if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 9409 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9410 if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N); 9411 MatCheckPreallocated(A,1); 9412 9413 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9414 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9415 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9416 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9417 PetscFunctionReturn(0); 9418 } 9419 9420 /*@ 9421 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9422 9423 Neighbor-wise Collective on Mat 9424 9425 Input Parameters: 9426 + A - the matrix 9427 - P - the projection matrix 9428 9429 Output Parameters: 9430 . C - the (i,j) structure of the product matrix 9431 9432 Notes: 9433 C will be created and must be destroyed by the user with MatDestroy(). 9434 9435 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9436 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9437 this (i,j) structure by calling MatPtAPNumeric(). 9438 9439 Level: intermediate 9440 9441 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9442 @*/ 9443 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9444 { 9445 PetscErrorCode ierr; 9446 9447 PetscFunctionBegin; 9448 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9449 PetscValidType(A,1); 9450 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9451 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9452 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9453 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9454 PetscValidType(P,2); 9455 MatCheckPreallocated(P,2); 9456 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9457 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9458 PetscValidPointer(C,3); 9459 9460 if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 9461 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9462 MatCheckPreallocated(A,1); 9463 9464 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9465 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9466 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9467 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9468 9469 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9470 PetscFunctionReturn(0); 9471 } 9472 9473 /*@ 9474 MatRARt - Creates the matrix product C = R * A * R^T 9475 9476 Neighbor-wise Collective on Mat 9477 9478 Input Parameters: 9479 + A - the matrix 9480 . R - the projection matrix 9481 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9482 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9483 if the result is a dense matrix this is irrelevent 9484 9485 Output Parameters: 9486 . C - the product matrix 9487 9488 Notes: 9489 C will be created and must be destroyed by the user with MatDestroy(). 9490 9491 This routine is currently only implemented for pairs of AIJ matrices and classes 9492 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9493 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9494 We recommend using MatPtAP(). 9495 9496 Level: intermediate 9497 9498 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9499 @*/ 9500 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9501 { 9502 PetscErrorCode ierr; 9503 9504 PetscFunctionBegin; 9505 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9506 PetscValidType(A,1); 9507 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9508 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9509 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9510 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9511 PetscValidType(R,2); 9512 MatCheckPreallocated(R,2); 9513 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9514 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9515 PetscValidPointer(C,3); 9516 if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 9517 9518 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9519 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9520 MatCheckPreallocated(A,1); 9521 9522 if (!A->ops->rart) { 9523 Mat Rt; 9524 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9525 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9526 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9527 PetscFunctionReturn(0); 9528 } 9529 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9530 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9531 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9532 PetscFunctionReturn(0); 9533 } 9534 9535 /*@ 9536 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9537 9538 Neighbor-wise Collective on Mat 9539 9540 Input Parameters: 9541 + A - the matrix 9542 - R - the projection matrix 9543 9544 Output Parameters: 9545 . C - the product matrix 9546 9547 Notes: 9548 C must have been created by calling MatRARtSymbolic and must be destroyed by 9549 the user using MatDestroy(). 9550 9551 This routine is currently only implemented for pairs of AIJ matrices and classes 9552 which inherit from AIJ. C will be of type MATAIJ. 9553 9554 Level: intermediate 9555 9556 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9557 @*/ 9558 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9559 { 9560 PetscErrorCode ierr; 9561 9562 PetscFunctionBegin; 9563 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9564 PetscValidType(A,1); 9565 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9566 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9567 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9568 PetscValidType(R,2); 9569 MatCheckPreallocated(R,2); 9570 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9571 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9572 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9573 PetscValidType(C,3); 9574 MatCheckPreallocated(C,3); 9575 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9576 if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N); 9577 if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 9578 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9579 if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N); 9580 MatCheckPreallocated(A,1); 9581 9582 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9583 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9584 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9585 PetscFunctionReturn(0); 9586 } 9587 9588 /*@ 9589 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9590 9591 Neighbor-wise Collective on Mat 9592 9593 Input Parameters: 9594 + A - the matrix 9595 - R - the projection matrix 9596 9597 Output Parameters: 9598 . C - the (i,j) structure of the product matrix 9599 9600 Notes: 9601 C will be created and must be destroyed by the user with MatDestroy(). 9602 9603 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9604 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9605 this (i,j) structure by calling MatRARtNumeric(). 9606 9607 Level: intermediate 9608 9609 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9610 @*/ 9611 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9612 { 9613 PetscErrorCode ierr; 9614 9615 PetscFunctionBegin; 9616 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9617 PetscValidType(A,1); 9618 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9619 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9620 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9621 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9622 PetscValidType(R,2); 9623 MatCheckPreallocated(R,2); 9624 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9625 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9626 PetscValidPointer(C,3); 9627 9628 if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 9629 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9630 MatCheckPreallocated(A,1); 9631 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9632 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9633 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9634 9635 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9636 PetscFunctionReturn(0); 9637 } 9638 9639 /*@ 9640 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9641 9642 Neighbor-wise Collective on Mat 9643 9644 Input Parameters: 9645 + A - the left matrix 9646 . B - the right matrix 9647 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9648 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9649 if the result is a dense matrix this is irrelevent 9650 9651 Output Parameters: 9652 . C - the product matrix 9653 9654 Notes: 9655 Unless scall is MAT_REUSE_MATRIX C will be created. 9656 9657 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 9658 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9659 9660 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9661 actually needed. 9662 9663 If you have many matrices with the same non-zero structure to multiply, you 9664 should either 9665 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9666 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9667 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 9668 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9669 9670 Level: intermediate 9671 9672 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9673 @*/ 9674 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9675 { 9676 PetscErrorCode ierr; 9677 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9678 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9679 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9680 9681 PetscFunctionBegin; 9682 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9683 PetscValidType(A,1); 9684 MatCheckPreallocated(A,1); 9685 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9686 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9687 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9688 PetscValidType(B,2); 9689 MatCheckPreallocated(B,2); 9690 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9691 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9692 PetscValidPointer(C,3); 9693 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9694 if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 9695 if (scall == MAT_REUSE_MATRIX) { 9696 PetscValidPointer(*C,5); 9697 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9698 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9699 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9700 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9701 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9702 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9703 PetscFunctionReturn(0); 9704 } 9705 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9706 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9707 9708 fA = A->ops->matmult; 9709 fB = B->ops->matmult; 9710 if (fB == fA) { 9711 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9712 mult = fB; 9713 } else { 9714 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9715 char multname[256]; 9716 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9717 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9718 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9719 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9720 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9721 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9722 if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9723 } 9724 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9725 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9726 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9727 PetscFunctionReturn(0); 9728 } 9729 9730 /*@ 9731 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9732 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9733 9734 Neighbor-wise Collective on Mat 9735 9736 Input Parameters: 9737 + A - the left matrix 9738 . B - the right matrix 9739 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9740 if C is a dense matrix this is irrelevent 9741 9742 Output Parameters: 9743 . C - the product matrix 9744 9745 Notes: 9746 Unless scall is MAT_REUSE_MATRIX C will be created. 9747 9748 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9749 actually needed. 9750 9751 This routine is currently implemented for 9752 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9753 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9754 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9755 9756 Level: intermediate 9757 9758 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 9759 We should incorporate them into PETSc. 9760 9761 .seealso: MatMatMult(), MatMatMultNumeric() 9762 @*/ 9763 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9764 { 9765 PetscErrorCode ierr; 9766 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9767 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9768 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9769 9770 PetscFunctionBegin; 9771 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9772 PetscValidType(A,1); 9773 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9774 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9775 9776 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9777 PetscValidType(B,2); 9778 MatCheckPreallocated(B,2); 9779 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9780 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9781 PetscValidPointer(C,3); 9782 9783 if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 9784 if (fill == PETSC_DEFAULT) fill = 2.0; 9785 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9786 MatCheckPreallocated(A,1); 9787 9788 Asymbolic = A->ops->matmultsymbolic; 9789 Bsymbolic = B->ops->matmultsymbolic; 9790 if (Asymbolic == Bsymbolic) { 9791 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9792 symbolic = Bsymbolic; 9793 } else { /* dispatch based on the type of A and B */ 9794 char symbolicname[256]; 9795 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9796 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9797 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9798 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9799 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9800 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9801 if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9802 } 9803 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9804 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9805 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9806 PetscFunctionReturn(0); 9807 } 9808 9809 /*@ 9810 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9811 Call this routine after first calling MatMatMultSymbolic(). 9812 9813 Neighbor-wise Collective on Mat 9814 9815 Input Parameters: 9816 + A - the left matrix 9817 - B - the right matrix 9818 9819 Output Parameters: 9820 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9821 9822 Notes: 9823 C must have been created with MatMatMultSymbolic(). 9824 9825 This routine is currently implemented for 9826 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9827 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9828 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9829 9830 Level: intermediate 9831 9832 .seealso: MatMatMult(), MatMatMultSymbolic() 9833 @*/ 9834 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9835 { 9836 PetscErrorCode ierr; 9837 9838 PetscFunctionBegin; 9839 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9840 PetscFunctionReturn(0); 9841 } 9842 9843 /*@ 9844 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9845 9846 Neighbor-wise Collective on Mat 9847 9848 Input Parameters: 9849 + A - the left matrix 9850 . B - the right matrix 9851 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9852 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9853 9854 Output Parameters: 9855 . C - the product matrix 9856 9857 Notes: 9858 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9859 9860 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9861 9862 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9863 actually needed. 9864 9865 This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class. 9866 9867 Level: intermediate 9868 9869 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9870 @*/ 9871 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9872 { 9873 PetscErrorCode ierr; 9874 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9875 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9876 9877 PetscFunctionBegin; 9878 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9879 PetscValidType(A,1); 9880 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9881 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9882 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9883 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9884 PetscValidType(B,2); 9885 MatCheckPreallocated(B,2); 9886 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9887 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9888 PetscValidPointer(C,3); 9889 if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N); 9890 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9891 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9892 MatCheckPreallocated(A,1); 9893 9894 fA = A->ops->mattransposemult; 9895 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9896 fB = B->ops->mattransposemult; 9897 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9898 if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9899 9900 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9901 if (scall == MAT_INITIAL_MATRIX) { 9902 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9903 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9904 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9905 } 9906 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9907 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9908 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9909 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9910 PetscFunctionReturn(0); 9911 } 9912 9913 /*@ 9914 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9915 9916 Neighbor-wise Collective on Mat 9917 9918 Input Parameters: 9919 + A - the left matrix 9920 . B - the right matrix 9921 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9922 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9923 9924 Output Parameters: 9925 . C - the product matrix 9926 9927 Notes: 9928 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9929 9930 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9931 9932 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9933 actually needed. 9934 9935 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9936 which inherit from SeqAIJ. C will be of same type as the input matrices. 9937 9938 Level: intermediate 9939 9940 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 9941 @*/ 9942 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9943 { 9944 PetscErrorCode ierr; 9945 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9946 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9947 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 9948 9949 PetscFunctionBegin; 9950 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9951 PetscValidType(A,1); 9952 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9953 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9954 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9955 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9956 PetscValidType(B,2); 9957 MatCheckPreallocated(B,2); 9958 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9959 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9960 PetscValidPointer(C,3); 9961 if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N); 9962 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9963 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9964 MatCheckPreallocated(A,1); 9965 9966 fA = A->ops->transposematmult; 9967 fB = B->ops->transposematmult; 9968 if (fB==fA) { 9969 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9970 transposematmult = fA; 9971 } else { 9972 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9973 char multname[256]; 9974 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 9975 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9976 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9977 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9978 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9979 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 9980 if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9981 } 9982 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9983 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 9984 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9985 PetscFunctionReturn(0); 9986 } 9987 9988 /*@ 9989 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9990 9991 Neighbor-wise Collective on Mat 9992 9993 Input Parameters: 9994 + A - the left matrix 9995 . B - the middle matrix 9996 . C - the right matrix 9997 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9998 - 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 9999 if the result is a dense matrix this is irrelevent 10000 10001 Output Parameters: 10002 . D - the product matrix 10003 10004 Notes: 10005 Unless scall is MAT_REUSE_MATRIX D will be created. 10006 10007 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10008 10009 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10010 actually needed. 10011 10012 If you have many matrices with the same non-zero structure to multiply, you 10013 should use MAT_REUSE_MATRIX in all calls but the first or 10014 10015 Level: intermediate 10016 10017 .seealso: MatMatMult, MatPtAP() 10018 @*/ 10019 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10020 { 10021 PetscErrorCode ierr; 10022 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10023 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10024 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10025 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 10026 10027 PetscFunctionBegin; 10028 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10029 PetscValidType(A,1); 10030 MatCheckPreallocated(A,1); 10031 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10032 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10033 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10034 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10035 PetscValidType(B,2); 10036 MatCheckPreallocated(B,2); 10037 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10038 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10039 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10040 PetscValidPointer(C,3); 10041 MatCheckPreallocated(C,3); 10042 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10043 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10044 if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 10045 if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N); 10046 if (scall == MAT_REUSE_MATRIX) { 10047 PetscValidPointer(*D,6); 10048 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 10049 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10050 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10051 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10052 PetscFunctionReturn(0); 10053 } 10054 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10055 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 10056 10057 fA = A->ops->matmatmult; 10058 fB = B->ops->matmatmult; 10059 fC = C->ops->matmatmult; 10060 if (fA == fB && fA == fC) { 10061 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 10062 mult = fA; 10063 } else { 10064 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 10065 char multname[256]; 10066 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 10067 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10068 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10069 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10070 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10071 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 10072 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 10073 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 10074 if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name); 10075 } 10076 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10077 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10078 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10079 PetscFunctionReturn(0); 10080 } 10081 10082 /*@ 10083 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10084 10085 Collective on Mat 10086 10087 Input Parameters: 10088 + mat - the matrix 10089 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10090 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10091 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10092 10093 Output Parameter: 10094 . matredundant - redundant matrix 10095 10096 Notes: 10097 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10098 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10099 10100 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 10101 calling it. 10102 10103 Level: advanced 10104 10105 Concepts: subcommunicator 10106 Concepts: duplicate matrix 10107 10108 .seealso: MatDestroy() 10109 @*/ 10110 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10111 { 10112 PetscErrorCode ierr; 10113 MPI_Comm comm; 10114 PetscMPIInt size; 10115 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10116 Mat_Redundant *redund=NULL; 10117 PetscSubcomm psubcomm=NULL; 10118 MPI_Comm subcomm_in=subcomm; 10119 Mat *matseq; 10120 IS isrow,iscol; 10121 PetscBool newsubcomm=PETSC_FALSE; 10122 10123 PetscFunctionBegin; 10124 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10125 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10126 PetscValidPointer(*matredundant,5); 10127 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10128 } 10129 10130 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10131 if (size == 1 || nsubcomm == 1) { 10132 if (reuse == MAT_INITIAL_MATRIX) { 10133 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10134 } else { 10135 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"); 10136 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10137 } 10138 PetscFunctionReturn(0); 10139 } 10140 10141 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10142 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10143 MatCheckPreallocated(mat,1); 10144 10145 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10146 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10147 /* create psubcomm, then get subcomm */ 10148 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10149 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10150 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10151 10152 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10153 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10154 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10155 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10156 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10157 newsubcomm = PETSC_TRUE; 10158 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10159 } 10160 10161 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10162 if (reuse == MAT_INITIAL_MATRIX) { 10163 mloc_sub = PETSC_DECIDE; 10164 nloc_sub = PETSC_DECIDE; 10165 if (bs < 1) { 10166 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10167 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10168 } else { 10169 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10170 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10171 } 10172 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10173 rstart = rend - mloc_sub; 10174 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10175 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10176 } else { /* reuse == MAT_REUSE_MATRIX */ 10177 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"); 10178 /* retrieve subcomm */ 10179 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10180 redund = (*matredundant)->redundant; 10181 isrow = redund->isrow; 10182 iscol = redund->iscol; 10183 matseq = redund->matseq; 10184 } 10185 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10186 10187 /* get matredundant over subcomm */ 10188 if (reuse == MAT_INITIAL_MATRIX) { 10189 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10190 10191 /* create a supporting struct and attach it to C for reuse */ 10192 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10193 (*matredundant)->redundant = redund; 10194 redund->isrow = isrow; 10195 redund->iscol = iscol; 10196 redund->matseq = matseq; 10197 if (newsubcomm) { 10198 redund->subcomm = subcomm; 10199 } else { 10200 redund->subcomm = MPI_COMM_NULL; 10201 } 10202 } else { 10203 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10204 } 10205 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10206 PetscFunctionReturn(0); 10207 } 10208 10209 /*@C 10210 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10211 a given 'mat' object. Each submatrix can span multiple procs. 10212 10213 Collective on Mat 10214 10215 Input Parameters: 10216 + mat - the matrix 10217 . subcomm - the subcommunicator obtained by com_split(comm) 10218 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10219 10220 Output Parameter: 10221 . subMat - 'parallel submatrices each spans a given subcomm 10222 10223 Notes: 10224 The submatrix partition across processors is dictated by 'subComm' a 10225 communicator obtained by com_split(comm). The comm_split 10226 is not restriced to be grouped with consecutive original ranks. 10227 10228 Due the comm_split() usage, the parallel layout of the submatrices 10229 map directly to the layout of the original matrix [wrt the local 10230 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10231 into the 'DiagonalMat' of the subMat, hence it is used directly from 10232 the subMat. However the offDiagMat looses some columns - and this is 10233 reconstructed with MatSetValues() 10234 10235 Level: advanced 10236 10237 Concepts: subcommunicator 10238 Concepts: submatrices 10239 10240 .seealso: MatCreateSubMatrices() 10241 @*/ 10242 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10243 { 10244 PetscErrorCode ierr; 10245 PetscMPIInt commsize,subCommSize; 10246 10247 PetscFunctionBegin; 10248 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10249 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10250 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10251 10252 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"); 10253 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10254 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10255 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10256 PetscFunctionReturn(0); 10257 } 10258 10259 /*@ 10260 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10261 10262 Not Collective 10263 10264 Input Arguments: 10265 mat - matrix to extract local submatrix from 10266 isrow - local row indices for submatrix 10267 iscol - local column indices for submatrix 10268 10269 Output Arguments: 10270 submat - the submatrix 10271 10272 Level: intermediate 10273 10274 Notes: 10275 The submat should be returned with MatRestoreLocalSubMatrix(). 10276 10277 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10278 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10279 10280 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10281 MatSetValuesBlockedLocal() will also be implemented. 10282 10283 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10284 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10285 10286 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10287 @*/ 10288 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10289 { 10290 PetscErrorCode ierr; 10291 10292 PetscFunctionBegin; 10293 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10294 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10295 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10296 PetscCheckSameComm(isrow,2,iscol,3); 10297 PetscValidPointer(submat,4); 10298 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10299 10300 if (mat->ops->getlocalsubmatrix) { 10301 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10302 } else { 10303 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10304 } 10305 PetscFunctionReturn(0); 10306 } 10307 10308 /*@ 10309 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10310 10311 Not Collective 10312 10313 Input Arguments: 10314 mat - matrix to extract local submatrix from 10315 isrow - local row indices for submatrix 10316 iscol - local column indices for submatrix 10317 submat - the submatrix 10318 10319 Level: intermediate 10320 10321 .seealso: MatGetLocalSubMatrix() 10322 @*/ 10323 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10324 { 10325 PetscErrorCode ierr; 10326 10327 PetscFunctionBegin; 10328 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10329 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10330 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10331 PetscCheckSameComm(isrow,2,iscol,3); 10332 PetscValidPointer(submat,4); 10333 if (*submat) { 10334 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10335 } 10336 10337 if (mat->ops->restorelocalsubmatrix) { 10338 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10339 } else { 10340 ierr = MatDestroy(submat);CHKERRQ(ierr); 10341 } 10342 *submat = NULL; 10343 PetscFunctionReturn(0); 10344 } 10345 10346 /* --------------------------------------------------------*/ 10347 /*@ 10348 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10349 10350 Collective on Mat 10351 10352 Input Parameter: 10353 . mat - the matrix 10354 10355 Output Parameter: 10356 . is - if any rows have zero diagonals this contains the list of them 10357 10358 Level: developer 10359 10360 Concepts: matrix-vector product 10361 10362 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10363 @*/ 10364 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10365 { 10366 PetscErrorCode ierr; 10367 10368 PetscFunctionBegin; 10369 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10370 PetscValidType(mat,1); 10371 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10372 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10373 10374 if (!mat->ops->findzerodiagonals) { 10375 Vec diag; 10376 const PetscScalar *a; 10377 PetscInt *rows; 10378 PetscInt rStart, rEnd, r, nrow = 0; 10379 10380 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10381 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10382 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10383 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10384 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10385 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10386 nrow = 0; 10387 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10388 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10389 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10390 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10391 } else { 10392 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10393 } 10394 PetscFunctionReturn(0); 10395 } 10396 10397 /*@ 10398 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10399 10400 Collective on Mat 10401 10402 Input Parameter: 10403 . mat - the matrix 10404 10405 Output Parameter: 10406 . is - contains the list of rows with off block diagonal entries 10407 10408 Level: developer 10409 10410 Concepts: matrix-vector product 10411 10412 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10413 @*/ 10414 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10415 { 10416 PetscErrorCode ierr; 10417 10418 PetscFunctionBegin; 10419 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10420 PetscValidType(mat,1); 10421 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10422 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10423 10424 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10425 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10426 PetscFunctionReturn(0); 10427 } 10428 10429 /*@C 10430 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10431 10432 Collective on Mat 10433 10434 Input Parameters: 10435 . mat - the matrix 10436 10437 Output Parameters: 10438 . values - the block inverses in column major order (FORTRAN-like) 10439 10440 Note: 10441 This routine is not available from Fortran. 10442 10443 Level: advanced 10444 10445 .seealso: MatInvertBockDiagonalMat 10446 @*/ 10447 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10448 { 10449 PetscErrorCode ierr; 10450 10451 PetscFunctionBegin; 10452 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10453 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10454 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10455 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10456 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10457 PetscFunctionReturn(0); 10458 } 10459 10460 /*@C 10461 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10462 10463 Collective on Mat 10464 10465 Input Parameters: 10466 + mat - the matrix 10467 . nblocks - the number of blocks 10468 - bsizes - the size of each block 10469 10470 Output Parameters: 10471 . values - the block inverses in column major order (FORTRAN-like) 10472 10473 Note: 10474 This routine is not available from Fortran. 10475 10476 Level: advanced 10477 10478 .seealso: MatInvertBockDiagonal() 10479 @*/ 10480 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10481 { 10482 PetscErrorCode ierr; 10483 10484 PetscFunctionBegin; 10485 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10486 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10487 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10488 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10489 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10490 PetscFunctionReturn(0); 10491 } 10492 10493 /*@ 10494 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10495 10496 Collective on Mat 10497 10498 Input Parameters: 10499 . A - the matrix 10500 10501 Output Parameters: 10502 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10503 10504 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10505 10506 Level: advanced 10507 10508 .seealso: MatInvertBockDiagonal() 10509 @*/ 10510 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10511 { 10512 PetscErrorCode ierr; 10513 const PetscScalar *vals; 10514 PetscInt *dnnz; 10515 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10516 10517 PetscFunctionBegin; 10518 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10519 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10520 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10521 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10522 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10523 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10524 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10525 for(j = 0; j < m/bs; j++) { 10526 dnnz[j] = 1; 10527 } 10528 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10529 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10530 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10531 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10532 for (i = rstart/bs; i < rend/bs; i++) { 10533 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10534 } 10535 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10536 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10537 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10538 PetscFunctionReturn(0); 10539 } 10540 10541 /*@C 10542 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10543 via MatTransposeColoringCreate(). 10544 10545 Collective on MatTransposeColoring 10546 10547 Input Parameter: 10548 . c - coloring context 10549 10550 Level: intermediate 10551 10552 .seealso: MatTransposeColoringCreate() 10553 @*/ 10554 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10555 { 10556 PetscErrorCode ierr; 10557 MatTransposeColoring matcolor=*c; 10558 10559 PetscFunctionBegin; 10560 if (!matcolor) PetscFunctionReturn(0); 10561 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10562 10563 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10564 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10565 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10566 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10567 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10568 if (matcolor->brows>0) { 10569 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10570 } 10571 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10572 PetscFunctionReturn(0); 10573 } 10574 10575 /*@C 10576 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10577 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10578 MatTransposeColoring to sparse B. 10579 10580 Collective on MatTransposeColoring 10581 10582 Input Parameters: 10583 + B - sparse matrix B 10584 . Btdense - symbolic dense matrix B^T 10585 - coloring - coloring context created with MatTransposeColoringCreate() 10586 10587 Output Parameter: 10588 . Btdense - dense matrix B^T 10589 10590 Level: advanced 10591 10592 Notes: 10593 These are used internally for some implementations of MatRARt() 10594 10595 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10596 10597 .keywords: coloring 10598 @*/ 10599 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10600 { 10601 PetscErrorCode ierr; 10602 10603 PetscFunctionBegin; 10604 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10605 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10606 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10607 10608 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10609 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10610 PetscFunctionReturn(0); 10611 } 10612 10613 /*@C 10614 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10615 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10616 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10617 Csp from Cden. 10618 10619 Collective on MatTransposeColoring 10620 10621 Input Parameters: 10622 + coloring - coloring context created with MatTransposeColoringCreate() 10623 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10624 10625 Output Parameter: 10626 . Csp - sparse matrix 10627 10628 Level: advanced 10629 10630 Notes: 10631 These are used internally for some implementations of MatRARt() 10632 10633 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10634 10635 .keywords: coloring 10636 @*/ 10637 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10638 { 10639 PetscErrorCode ierr; 10640 10641 PetscFunctionBegin; 10642 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10643 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10644 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10645 10646 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10647 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10648 PetscFunctionReturn(0); 10649 } 10650 10651 /*@C 10652 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10653 10654 Collective on Mat 10655 10656 Input Parameters: 10657 + mat - the matrix product C 10658 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10659 10660 Output Parameter: 10661 . color - the new coloring context 10662 10663 Level: intermediate 10664 10665 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10666 MatTransColoringApplyDenToSp() 10667 @*/ 10668 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10669 { 10670 MatTransposeColoring c; 10671 MPI_Comm comm; 10672 PetscErrorCode ierr; 10673 10674 PetscFunctionBegin; 10675 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10676 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10677 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10678 10679 c->ctype = iscoloring->ctype; 10680 if (mat->ops->transposecoloringcreate) { 10681 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10682 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10683 10684 *color = c; 10685 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10686 PetscFunctionReturn(0); 10687 } 10688 10689 /*@ 10690 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10691 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10692 same, otherwise it will be larger 10693 10694 Not Collective 10695 10696 Input Parameter: 10697 . A - the matrix 10698 10699 Output Parameter: 10700 . state - the current state 10701 10702 Notes: 10703 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10704 different matrices 10705 10706 Level: intermediate 10707 10708 @*/ 10709 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10710 { 10711 PetscFunctionBegin; 10712 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10713 *state = mat->nonzerostate; 10714 PetscFunctionReturn(0); 10715 } 10716 10717 /*@ 10718 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10719 matrices from each processor 10720 10721 Collective on MPI_Comm 10722 10723 Input Parameters: 10724 + comm - the communicators the parallel matrix will live on 10725 . seqmat - the input sequential matrices 10726 . n - number of local columns (or PETSC_DECIDE) 10727 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10728 10729 Output Parameter: 10730 . mpimat - the parallel matrix generated 10731 10732 Level: advanced 10733 10734 Notes: 10735 The number of columns of the matrix in EACH processor MUST be the same. 10736 10737 @*/ 10738 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10739 { 10740 PetscErrorCode ierr; 10741 10742 PetscFunctionBegin; 10743 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10744 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"); 10745 10746 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10747 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10748 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10749 PetscFunctionReturn(0); 10750 } 10751 10752 /*@ 10753 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10754 ranks' ownership ranges. 10755 10756 Collective on A 10757 10758 Input Parameters: 10759 + A - the matrix to create subdomains from 10760 - N - requested number of subdomains 10761 10762 10763 Output Parameters: 10764 + n - number of subdomains resulting on this rank 10765 - iss - IS list with indices of subdomains on this rank 10766 10767 Level: advanced 10768 10769 Notes: 10770 number of subdomains must be smaller than the communicator size 10771 @*/ 10772 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10773 { 10774 MPI_Comm comm,subcomm; 10775 PetscMPIInt size,rank,color; 10776 PetscInt rstart,rend,k; 10777 PetscErrorCode ierr; 10778 10779 PetscFunctionBegin; 10780 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10781 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10782 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10783 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); 10784 *n = 1; 10785 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10786 color = rank/k; 10787 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10788 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10789 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10790 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10791 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10792 PetscFunctionReturn(0); 10793 } 10794 10795 /*@ 10796 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10797 10798 If the interpolation and restriction operators are the same, uses MatPtAP. 10799 If they are not the same, use MatMatMatMult. 10800 10801 Once the coarse grid problem is constructed, correct for interpolation operators 10802 that are not of full rank, which can legitimately happen in the case of non-nested 10803 geometric multigrid. 10804 10805 Input Parameters: 10806 + restrct - restriction operator 10807 . dA - fine grid matrix 10808 . interpolate - interpolation operator 10809 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10810 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10811 10812 Output Parameters: 10813 . A - the Galerkin coarse matrix 10814 10815 Options Database Key: 10816 . -pc_mg_galerkin <both,pmat,mat,none> 10817 10818 Level: developer 10819 10820 .keywords: MG, multigrid, Galerkin 10821 10822 .seealso: MatPtAP(), MatMatMatMult() 10823 @*/ 10824 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10825 { 10826 PetscErrorCode ierr; 10827 IS zerorows; 10828 Vec diag; 10829 10830 PetscFunctionBegin; 10831 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10832 /* Construct the coarse grid matrix */ 10833 if (interpolate == restrct) { 10834 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10835 } else { 10836 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10837 } 10838 10839 /* If the interpolation matrix is not of full rank, A will have zero rows. 10840 This can legitimately happen in the case of non-nested geometric multigrid. 10841 In that event, we set the rows of the matrix to the rows of the identity, 10842 ignoring the equations (as the RHS will also be zero). */ 10843 10844 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10845 10846 if (zerorows != NULL) { /* if there are any zero rows */ 10847 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10848 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10849 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10850 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10851 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10852 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10853 } 10854 PetscFunctionReturn(0); 10855 } 10856 10857 /*@C 10858 MatSetOperation - Allows user to set a matrix operation for any matrix type 10859 10860 Logically Collective on Mat 10861 10862 Input Parameters: 10863 + mat - the matrix 10864 . op - the name of the operation 10865 - f - the function that provides the operation 10866 10867 Level: developer 10868 10869 Usage: 10870 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10871 $ ierr = MatCreateXXX(comm,...&A); 10872 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10873 10874 Notes: 10875 See the file include/petscmat.h for a complete list of matrix 10876 operations, which all have the form MATOP_<OPERATION>, where 10877 <OPERATION> is the name (in all capital letters) of the 10878 user interface routine (e.g., MatMult() -> MATOP_MULT). 10879 10880 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10881 sequence as the usual matrix interface routines, since they 10882 are intended to be accessed via the usual matrix interface 10883 routines, e.g., 10884 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10885 10886 In particular each function MUST return an error code of 0 on success and 10887 nonzero on failure. 10888 10889 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10890 10891 .keywords: matrix, set, operation 10892 10893 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10894 @*/ 10895 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10896 { 10897 PetscFunctionBegin; 10898 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10899 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10900 mat->ops->viewnative = mat->ops->view; 10901 } 10902 (((void(**)(void))mat->ops)[op]) = f; 10903 PetscFunctionReturn(0); 10904 } 10905 10906 /*@C 10907 MatGetOperation - Gets a matrix operation for any matrix type. 10908 10909 Not Collective 10910 10911 Input Parameters: 10912 + mat - the matrix 10913 - op - the name of the operation 10914 10915 Output Parameter: 10916 . f - the function that provides the operation 10917 10918 Level: developer 10919 10920 Usage: 10921 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10922 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10923 10924 Notes: 10925 See the file include/petscmat.h for a complete list of matrix 10926 operations, which all have the form MATOP_<OPERATION>, where 10927 <OPERATION> is the name (in all capital letters) of the 10928 user interface routine (e.g., MatMult() -> MATOP_MULT). 10929 10930 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10931 10932 .keywords: matrix, get, operation 10933 10934 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10935 @*/ 10936 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10937 { 10938 PetscFunctionBegin; 10939 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10940 *f = (((void (**)(void))mat->ops)[op]); 10941 PetscFunctionReturn(0); 10942 } 10943 10944 /*@ 10945 MatHasOperation - Determines whether the given matrix supports the particular 10946 operation. 10947 10948 Not Collective 10949 10950 Input Parameters: 10951 + mat - the matrix 10952 - op - the operation, for example, MATOP_GET_DIAGONAL 10953 10954 Output Parameter: 10955 . has - either PETSC_TRUE or PETSC_FALSE 10956 10957 Level: advanced 10958 10959 Notes: 10960 See the file include/petscmat.h for a complete list of matrix 10961 operations, which all have the form MATOP_<OPERATION>, where 10962 <OPERATION> is the name (in all capital letters) of the 10963 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10964 10965 .keywords: matrix, has, operation 10966 10967 .seealso: MatCreateShell() 10968 @*/ 10969 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10970 { 10971 PetscErrorCode ierr; 10972 10973 PetscFunctionBegin; 10974 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10975 PetscValidType(mat,1); 10976 PetscValidPointer(has,3); 10977 if (mat->ops->hasoperation) { 10978 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 10979 } else { 10980 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10981 else { 10982 *has = PETSC_FALSE; 10983 if (op == MATOP_CREATE_SUBMATRIX) { 10984 PetscMPIInt size; 10985 10986 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10987 if (size == 1) { 10988 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 10989 } 10990 } 10991 } 10992 } 10993 PetscFunctionReturn(0); 10994 } 10995 10996 /*@ 10997 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10998 of the matrix are congruent 10999 11000 Collective on mat 11001 11002 Input Parameters: 11003 . mat - the matrix 11004 11005 Output Parameter: 11006 . cong - either PETSC_TRUE or PETSC_FALSE 11007 11008 Level: beginner 11009 11010 Notes: 11011 11012 .keywords: matrix, has 11013 11014 .seealso: MatCreate(), MatSetSizes() 11015 @*/ 11016 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 11017 { 11018 PetscErrorCode ierr; 11019 11020 PetscFunctionBegin; 11021 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11022 PetscValidType(mat,1); 11023 PetscValidPointer(cong,2); 11024 if (!mat->rmap || !mat->cmap) { 11025 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11026 PetscFunctionReturn(0); 11027 } 11028 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11029 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 11030 if (*cong) mat->congruentlayouts = 1; 11031 else mat->congruentlayouts = 0; 11032 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11033 PetscFunctionReturn(0); 11034 } 11035