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_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 ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 94 ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 95 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 96 PetscFunctionReturn(0); 97 } 98 99 /*@ 100 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 101 102 Logically Collective on Mat 103 104 Input Parameters: 105 . mat - the factored matrix 106 107 Output Parameter: 108 + pivot - the pivot value computed 109 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 110 the share the matrix 111 112 Level: advanced 113 114 Notes: 115 This routine does not work for factorizations done with external packages. 116 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 117 118 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 119 120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 121 @*/ 122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 123 { 124 PetscFunctionBegin; 125 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 126 *pivot = mat->factorerror_zeropivot_value; 127 *row = mat->factorerror_zeropivot_row; 128 PetscFunctionReturn(0); 129 } 130 131 /*@ 132 MatFactorGetError - gets the error code from a factorization 133 134 Logically Collective on Mat 135 136 Input Parameters: 137 . mat - the factored matrix 138 139 Output Parameter: 140 . err - the error code 141 142 Level: advanced 143 144 Notes: 145 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 146 147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 148 @*/ 149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 150 { 151 PetscFunctionBegin; 152 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 153 *err = mat->factorerrortype; 154 PetscFunctionReturn(0); 155 } 156 157 /*@ 158 MatFactorClearError - clears the error code in a factorization 159 160 Logically Collective on Mat 161 162 Input Parameter: 163 . mat - the factored matrix 164 165 Level: developer 166 167 Notes: 168 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 169 170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 171 @*/ 172 PetscErrorCode MatFactorClearError(Mat mat) 173 { 174 PetscFunctionBegin; 175 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 176 mat->factorerrortype = MAT_FACTOR_NOERROR; 177 mat->factorerror_zeropivot_value = 0.0; 178 mat->factorerror_zeropivot_row = 0; 179 PetscFunctionReturn(0); 180 } 181 182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 183 { 184 PetscErrorCode ierr; 185 Vec r,l; 186 const PetscScalar *al; 187 PetscInt i,nz,gnz,N,n; 188 189 PetscFunctionBegin; 190 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 191 if (!cols) { /* nonzero rows */ 192 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 193 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 194 ierr = VecSet(l,0.0);CHKERRQ(ierr); 195 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 196 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 197 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 198 } else { /* nonzero columns */ 199 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 200 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 201 ierr = VecSet(r,0.0);CHKERRQ(ierr); 202 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 203 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 204 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 205 } 206 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 207 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 208 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 209 if (gnz != N) { 210 PetscInt *nzr; 211 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 212 if (nz) { 213 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 214 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 215 } 216 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 217 } else *nonzero = NULL; 218 if (!cols) { /* nonzero rows */ 219 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 220 } else { 221 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 222 } 223 ierr = VecDestroy(&l);CHKERRQ(ierr); 224 ierr = VecDestroy(&r);CHKERRQ(ierr); 225 PetscFunctionReturn(0); 226 } 227 228 /*@ 229 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 230 231 Input Parameter: 232 . A - the matrix 233 234 Output Parameter: 235 . keptrows - the rows that are not completely zero 236 237 Notes: 238 keptrows is set to NULL if all rows are nonzero. 239 240 Level: intermediate 241 242 @*/ 243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 244 { 245 PetscErrorCode ierr; 246 247 PetscFunctionBegin; 248 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 249 PetscValidType(mat,1); 250 PetscValidPointer(keptrows,2); 251 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 252 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 253 if (!mat->ops->findnonzerorows) { 254 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 255 } else { 256 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 257 } 258 PetscFunctionReturn(0); 259 } 260 261 /*@ 262 MatFindZeroRows - Locate all rows that are completely zero in the matrix 263 264 Input Parameter: 265 . A - the matrix 266 267 Output Parameter: 268 . zerorows - the rows that are completely zero 269 270 Notes: 271 zerorows is set to NULL if no rows are zero. 272 273 Level: intermediate 274 275 @*/ 276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 277 { 278 PetscErrorCode ierr; 279 IS keptrows; 280 PetscInt m, n; 281 282 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 283 PetscValidType(mat,1); 284 285 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 286 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 287 In keeping with this convention, we set zerorows to NULL if there are no zero 288 rows. */ 289 if (keptrows == NULL) { 290 *zerorows = NULL; 291 } else { 292 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 293 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 294 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 295 } 296 PetscFunctionReturn(0); 297 } 298 299 /*@ 300 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 301 302 Not Collective 303 304 Input Parameters: 305 . A - the matrix 306 307 Output Parameters: 308 . a - the diagonal part (which is a SEQUENTIAL matrix) 309 310 Notes: 311 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 312 Use caution, as the reference count on the returned matrix is not incremented and it is used as 313 part of the containing MPI Mat's normal operation. 314 315 Level: advanced 316 317 @*/ 318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 319 { 320 PetscErrorCode ierr; 321 322 PetscFunctionBegin; 323 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 324 PetscValidType(A,1); 325 PetscValidPointer(a,3); 326 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 327 if (!A->ops->getdiagonalblock) { 328 PetscMPIInt size; 329 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 330 if (size == 1) { 331 *a = A; 332 PetscFunctionReturn(0); 333 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type"); 334 } 335 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 336 PetscFunctionReturn(0); 337 } 338 339 /*@ 340 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 341 342 Collective on Mat 343 344 Input Parameters: 345 . mat - the matrix 346 347 Output Parameter: 348 . trace - the sum of the diagonal entries 349 350 Level: advanced 351 352 @*/ 353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 354 { 355 PetscErrorCode ierr; 356 Vec diag; 357 358 PetscFunctionBegin; 359 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 360 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 361 ierr = VecSum(diag,trace);CHKERRQ(ierr); 362 ierr = VecDestroy(&diag);CHKERRQ(ierr); 363 PetscFunctionReturn(0); 364 } 365 366 /*@ 367 MatRealPart - Zeros out the imaginary part of the matrix 368 369 Logically Collective on Mat 370 371 Input Parameters: 372 . mat - the matrix 373 374 Level: advanced 375 376 377 .seealso: MatImaginaryPart() 378 @*/ 379 PetscErrorCode MatRealPart(Mat mat) 380 { 381 PetscErrorCode ierr; 382 383 PetscFunctionBegin; 384 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 385 PetscValidType(mat,1); 386 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 387 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 388 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 389 MatCheckPreallocated(mat,1); 390 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 392 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 393 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 394 } 395 #endif 396 PetscFunctionReturn(0); 397 } 398 399 /*@C 400 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 401 402 Collective on Mat 403 404 Input Parameter: 405 . mat - the matrix 406 407 Output Parameters: 408 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 409 - ghosts - the global indices of the ghost points 410 411 Notes: 412 the nghosts and ghosts are suitable to pass into VecCreateGhost() 413 414 Level: advanced 415 416 @*/ 417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 418 { 419 PetscErrorCode ierr; 420 421 PetscFunctionBegin; 422 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 423 PetscValidType(mat,1); 424 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 425 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 426 if (!mat->ops->getghosts) { 427 if (nghosts) *nghosts = 0; 428 if (ghosts) *ghosts = 0; 429 } else { 430 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 431 } 432 PetscFunctionReturn(0); 433 } 434 435 436 /*@ 437 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 438 439 Logically Collective on Mat 440 441 Input Parameters: 442 . mat - the matrix 443 444 Level: advanced 445 446 447 .seealso: MatRealPart() 448 @*/ 449 PetscErrorCode MatImaginaryPart(Mat mat) 450 { 451 PetscErrorCode ierr; 452 453 PetscFunctionBegin; 454 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 455 PetscValidType(mat,1); 456 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 457 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 458 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 459 MatCheckPreallocated(mat,1); 460 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 462 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 463 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 464 } 465 #endif 466 PetscFunctionReturn(0); 467 } 468 469 /*@ 470 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 471 472 Not Collective 473 474 Input Parameter: 475 . mat - the matrix 476 477 Output Parameters: 478 + missing - is any diagonal missing 479 - dd - first diagonal entry that is missing (optional) on this process 480 481 Level: advanced 482 483 484 .seealso: MatRealPart() 485 @*/ 486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 487 { 488 PetscErrorCode ierr; 489 490 PetscFunctionBegin; 491 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 492 PetscValidType(mat,1); 493 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 494 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 495 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 496 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 497 PetscFunctionReturn(0); 498 } 499 500 /*@C 501 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 502 for each row that you get to ensure that your application does 503 not bleed memory. 504 505 Not Collective 506 507 Input Parameters: 508 + mat - the matrix 509 - row - the row to get 510 511 Output Parameters: 512 + ncols - if not NULL, the number of nonzeros in the row 513 . cols - if not NULL, the column numbers 514 - vals - if not NULL, the values 515 516 Notes: 517 This routine is provided for people who need to have direct access 518 to the structure of a matrix. We hope that we provide enough 519 high-level matrix routines that few users will need it. 520 521 MatGetRow() always returns 0-based column indices, regardless of 522 whether the internal representation is 0-based (default) or 1-based. 523 524 For better efficiency, set cols and/or vals to NULL if you do 525 not wish to extract these quantities. 526 527 The user can only examine the values extracted with MatGetRow(); 528 the values cannot be altered. To change the matrix entries, one 529 must use MatSetValues(). 530 531 You can only have one call to MatGetRow() outstanding for a particular 532 matrix at a time, per processor. MatGetRow() can only obtain rows 533 associated with the given processor, it cannot get rows from the 534 other processors; for that we suggest using MatCreateSubMatrices(), then 535 MatGetRow() on the submatrix. The row index passed to MatGetRow() 536 is in the global number of rows. 537 538 Fortran Notes: 539 The calling sequence from Fortran is 540 .vb 541 MatGetRow(matrix,row,ncols,cols,values,ierr) 542 Mat matrix (input) 543 integer row (input) 544 integer ncols (output) 545 integer cols(maxcols) (output) 546 double precision (or double complex) values(maxcols) output 547 .ve 548 where maxcols >= maximum nonzeros in any row of the matrix. 549 550 551 Caution: 552 Do not try to change the contents of the output arrays (cols and vals). 553 In some cases, this may corrupt the matrix. 554 555 Level: advanced 556 557 Concepts: matrices^row access 558 559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 560 @*/ 561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 562 { 563 PetscErrorCode ierr; 564 PetscInt incols; 565 566 PetscFunctionBegin; 567 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 568 PetscValidType(mat,1); 569 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 570 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 571 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 572 MatCheckPreallocated(mat,1); 573 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 574 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 575 if (ncols) *ncols = incols; 576 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 577 PetscFunctionReturn(0); 578 } 579 580 /*@ 581 MatConjugate - replaces the matrix values with their complex conjugates 582 583 Logically Collective on Mat 584 585 Input Parameters: 586 . mat - the matrix 587 588 Level: advanced 589 590 .seealso: VecConjugate() 591 @*/ 592 PetscErrorCode MatConjugate(Mat mat) 593 { 594 #if defined(PETSC_USE_COMPLEX) 595 PetscErrorCode ierr; 596 597 PetscFunctionBegin; 598 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 599 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 600 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"); 601 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 603 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 604 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 605 } 606 #endif 607 PetscFunctionReturn(0); 608 #else 609 return 0; 610 #endif 611 } 612 613 /*@C 614 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 615 616 Not Collective 617 618 Input Parameters: 619 + mat - the matrix 620 . row - the row to get 621 . ncols, cols - the number of nonzeros and their columns 622 - vals - if nonzero the column values 623 624 Notes: 625 This routine should be called after you have finished examining the entries. 626 627 This routine zeros out ncols, cols, and vals. This is to prevent accidental 628 us of the array after it has been restored. If you pass NULL, it will 629 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 630 631 Fortran Notes: 632 The calling sequence from Fortran is 633 .vb 634 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 635 Mat matrix (input) 636 integer row (input) 637 integer ncols (output) 638 integer cols(maxcols) (output) 639 double precision (or double complex) values(maxcols) output 640 .ve 641 Where maxcols >= maximum nonzeros in any row of the matrix. 642 643 In Fortran MatRestoreRow() MUST be called after MatGetRow() 644 before another call to MatGetRow() can be made. 645 646 Level: advanced 647 648 .seealso: MatGetRow() 649 @*/ 650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 651 { 652 PetscErrorCode ierr; 653 654 PetscFunctionBegin; 655 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 656 if (ncols) PetscValidIntPointer(ncols,3); 657 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 658 if (!mat->ops->restorerow) PetscFunctionReturn(0); 659 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 660 if (ncols) *ncols = 0; 661 if (cols) *cols = NULL; 662 if (vals) *vals = NULL; 663 PetscFunctionReturn(0); 664 } 665 666 /*@ 667 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 668 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 669 670 Not Collective 671 672 Input Parameters: 673 + mat - the matrix 674 675 Notes: 676 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. 677 678 Level: advanced 679 680 Concepts: matrices^row access 681 682 .seealso: MatRestoreRowUpperTriangular() 683 @*/ 684 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 685 { 686 PetscErrorCode ierr; 687 688 PetscFunctionBegin; 689 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 690 PetscValidType(mat,1); 691 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 692 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 693 MatCheckPreallocated(mat,1); 694 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 695 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 696 PetscFunctionReturn(0); 697 } 698 699 /*@ 700 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 701 702 Not Collective 703 704 Input Parameters: 705 + mat - the matrix 706 707 Notes: 708 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 709 710 711 Level: advanced 712 713 .seealso: MatGetRowUpperTriangular() 714 @*/ 715 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 716 { 717 PetscErrorCode ierr; 718 719 PetscFunctionBegin; 720 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 721 PetscValidType(mat,1); 722 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 723 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 724 MatCheckPreallocated(mat,1); 725 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 726 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 727 PetscFunctionReturn(0); 728 } 729 730 /*@C 731 MatSetOptionsPrefix - Sets the prefix used for searching for all 732 Mat options in the database. 733 734 Logically Collective on Mat 735 736 Input Parameter: 737 + A - the Mat context 738 - prefix - the prefix to prepend to all option names 739 740 Notes: 741 A hyphen (-) must NOT be given at the beginning of the prefix name. 742 The first character of all runtime options is AUTOMATICALLY the hyphen. 743 744 Level: advanced 745 746 .keywords: Mat, set, options, prefix, database 747 748 .seealso: MatSetFromOptions() 749 @*/ 750 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 751 { 752 PetscErrorCode ierr; 753 754 PetscFunctionBegin; 755 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 756 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 757 PetscFunctionReturn(0); 758 } 759 760 /*@C 761 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 762 Mat options in the database. 763 764 Logically Collective on Mat 765 766 Input Parameters: 767 + A - the Mat context 768 - prefix - the prefix to prepend to all option names 769 770 Notes: 771 A hyphen (-) must NOT be given at the beginning of the prefix name. 772 The first character of all runtime options is AUTOMATICALLY the hyphen. 773 774 Level: advanced 775 776 .keywords: Mat, append, options, prefix, database 777 778 .seealso: MatGetOptionsPrefix() 779 @*/ 780 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 781 { 782 PetscErrorCode ierr; 783 784 PetscFunctionBegin; 785 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 786 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 787 PetscFunctionReturn(0); 788 } 789 790 /*@C 791 MatGetOptionsPrefix - Sets the prefix used for searching for all 792 Mat options in the database. 793 794 Not Collective 795 796 Input Parameter: 797 . A - the Mat context 798 799 Output Parameter: 800 . prefix - pointer to the prefix string used 801 802 Notes: 803 On the fortran side, the user should pass in a string 'prefix' of 804 sufficient length to hold the prefix. 805 806 Level: advanced 807 808 .keywords: Mat, get, options, prefix, database 809 810 .seealso: MatAppendOptionsPrefix() 811 @*/ 812 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 813 { 814 PetscErrorCode ierr; 815 816 PetscFunctionBegin; 817 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 818 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 819 PetscFunctionReturn(0); 820 } 821 822 /*@ 823 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 824 825 Collective on Mat 826 827 Input Parameters: 828 . A - the Mat context 829 830 Notes: 831 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 832 Currently support MPIAIJ and SEQAIJ. 833 834 Level: beginner 835 836 .keywords: Mat, ResetPreallocation 837 838 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 839 @*/ 840 PetscErrorCode MatResetPreallocation(Mat A) 841 { 842 PetscErrorCode ierr; 843 844 PetscFunctionBegin; 845 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 846 PetscValidType(A,1); 847 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 848 PetscFunctionReturn(0); 849 } 850 851 852 /*@ 853 MatSetUp - Sets up the internal matrix data structures for the later use. 854 855 Collective on Mat 856 857 Input Parameters: 858 . A - the Mat context 859 860 Notes: 861 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 862 863 If a suitable preallocation routine is used, this function does not need to be called. 864 865 See the Performance chapter of the PETSc users manual for how to preallocate matrices 866 867 Level: beginner 868 869 .keywords: Mat, setup 870 871 .seealso: MatCreate(), MatDestroy() 872 @*/ 873 PetscErrorCode MatSetUp(Mat A) 874 { 875 PetscMPIInt size; 876 PetscErrorCode ierr; 877 878 PetscFunctionBegin; 879 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 880 if (!((PetscObject)A)->type_name) { 881 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 882 if (size == 1) { 883 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 884 } else { 885 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 886 } 887 } 888 if (!A->preallocated && A->ops->setup) { 889 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 890 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 891 } 892 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 893 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 894 A->preallocated = PETSC_TRUE; 895 PetscFunctionReturn(0); 896 } 897 898 #if defined(PETSC_HAVE_SAWS) 899 #include <petscviewersaws.h> 900 #endif 901 /*@C 902 MatView - Visualizes a matrix object. 903 904 Collective on Mat 905 906 Input Parameters: 907 + mat - the matrix 908 - viewer - visualization context 909 910 Notes: 911 The available visualization contexts include 912 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 913 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 914 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 915 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 916 917 The user can open alternative visualization contexts with 918 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 919 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 920 specified file; corresponding input uses MatLoad() 921 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 922 an X window display 923 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 924 Currently only the sequential dense and AIJ 925 matrix types support the Socket viewer. 926 927 The user can call PetscViewerPushFormat() to specify the output 928 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 929 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 930 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 931 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 932 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 933 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 934 format common among all matrix types 935 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 936 format (which is in many cases the same as the default) 937 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 938 size and structure (not the matrix entries) 939 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 940 the matrix structure 941 942 Options Database Keys: 943 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 944 . -mat_view ::ascii_info_detail - Prints more detailed info 945 . -mat_view - Prints matrix in ASCII format 946 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 947 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 948 . -display <name> - Sets display name (default is host) 949 . -draw_pause <sec> - Sets number of seconds to pause after display 950 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 951 . -viewer_socket_machine <machine> - 952 . -viewer_socket_port <port> - 953 . -mat_view binary - save matrix to file in binary format 954 - -viewer_binary_filename <name> - 955 Level: beginner 956 957 Notes: 958 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 959 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 960 961 See the manual page for MatLoad() for the exact format of the binary file when the binary 962 viewer is used. 963 964 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 965 viewer is used. 966 967 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 968 and then use the following mouse functions. 969 + left mouse: zoom in 970 . middle mouse: zoom out 971 - right mouse: continue with the simulation 972 973 Concepts: matrices^viewing 974 Concepts: matrices^plotting 975 Concepts: matrices^printing 976 977 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 978 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 979 @*/ 980 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 981 { 982 PetscErrorCode ierr; 983 PetscInt rows,cols,rbs,cbs; 984 PetscBool iascii,ibinary; 985 PetscViewerFormat format; 986 PetscMPIInt size; 987 #if defined(PETSC_HAVE_SAWS) 988 PetscBool issaws; 989 #endif 990 991 PetscFunctionBegin; 992 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 993 PetscValidType(mat,1); 994 if (!viewer) { 995 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 996 } 997 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 998 PetscCheckSameComm(mat,1,viewer,2); 999 MatCheckPreallocated(mat,1); 1000 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1001 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 1002 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1003 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 1004 if (ibinary) { 1005 PetscBool mpiio; 1006 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 1007 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 1008 } 1009 1010 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1011 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1012 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1013 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 1014 } 1015 1016 #if defined(PETSC_HAVE_SAWS) 1017 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 1018 #endif 1019 if (iascii) { 1020 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1021 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 1022 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1023 MatNullSpace nullsp,transnullsp; 1024 1025 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1026 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1027 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1028 if (rbs != 1 || cbs != 1) { 1029 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 1030 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 1031 } else { 1032 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1033 } 1034 if (mat->factortype) { 1035 MatSolverType solver; 1036 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1037 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1038 } 1039 if (mat->ops->getinfo) { 1040 MatInfo info; 1041 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1042 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1043 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1044 } 1045 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1046 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1047 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1048 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1049 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1050 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1051 } 1052 #if defined(PETSC_HAVE_SAWS) 1053 } else if (issaws) { 1054 PetscMPIInt rank; 1055 1056 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1057 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1058 if (!((PetscObject)mat)->amsmem && !rank) { 1059 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1060 } 1061 #endif 1062 } 1063 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1064 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1065 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1066 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1067 } else if (mat->ops->view) { 1068 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1069 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1070 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1071 } 1072 if (iascii) { 1073 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1074 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1075 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1076 } 1077 } 1078 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1079 PetscFunctionReturn(0); 1080 } 1081 1082 #if defined(PETSC_USE_DEBUG) 1083 #include <../src/sys/totalview/tv_data_display.h> 1084 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1085 { 1086 TV_add_row("Local rows", "int", &mat->rmap->n); 1087 TV_add_row("Local columns", "int", &mat->cmap->n); 1088 TV_add_row("Global rows", "int", &mat->rmap->N); 1089 TV_add_row("Global columns", "int", &mat->cmap->N); 1090 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1091 return TV_format_OK; 1092 } 1093 #endif 1094 1095 /*@C 1096 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1097 with MatView(). The matrix format is determined from the options database. 1098 Generates a parallel MPI matrix if the communicator has more than one 1099 processor. The default matrix type is AIJ. 1100 1101 Collective on PetscViewer 1102 1103 Input Parameters: 1104 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1105 or some related function before a call to MatLoad() 1106 - viewer - binary/HDF5 file viewer 1107 1108 Options Database Keys: 1109 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1110 block size 1111 . -matload_block_size <bs> 1112 1113 Level: beginner 1114 1115 Notes: 1116 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1117 Mat before calling this routine if you wish to set it from the options database. 1118 1119 MatLoad() automatically loads into the options database any options 1120 given in the file filename.info where filename is the name of the file 1121 that was passed to the PetscViewerBinaryOpen(). The options in the info 1122 file will be ignored if you use the -viewer_binary_skip_info option. 1123 1124 If the type or size of newmat is not set before a call to MatLoad, PETSc 1125 sets the default matrix type AIJ and sets the local and global sizes. 1126 If type and/or size is already set, then the same are used. 1127 1128 In parallel, each processor can load a subset of rows (or the 1129 entire matrix). This routine is especially useful when a large 1130 matrix is stored on disk and only part of it is desired on each 1131 processor. For example, a parallel solver may access only some of 1132 the rows from each processor. The algorithm used here reads 1133 relatively small blocks of data rather than reading the entire 1134 matrix and then subsetting it. 1135 1136 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1137 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1138 or the sequence like 1139 $ PetscViewer v; 1140 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1141 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1142 $ PetscViewerSetFromOptions(v); 1143 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1144 $ PetscViewerFileSetName(v,"datafile"); 1145 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1146 $ -viewer_type {binary,hdf5} 1147 1148 See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach, 1149 and src/mat/examples/tutorials/ex10.c with the second approach. 1150 1151 Notes about the PETSc binary format: 1152 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1153 is read onto rank 0 and then shipped to its destination rank, one after another. 1154 Multiple objects, both matrices and vectors, can be stored within the same file. 1155 Their PetscObject name is ignored; they are loaded in the order of their storage. 1156 1157 Most users should not need to know the details of the binary storage 1158 format, since MatLoad() and MatView() completely hide these details. 1159 But for anyone who's interested, the standard binary matrix storage 1160 format is 1161 1162 $ int MAT_FILE_CLASSID 1163 $ int number of rows 1164 $ int number of columns 1165 $ int total number of nonzeros 1166 $ int *number nonzeros in each row 1167 $ int *column indices of all nonzeros (starting index is zero) 1168 $ PetscScalar *values of all nonzeros 1169 1170 PETSc automatically does the byte swapping for 1171 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1172 linux, Windows and the paragon; thus if you write your own binary 1173 read/write routines you have to swap the bytes; see PetscBinaryRead() 1174 and PetscBinaryWrite() to see how this may be done. 1175 1176 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1177 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1178 Each processor's chunk is loaded independently by its owning rank. 1179 Multiple objects, both matrices and vectors, can be stored within the same file. 1180 They are looked up by their PetscObject name. 1181 1182 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1183 by default the same structure and naming of the AIJ arrays and column count 1184 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1185 $ save example.mat A b -v7.3 1186 can be directly read by this routine (see Reference 1 for details). 1187 Note that depending on your MATLAB version, this format might be a default, 1188 otherwise you can set it as default in Preferences. 1189 1190 Unless -nocompression flag is used to save the file in MATLAB, 1191 PETSc must be configured with ZLIB package. 1192 1193 See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c 1194 1195 Current HDF5 (MAT-File) limitations: 1196 This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices. 1197 1198 Corresponding MatView() is not yet implemented. 1199 1200 The loaded matrix is actually a transpose of the original one in MATLAB, 1201 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1202 With this format, matrix is automatically transposed by PETSc, 1203 unless the matrix is marked as SPD or symmetric 1204 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1205 1206 References: 1207 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1208 1209 .keywords: matrix, load, binary, input, HDF5 1210 1211 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad() 1212 1213 @*/ 1214 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1215 { 1216 PetscErrorCode ierr; 1217 PetscBool flg; 1218 1219 PetscFunctionBegin; 1220 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1221 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1222 1223 if (!((PetscObject)newmat)->type_name) { 1224 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1225 } 1226 1227 flg = PETSC_FALSE; 1228 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1229 if (flg) { 1230 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1231 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1232 } 1233 flg = PETSC_FALSE; 1234 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1235 if (flg) { 1236 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1237 } 1238 1239 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 1240 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1241 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1242 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1243 PetscFunctionReturn(0); 1244 } 1245 1246 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1247 { 1248 PetscErrorCode ierr; 1249 Mat_Redundant *redund = *redundant; 1250 PetscInt i; 1251 1252 PetscFunctionBegin; 1253 if (redund){ 1254 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1255 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1256 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1257 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1258 } else { 1259 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1260 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1261 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1262 for (i=0; i<redund->nrecvs; i++) { 1263 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1264 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1265 } 1266 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1267 } 1268 1269 if (redund->subcomm) { 1270 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1271 } 1272 ierr = PetscFree(redund);CHKERRQ(ierr); 1273 } 1274 PetscFunctionReturn(0); 1275 } 1276 1277 /*@ 1278 MatDestroy - Frees space taken by a matrix. 1279 1280 Collective on Mat 1281 1282 Input Parameter: 1283 . A - the matrix 1284 1285 Level: beginner 1286 1287 @*/ 1288 PetscErrorCode MatDestroy(Mat *A) 1289 { 1290 PetscErrorCode ierr; 1291 1292 PetscFunctionBegin; 1293 if (!*A) PetscFunctionReturn(0); 1294 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1295 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1296 1297 /* if memory was published with SAWs then destroy it */ 1298 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1299 if ((*A)->ops->destroy) { 1300 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1301 } 1302 1303 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1304 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1305 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1306 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1307 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1308 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1309 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1310 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1311 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1312 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1313 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1314 PetscFunctionReturn(0); 1315 } 1316 1317 /*@C 1318 MatSetValues - Inserts or adds a block of values into a matrix. 1319 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1320 MUST be called after all calls to MatSetValues() have been completed. 1321 1322 Not Collective 1323 1324 Input Parameters: 1325 + mat - the matrix 1326 . v - a logically two-dimensional array of values 1327 . m, idxm - the number of rows and their global indices 1328 . n, idxn - the number of columns and their global indices 1329 - addv - either ADD_VALUES or INSERT_VALUES, where 1330 ADD_VALUES adds values to any existing entries, and 1331 INSERT_VALUES replaces existing entries with new values 1332 1333 Notes: 1334 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1335 MatSetUp() before using this routine 1336 1337 By default the values, v, are row-oriented. See MatSetOption() for other options. 1338 1339 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1340 options cannot be mixed without intervening calls to the assembly 1341 routines. 1342 1343 MatSetValues() uses 0-based row and column numbers in Fortran 1344 as well as in C. 1345 1346 Negative indices may be passed in idxm and idxn, these rows and columns are 1347 simply ignored. This allows easily inserting element stiffness matrices 1348 with homogeneous Dirchlet boundary conditions that you don't want represented 1349 in the matrix. 1350 1351 Efficiency Alert: 1352 The routine MatSetValuesBlocked() may offer much better efficiency 1353 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1354 1355 Level: beginner 1356 1357 Developer Notes: 1358 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1359 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1360 1361 Concepts: matrices^putting entries in 1362 1363 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1364 InsertMode, INSERT_VALUES, ADD_VALUES 1365 @*/ 1366 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1367 { 1368 PetscErrorCode ierr; 1369 #if defined(PETSC_USE_DEBUG) 1370 PetscInt i,j; 1371 #endif 1372 1373 PetscFunctionBeginHot; 1374 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1375 PetscValidType(mat,1); 1376 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1377 PetscValidIntPointer(idxm,3); 1378 PetscValidIntPointer(idxn,5); 1379 PetscValidScalarPointer(v,6); 1380 MatCheckPreallocated(mat,1); 1381 if (mat->insertmode == NOT_SET_VALUES) { 1382 mat->insertmode = addv; 1383 } 1384 #if defined(PETSC_USE_DEBUG) 1385 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1386 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1387 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1388 1389 for (i=0; i<m; i++) { 1390 for (j=0; j<n; j++) { 1391 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1392 #if defined(PETSC_USE_COMPLEX) 1393 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]); 1394 #else 1395 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1396 #endif 1397 } 1398 } 1399 #endif 1400 1401 if (mat->assembled) { 1402 mat->was_assembled = PETSC_TRUE; 1403 mat->assembled = PETSC_FALSE; 1404 } 1405 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1406 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1407 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1408 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1409 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1410 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1411 } 1412 #endif 1413 PetscFunctionReturn(0); 1414 } 1415 1416 1417 /*@ 1418 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1419 values into a matrix 1420 1421 Not Collective 1422 1423 Input Parameters: 1424 + mat - the matrix 1425 . row - the (block) row to set 1426 - v - a logically two-dimensional array of values 1427 1428 Notes: 1429 By the values, v, are column-oriented (for the block version) and sorted 1430 1431 All the nonzeros in the row must be provided 1432 1433 The matrix must have previously had its column indices set 1434 1435 The row must belong to this process 1436 1437 Level: intermediate 1438 1439 Concepts: matrices^putting entries in 1440 1441 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1442 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1443 @*/ 1444 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1445 { 1446 PetscErrorCode ierr; 1447 PetscInt globalrow; 1448 1449 PetscFunctionBegin; 1450 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1451 PetscValidType(mat,1); 1452 PetscValidScalarPointer(v,2); 1453 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1454 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1455 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1456 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1457 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1458 } 1459 #endif 1460 PetscFunctionReturn(0); 1461 } 1462 1463 /*@ 1464 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1465 values into a matrix 1466 1467 Not Collective 1468 1469 Input Parameters: 1470 + mat - the matrix 1471 . row - the (block) row to set 1472 - 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 1473 1474 Notes: 1475 The values, v, are column-oriented for the block version. 1476 1477 All the nonzeros in the row must be provided 1478 1479 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1480 1481 The row must belong to this process 1482 1483 Level: advanced 1484 1485 Concepts: matrices^putting entries in 1486 1487 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1488 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1489 @*/ 1490 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1491 { 1492 PetscErrorCode ierr; 1493 1494 PetscFunctionBeginHot; 1495 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1496 PetscValidType(mat,1); 1497 MatCheckPreallocated(mat,1); 1498 PetscValidScalarPointer(v,2); 1499 #if defined(PETSC_USE_DEBUG) 1500 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1501 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1502 #endif 1503 mat->insertmode = INSERT_VALUES; 1504 1505 if (mat->assembled) { 1506 mat->was_assembled = PETSC_TRUE; 1507 mat->assembled = PETSC_FALSE; 1508 } 1509 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1510 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1511 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1512 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1513 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1514 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1515 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1516 } 1517 #endif 1518 PetscFunctionReturn(0); 1519 } 1520 1521 /*@ 1522 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1523 Using structured grid indexing 1524 1525 Not Collective 1526 1527 Input Parameters: 1528 + mat - the matrix 1529 . m - number of rows being entered 1530 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1531 . n - number of columns being entered 1532 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1533 . v - a logically two-dimensional array of values 1534 - addv - either ADD_VALUES or INSERT_VALUES, where 1535 ADD_VALUES adds values to any existing entries, and 1536 INSERT_VALUES replaces existing entries with new values 1537 1538 Notes: 1539 By default the values, v, are row-oriented. See MatSetOption() for other options. 1540 1541 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1542 options cannot be mixed without intervening calls to the assembly 1543 routines. 1544 1545 The grid coordinates are across the entire grid, not just the local portion 1546 1547 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1548 as well as in C. 1549 1550 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1551 1552 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1553 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1554 1555 The columns and rows in the stencil passed in MUST be contained within the 1556 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1557 if you create a DMDA with an overlap of one grid level and on a particular process its first 1558 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1559 first i index you can use in your column and row indices in MatSetStencil() is 5. 1560 1561 In Fortran idxm and idxn should be declared as 1562 $ MatStencil idxm(4,m),idxn(4,n) 1563 and the values inserted using 1564 $ idxm(MatStencil_i,1) = i 1565 $ idxm(MatStencil_j,1) = j 1566 $ idxm(MatStencil_k,1) = k 1567 $ idxm(MatStencil_c,1) = c 1568 etc 1569 1570 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1571 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1572 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1573 DM_BOUNDARY_PERIODIC boundary type. 1574 1575 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 1576 a single value per point) you can skip filling those indices. 1577 1578 Inspired by the structured grid interface to the HYPRE package 1579 (http://www.llnl.gov/CASC/hypre) 1580 1581 Efficiency Alert: 1582 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1583 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1584 1585 Level: beginner 1586 1587 Concepts: matrices^putting entries in 1588 1589 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1590 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1591 @*/ 1592 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1593 { 1594 PetscErrorCode ierr; 1595 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1596 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1597 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1598 1599 PetscFunctionBegin; 1600 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1601 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1602 PetscValidType(mat,1); 1603 PetscValidIntPointer(idxm,3); 1604 PetscValidIntPointer(idxn,5); 1605 PetscValidScalarPointer(v,6); 1606 1607 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1608 jdxm = buf; jdxn = buf+m; 1609 } else { 1610 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1611 jdxm = bufm; jdxn = bufn; 1612 } 1613 for (i=0; i<m; i++) { 1614 for (j=0; j<3-sdim; j++) dxm++; 1615 tmp = *dxm++ - starts[0]; 1616 for (j=0; j<dim-1; j++) { 1617 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1618 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1619 } 1620 if (mat->stencil.noc) dxm++; 1621 jdxm[i] = tmp; 1622 } 1623 for (i=0; i<n; i++) { 1624 for (j=0; j<3-sdim; j++) dxn++; 1625 tmp = *dxn++ - starts[0]; 1626 for (j=0; j<dim-1; j++) { 1627 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1628 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1629 } 1630 if (mat->stencil.noc) dxn++; 1631 jdxn[i] = tmp; 1632 } 1633 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1634 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1635 PetscFunctionReturn(0); 1636 } 1637 1638 /*@ 1639 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1640 Using structured grid indexing 1641 1642 Not Collective 1643 1644 Input Parameters: 1645 + mat - the matrix 1646 . m - number of rows being entered 1647 . idxm - grid coordinates for matrix rows being entered 1648 . n - number of columns being entered 1649 . idxn - grid coordinates for matrix columns being entered 1650 . v - a logically two-dimensional array of values 1651 - addv - either ADD_VALUES or INSERT_VALUES, where 1652 ADD_VALUES adds values to any existing entries, and 1653 INSERT_VALUES replaces existing entries with new values 1654 1655 Notes: 1656 By default the values, v, are row-oriented and unsorted. 1657 See MatSetOption() for other options. 1658 1659 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1660 options cannot be mixed without intervening calls to the assembly 1661 routines. 1662 1663 The grid coordinates are across the entire grid, not just the local portion 1664 1665 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1666 as well as in C. 1667 1668 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1669 1670 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1671 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1672 1673 The columns and rows in the stencil passed in MUST be contained within the 1674 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1675 if you create a DMDA with an overlap of one grid level and on a particular process its first 1676 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1677 first i index you can use in your column and row indices in MatSetStencil() is 5. 1678 1679 In Fortran idxm and idxn should be declared as 1680 $ MatStencil idxm(4,m),idxn(4,n) 1681 and the values inserted using 1682 $ idxm(MatStencil_i,1) = i 1683 $ idxm(MatStencil_j,1) = j 1684 $ idxm(MatStencil_k,1) = k 1685 etc 1686 1687 Negative indices may be passed in idxm and idxn, these rows and columns are 1688 simply ignored. This allows easily inserting element stiffness matrices 1689 with homogeneous Dirchlet boundary conditions that you don't want represented 1690 in the matrix. 1691 1692 Inspired by the structured grid interface to the HYPRE package 1693 (http://www.llnl.gov/CASC/hypre) 1694 1695 Level: beginner 1696 1697 Concepts: matrices^putting entries in 1698 1699 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1700 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1701 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1702 @*/ 1703 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1704 { 1705 PetscErrorCode ierr; 1706 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1707 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1708 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1709 1710 PetscFunctionBegin; 1711 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1712 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1713 PetscValidType(mat,1); 1714 PetscValidIntPointer(idxm,3); 1715 PetscValidIntPointer(idxn,5); 1716 PetscValidScalarPointer(v,6); 1717 1718 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1719 jdxm = buf; jdxn = buf+m; 1720 } else { 1721 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1722 jdxm = bufm; jdxn = bufn; 1723 } 1724 for (i=0; i<m; i++) { 1725 for (j=0; j<3-sdim; j++) dxm++; 1726 tmp = *dxm++ - starts[0]; 1727 for (j=0; j<sdim-1; j++) { 1728 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1729 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1730 } 1731 dxm++; 1732 jdxm[i] = tmp; 1733 } 1734 for (i=0; i<n; i++) { 1735 for (j=0; j<3-sdim; j++) dxn++; 1736 tmp = *dxn++ - starts[0]; 1737 for (j=0; j<sdim-1; j++) { 1738 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1739 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1740 } 1741 dxn++; 1742 jdxn[i] = tmp; 1743 } 1744 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1745 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1746 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1747 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1748 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1749 } 1750 #endif 1751 PetscFunctionReturn(0); 1752 } 1753 1754 /*@ 1755 MatSetStencil - Sets the grid information for setting values into a matrix via 1756 MatSetValuesStencil() 1757 1758 Not Collective 1759 1760 Input Parameters: 1761 + mat - the matrix 1762 . dim - dimension of the grid 1, 2, or 3 1763 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1764 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1765 - dof - number of degrees of freedom per node 1766 1767 1768 Inspired by the structured grid interface to the HYPRE package 1769 (www.llnl.gov/CASC/hyper) 1770 1771 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1772 user. 1773 1774 Level: beginner 1775 1776 Concepts: matrices^putting entries in 1777 1778 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1779 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1780 @*/ 1781 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1782 { 1783 PetscInt i; 1784 1785 PetscFunctionBegin; 1786 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1787 PetscValidIntPointer(dims,3); 1788 PetscValidIntPointer(starts,4); 1789 1790 mat->stencil.dim = dim + (dof > 1); 1791 for (i=0; i<dim; i++) { 1792 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1793 mat->stencil.starts[i] = starts[dim-i-1]; 1794 } 1795 mat->stencil.dims[dim] = dof; 1796 mat->stencil.starts[dim] = 0; 1797 mat->stencil.noc = (PetscBool)(dof == 1); 1798 PetscFunctionReturn(0); 1799 } 1800 1801 /*@C 1802 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1803 1804 Not Collective 1805 1806 Input Parameters: 1807 + mat - the matrix 1808 . v - a logically two-dimensional array of values 1809 . m, idxm - the number of block rows and their global block indices 1810 . n, idxn - the number of block columns and their global block indices 1811 - addv - either ADD_VALUES or INSERT_VALUES, where 1812 ADD_VALUES adds values to any existing entries, and 1813 INSERT_VALUES replaces existing entries with new values 1814 1815 Notes: 1816 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1817 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1818 1819 The m and n count the NUMBER of blocks in the row direction and column direction, 1820 NOT the total number of rows/columns; for example, if the block size is 2 and 1821 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1822 The values in idxm would be 1 2; that is the first index for each block divided by 1823 the block size. 1824 1825 Note that you must call MatSetBlockSize() when constructing this matrix (before 1826 preallocating it). 1827 1828 By default the values, v, are row-oriented, so the layout of 1829 v is the same as for MatSetValues(). See MatSetOption() for other options. 1830 1831 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1832 options cannot be mixed without intervening calls to the assembly 1833 routines. 1834 1835 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1836 as well as in C. 1837 1838 Negative indices may be passed in idxm and idxn, these rows and columns are 1839 simply ignored. This allows easily inserting element stiffness matrices 1840 with homogeneous Dirchlet boundary conditions that you don't want represented 1841 in the matrix. 1842 1843 Each time an entry is set within a sparse matrix via MatSetValues(), 1844 internal searching must be done to determine where to place the 1845 data in the matrix storage space. By instead inserting blocks of 1846 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1847 reduced. 1848 1849 Example: 1850 $ Suppose m=n=2 and block size(bs) = 2 The array is 1851 $ 1852 $ 1 2 | 3 4 1853 $ 5 6 | 7 8 1854 $ - - - | - - - 1855 $ 9 10 | 11 12 1856 $ 13 14 | 15 16 1857 $ 1858 $ v[] should be passed in like 1859 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1860 $ 1861 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1862 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1863 1864 Level: intermediate 1865 1866 Concepts: matrices^putting entries in blocked 1867 1868 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1869 @*/ 1870 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1871 { 1872 PetscErrorCode ierr; 1873 1874 PetscFunctionBeginHot; 1875 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1876 PetscValidType(mat,1); 1877 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1878 PetscValidIntPointer(idxm,3); 1879 PetscValidIntPointer(idxn,5); 1880 PetscValidScalarPointer(v,6); 1881 MatCheckPreallocated(mat,1); 1882 if (mat->insertmode == NOT_SET_VALUES) { 1883 mat->insertmode = addv; 1884 } 1885 #if defined(PETSC_USE_DEBUG) 1886 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1887 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1888 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1889 #endif 1890 1891 if (mat->assembled) { 1892 mat->was_assembled = PETSC_TRUE; 1893 mat->assembled = PETSC_FALSE; 1894 } 1895 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1896 if (mat->ops->setvaluesblocked) { 1897 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1898 } else { 1899 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1900 PetscInt i,j,bs,cbs; 1901 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1902 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1903 iidxm = buf; iidxn = buf + m*bs; 1904 } else { 1905 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1906 iidxm = bufr; iidxn = bufc; 1907 } 1908 for (i=0; i<m; i++) { 1909 for (j=0; j<bs; j++) { 1910 iidxm[i*bs+j] = bs*idxm[i] + j; 1911 } 1912 } 1913 for (i=0; i<n; i++) { 1914 for (j=0; j<cbs; j++) { 1915 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1916 } 1917 } 1918 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1919 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1920 } 1921 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1922 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1923 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1924 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1925 } 1926 #endif 1927 PetscFunctionReturn(0); 1928 } 1929 1930 /*@ 1931 MatGetValues - Gets a block of values from a matrix. 1932 1933 Not Collective; currently only returns a local block 1934 1935 Input Parameters: 1936 + mat - the matrix 1937 . v - a logically two-dimensional array for storing the values 1938 . m, idxm - the number of rows and their global indices 1939 - n, idxn - the number of columns and their global indices 1940 1941 Notes: 1942 The user must allocate space (m*n PetscScalars) for the values, v. 1943 The values, v, are then returned in a row-oriented format, 1944 analogous to that used by default in MatSetValues(). 1945 1946 MatGetValues() uses 0-based row and column numbers in 1947 Fortran as well as in C. 1948 1949 MatGetValues() requires that the matrix has been assembled 1950 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1951 MatSetValues() and MatGetValues() CANNOT be made in succession 1952 without intermediate matrix assembly. 1953 1954 Negative row or column indices will be ignored and those locations in v[] will be 1955 left unchanged. 1956 1957 Level: advanced 1958 1959 Concepts: matrices^accessing values 1960 1961 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1962 @*/ 1963 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1964 { 1965 PetscErrorCode ierr; 1966 1967 PetscFunctionBegin; 1968 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1969 PetscValidType(mat,1); 1970 if (!m || !n) PetscFunctionReturn(0); 1971 PetscValidIntPointer(idxm,3); 1972 PetscValidIntPointer(idxn,5); 1973 PetscValidScalarPointer(v,6); 1974 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1975 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1976 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1977 MatCheckPreallocated(mat,1); 1978 1979 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1980 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1981 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1982 PetscFunctionReturn(0); 1983 } 1984 1985 /*@ 1986 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1987 the same size. Currently, this can only be called once and creates the given matrix. 1988 1989 Not Collective 1990 1991 Input Parameters: 1992 + mat - the matrix 1993 . nb - the number of blocks 1994 . bs - the number of rows (and columns) in each block 1995 . rows - a concatenation of the rows for each block 1996 - v - a concatenation of logically two-dimensional arrays of values 1997 1998 Notes: 1999 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2000 2001 Level: advanced 2002 2003 Concepts: matrices^putting entries in 2004 2005 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 2006 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 2007 @*/ 2008 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2009 { 2010 PetscErrorCode ierr; 2011 2012 PetscFunctionBegin; 2013 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2014 PetscValidType(mat,1); 2015 PetscValidScalarPointer(rows,4); 2016 PetscValidScalarPointer(v,5); 2017 #if defined(PETSC_USE_DEBUG) 2018 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2019 #endif 2020 2021 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 2022 if (mat->ops->setvaluesbatch) { 2023 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 2024 } else { 2025 PetscInt b; 2026 for (b = 0; b < nb; ++b) { 2027 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 2028 } 2029 } 2030 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 2031 PetscFunctionReturn(0); 2032 } 2033 2034 /*@ 2035 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2036 the routine MatSetValuesLocal() to allow users to insert matrix entries 2037 using a local (per-processor) numbering. 2038 2039 Not Collective 2040 2041 Input Parameters: 2042 + x - the matrix 2043 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2044 - cmapping - column mapping 2045 2046 Level: intermediate 2047 2048 Concepts: matrices^local to global mapping 2049 Concepts: local to global mapping^for matrices 2050 2051 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 2052 @*/ 2053 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2054 { 2055 PetscErrorCode ierr; 2056 2057 PetscFunctionBegin; 2058 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2059 PetscValidType(x,1); 2060 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2061 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2062 2063 if (x->ops->setlocaltoglobalmapping) { 2064 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 2065 } else { 2066 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 2067 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 2068 } 2069 PetscFunctionReturn(0); 2070 } 2071 2072 2073 /*@ 2074 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2075 2076 Not Collective 2077 2078 Input Parameters: 2079 . A - the matrix 2080 2081 Output Parameters: 2082 + rmapping - row mapping 2083 - cmapping - column mapping 2084 2085 Level: advanced 2086 2087 Concepts: matrices^local to global mapping 2088 Concepts: local to global mapping^for matrices 2089 2090 .seealso: MatSetValuesLocal() 2091 @*/ 2092 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2093 { 2094 PetscFunctionBegin; 2095 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2096 PetscValidType(A,1); 2097 if (rmapping) PetscValidPointer(rmapping,2); 2098 if (cmapping) PetscValidPointer(cmapping,3); 2099 if (rmapping) *rmapping = A->rmap->mapping; 2100 if (cmapping) *cmapping = A->cmap->mapping; 2101 PetscFunctionReturn(0); 2102 } 2103 2104 /*@ 2105 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2106 2107 Not Collective 2108 2109 Input Parameters: 2110 . A - the matrix 2111 2112 Output Parameters: 2113 + rmap - row layout 2114 - cmap - column layout 2115 2116 Level: advanced 2117 2118 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2119 @*/ 2120 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2121 { 2122 PetscFunctionBegin; 2123 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2124 PetscValidType(A,1); 2125 if (rmap) PetscValidPointer(rmap,2); 2126 if (cmap) PetscValidPointer(cmap,3); 2127 if (rmap) *rmap = A->rmap; 2128 if (cmap) *cmap = A->cmap; 2129 PetscFunctionReturn(0); 2130 } 2131 2132 /*@C 2133 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2134 using a local ordering of the nodes. 2135 2136 Not Collective 2137 2138 Input Parameters: 2139 + mat - the matrix 2140 . nrow, irow - number of rows and their local indices 2141 . ncol, icol - number of columns and their local indices 2142 . y - a logically two-dimensional array of values 2143 - addv - either INSERT_VALUES or ADD_VALUES, where 2144 ADD_VALUES adds values to any existing entries, and 2145 INSERT_VALUES replaces existing entries with new values 2146 2147 Notes: 2148 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2149 MatSetUp() before using this routine 2150 2151 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2152 2153 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2154 options cannot be mixed without intervening calls to the assembly 2155 routines. 2156 2157 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2158 MUST be called after all calls to MatSetValuesLocal() have been completed. 2159 2160 Level: intermediate 2161 2162 Concepts: matrices^putting entries in with local numbering 2163 2164 Developer Notes: 2165 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2166 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2167 2168 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2169 MatSetValueLocal() 2170 @*/ 2171 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2172 { 2173 PetscErrorCode ierr; 2174 2175 PetscFunctionBeginHot; 2176 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2177 PetscValidType(mat,1); 2178 MatCheckPreallocated(mat,1); 2179 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2180 PetscValidIntPointer(irow,3); 2181 PetscValidIntPointer(icol,5); 2182 PetscValidScalarPointer(y,6); 2183 if (mat->insertmode == NOT_SET_VALUES) { 2184 mat->insertmode = addv; 2185 } 2186 #if defined(PETSC_USE_DEBUG) 2187 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2188 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2189 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2190 #endif 2191 2192 if (mat->assembled) { 2193 mat->was_assembled = PETSC_TRUE; 2194 mat->assembled = PETSC_FALSE; 2195 } 2196 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2197 if (mat->ops->setvalueslocal) { 2198 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2199 } else { 2200 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2201 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2202 irowm = buf; icolm = buf+nrow; 2203 } else { 2204 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2205 irowm = bufr; icolm = bufc; 2206 } 2207 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2208 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2209 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2210 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2211 } 2212 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2213 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2214 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2215 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2216 } 2217 #endif 2218 PetscFunctionReturn(0); 2219 } 2220 2221 /*@C 2222 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2223 using a local ordering of the nodes a block at a time. 2224 2225 Not Collective 2226 2227 Input Parameters: 2228 + x - the matrix 2229 . nrow, irow - number of rows and their local indices 2230 . ncol, icol - number of columns and their local indices 2231 . y - a logically two-dimensional array of values 2232 - addv - either INSERT_VALUES or ADD_VALUES, where 2233 ADD_VALUES adds values to any existing entries, and 2234 INSERT_VALUES replaces existing entries with new values 2235 2236 Notes: 2237 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2238 MatSetUp() before using this routine 2239 2240 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2241 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2242 2243 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2244 options cannot be mixed without intervening calls to the assembly 2245 routines. 2246 2247 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2248 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2249 2250 Level: intermediate 2251 2252 Developer Notes: 2253 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2254 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2255 2256 Concepts: matrices^putting blocked values in with local numbering 2257 2258 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2259 MatSetValuesLocal(), MatSetValuesBlocked() 2260 @*/ 2261 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2262 { 2263 PetscErrorCode ierr; 2264 2265 PetscFunctionBeginHot; 2266 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2267 PetscValidType(mat,1); 2268 MatCheckPreallocated(mat,1); 2269 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2270 PetscValidIntPointer(irow,3); 2271 PetscValidIntPointer(icol,5); 2272 PetscValidScalarPointer(y,6); 2273 if (mat->insertmode == NOT_SET_VALUES) { 2274 mat->insertmode = addv; 2275 } 2276 #if defined(PETSC_USE_DEBUG) 2277 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2278 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2279 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); 2280 #endif 2281 2282 if (mat->assembled) { 2283 mat->was_assembled = PETSC_TRUE; 2284 mat->assembled = PETSC_FALSE; 2285 } 2286 #if defined(PETSC_USE_DEBUG) 2287 /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2288 if (mat->rmap->mapping) { 2289 PetscInt irbs, rbs; 2290 ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr); 2291 ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr); 2292 if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs); 2293 } 2294 if (mat->cmap->mapping) { 2295 PetscInt icbs, cbs; 2296 ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr); 2297 ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr); 2298 if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs); 2299 } 2300 #endif 2301 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2302 if (mat->ops->setvaluesblockedlocal) { 2303 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2304 } else { 2305 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2306 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2307 irowm = buf; icolm = buf + nrow; 2308 } else { 2309 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2310 irowm = bufr; icolm = bufc; 2311 } 2312 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2313 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2314 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2315 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2316 } 2317 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2318 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2319 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2320 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2321 } 2322 #endif 2323 PetscFunctionReturn(0); 2324 } 2325 2326 /*@ 2327 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2328 2329 Collective on Mat and Vec 2330 2331 Input Parameters: 2332 + mat - the matrix 2333 - x - the vector to be multiplied 2334 2335 Output Parameters: 2336 . y - the result 2337 2338 Notes: 2339 The vectors x and y cannot be the same. I.e., one cannot 2340 call MatMult(A,y,y). 2341 2342 Level: developer 2343 2344 Concepts: matrix-vector product 2345 2346 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2347 @*/ 2348 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2349 { 2350 PetscErrorCode ierr; 2351 2352 PetscFunctionBegin; 2353 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2354 PetscValidType(mat,1); 2355 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2356 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2357 2358 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2359 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2360 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2361 MatCheckPreallocated(mat,1); 2362 2363 if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2364 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2365 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2366 PetscFunctionReturn(0); 2367 } 2368 2369 /* --------------------------------------------------------*/ 2370 /*@ 2371 MatMult - Computes the matrix-vector product, y = Ax. 2372 2373 Neighbor-wise Collective on Mat and Vec 2374 2375 Input Parameters: 2376 + mat - the matrix 2377 - x - the vector to be multiplied 2378 2379 Output Parameters: 2380 . y - the result 2381 2382 Notes: 2383 The vectors x and y cannot be the same. I.e., one cannot 2384 call MatMult(A,y,y). 2385 2386 Level: beginner 2387 2388 Concepts: matrix-vector product 2389 2390 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2391 @*/ 2392 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2393 { 2394 PetscErrorCode ierr; 2395 2396 PetscFunctionBegin; 2397 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2398 PetscValidType(mat,1); 2399 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2400 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2401 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2402 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2403 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2404 #if !defined(PETSC_HAVE_CONSTRAINTS) 2405 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); 2406 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); 2407 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); 2408 #endif 2409 ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr); 2410 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2411 MatCheckPreallocated(mat,1); 2412 2413 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2414 if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2415 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2416 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2417 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2418 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2419 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2420 PetscFunctionReturn(0); 2421 } 2422 2423 /*@ 2424 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2425 2426 Neighbor-wise Collective on Mat and Vec 2427 2428 Input Parameters: 2429 + mat - the matrix 2430 - x - the vector to be multiplied 2431 2432 Output Parameters: 2433 . y - the result 2434 2435 Notes: 2436 The vectors x and y cannot be the same. I.e., one cannot 2437 call MatMultTranspose(A,y,y). 2438 2439 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2440 use MatMultHermitianTranspose() 2441 2442 Level: beginner 2443 2444 Concepts: matrix vector product^transpose 2445 2446 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2447 @*/ 2448 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2449 { 2450 PetscErrorCode ierr; 2451 2452 PetscFunctionBegin; 2453 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2454 PetscValidType(mat,1); 2455 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2456 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2457 2458 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2459 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2460 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2461 #if !defined(PETSC_HAVE_CONSTRAINTS) 2462 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); 2463 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); 2464 #endif 2465 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2466 MatCheckPreallocated(mat,1); 2467 2468 if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined"); 2469 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2470 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2471 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2472 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2473 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2474 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2475 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2476 PetscFunctionReturn(0); 2477 } 2478 2479 /*@ 2480 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2481 2482 Neighbor-wise Collective on Mat and Vec 2483 2484 Input Parameters: 2485 + mat - the matrix 2486 - x - the vector to be multilplied 2487 2488 Output Parameters: 2489 . y - the result 2490 2491 Notes: 2492 The vectors x and y cannot be the same. I.e., one cannot 2493 call MatMultHermitianTranspose(A,y,y). 2494 2495 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2496 2497 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2498 2499 Level: beginner 2500 2501 Concepts: matrix vector product^transpose 2502 2503 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2504 @*/ 2505 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2506 { 2507 PetscErrorCode ierr; 2508 Vec w; 2509 2510 PetscFunctionBegin; 2511 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2512 PetscValidType(mat,1); 2513 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2514 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2515 2516 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2517 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2518 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2519 #if !defined(PETSC_HAVE_CONSTRAINTS) 2520 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); 2521 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); 2522 #endif 2523 MatCheckPreallocated(mat,1); 2524 2525 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2526 if (mat->ops->multhermitiantranspose) { 2527 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2528 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2529 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2530 } else { 2531 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2532 ierr = VecCopy(x,w);CHKERRQ(ierr); 2533 ierr = VecConjugate(w);CHKERRQ(ierr); 2534 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2535 ierr = VecDestroy(&w);CHKERRQ(ierr); 2536 ierr = VecConjugate(y);CHKERRQ(ierr); 2537 } 2538 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2539 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2540 PetscFunctionReturn(0); 2541 } 2542 2543 /*@ 2544 MatMultAdd - Computes v3 = v2 + A * v1. 2545 2546 Neighbor-wise Collective on Mat and Vec 2547 2548 Input Parameters: 2549 + mat - the matrix 2550 - v1, v2 - the vectors 2551 2552 Output Parameters: 2553 . v3 - the result 2554 2555 Notes: 2556 The vectors v1 and v3 cannot be the same. I.e., one cannot 2557 call MatMultAdd(A,v1,v2,v1). 2558 2559 Level: beginner 2560 2561 Concepts: matrix vector product^addition 2562 2563 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2564 @*/ 2565 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2566 { 2567 PetscErrorCode ierr; 2568 2569 PetscFunctionBegin; 2570 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2571 PetscValidType(mat,1); 2572 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2573 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2574 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2575 2576 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2577 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2578 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); 2579 /* 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); 2580 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); */ 2581 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); 2582 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); 2583 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2584 MatCheckPreallocated(mat,1); 2585 2586 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2587 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2588 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2589 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2590 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2591 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2592 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2593 PetscFunctionReturn(0); 2594 } 2595 2596 /*@ 2597 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2598 2599 Neighbor-wise Collective on Mat and Vec 2600 2601 Input Parameters: 2602 + mat - the matrix 2603 - v1, v2 - the vectors 2604 2605 Output Parameters: 2606 . v3 - the result 2607 2608 Notes: 2609 The vectors v1 and v3 cannot be the same. I.e., one cannot 2610 call MatMultTransposeAdd(A,v1,v2,v1). 2611 2612 Level: beginner 2613 2614 Concepts: matrix vector product^transpose and addition 2615 2616 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2617 @*/ 2618 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2619 { 2620 PetscErrorCode ierr; 2621 2622 PetscFunctionBegin; 2623 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2624 PetscValidType(mat,1); 2625 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2626 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2627 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2628 2629 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2630 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2631 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2632 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2633 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); 2634 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); 2635 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); 2636 MatCheckPreallocated(mat,1); 2637 2638 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2639 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2640 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2641 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2642 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2643 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2644 PetscFunctionReturn(0); 2645 } 2646 2647 /*@ 2648 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2649 2650 Neighbor-wise Collective on Mat and Vec 2651 2652 Input Parameters: 2653 + mat - the matrix 2654 - v1, v2 - the vectors 2655 2656 Output Parameters: 2657 . v3 - the result 2658 2659 Notes: 2660 The vectors v1 and v3 cannot be the same. I.e., one cannot 2661 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2662 2663 Level: beginner 2664 2665 Concepts: matrix vector product^transpose and addition 2666 2667 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2668 @*/ 2669 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2670 { 2671 PetscErrorCode ierr; 2672 2673 PetscFunctionBegin; 2674 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2675 PetscValidType(mat,1); 2676 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2677 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2678 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2679 2680 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2681 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2682 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2683 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); 2684 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); 2685 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); 2686 MatCheckPreallocated(mat,1); 2687 2688 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2689 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2690 if (mat->ops->multhermitiantransposeadd) { 2691 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2692 } else { 2693 Vec w,z; 2694 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2695 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2696 ierr = VecConjugate(w);CHKERRQ(ierr); 2697 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2698 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2699 ierr = VecDestroy(&w);CHKERRQ(ierr); 2700 ierr = VecConjugate(z);CHKERRQ(ierr); 2701 if (v2 != v3) { 2702 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2703 } else { 2704 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2705 } 2706 ierr = VecDestroy(&z);CHKERRQ(ierr); 2707 } 2708 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2709 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2710 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2711 PetscFunctionReturn(0); 2712 } 2713 2714 /*@ 2715 MatMultConstrained - The inner multiplication routine for a 2716 constrained matrix P^T A P. 2717 2718 Neighbor-wise Collective on Mat and Vec 2719 2720 Input Parameters: 2721 + mat - the matrix 2722 - x - the vector to be multilplied 2723 2724 Output Parameters: 2725 . y - the result 2726 2727 Notes: 2728 The vectors x and y cannot be the same. I.e., one cannot 2729 call MatMult(A,y,y). 2730 2731 Level: beginner 2732 2733 .keywords: matrix, multiply, matrix-vector product, constraint 2734 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2735 @*/ 2736 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2737 { 2738 PetscErrorCode ierr; 2739 2740 PetscFunctionBegin; 2741 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2742 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2743 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2744 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2745 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2746 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2747 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); 2748 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); 2749 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); 2750 2751 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2752 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2753 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2754 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2755 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2756 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2757 PetscFunctionReturn(0); 2758 } 2759 2760 /*@ 2761 MatMultTransposeConstrained - The inner multiplication routine for a 2762 constrained matrix P^T A^T P. 2763 2764 Neighbor-wise Collective on Mat and Vec 2765 2766 Input Parameters: 2767 + mat - the matrix 2768 - x - the vector to be multilplied 2769 2770 Output Parameters: 2771 . y - the result 2772 2773 Notes: 2774 The vectors x and y cannot be the same. I.e., one cannot 2775 call MatMult(A,y,y). 2776 2777 Level: beginner 2778 2779 .keywords: matrix, multiply, matrix-vector product, constraint 2780 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2781 @*/ 2782 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2783 { 2784 PetscErrorCode ierr; 2785 2786 PetscFunctionBegin; 2787 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2788 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2789 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2790 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2791 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2792 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2793 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); 2794 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); 2795 2796 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2797 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2798 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2799 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2800 PetscFunctionReturn(0); 2801 } 2802 2803 /*@C 2804 MatGetFactorType - gets the type of factorization it is 2805 2806 Not Collective 2807 2808 Input Parameters: 2809 . mat - the matrix 2810 2811 Output Parameters: 2812 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2813 2814 Level: intermediate 2815 2816 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType() 2817 @*/ 2818 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2819 { 2820 PetscFunctionBegin; 2821 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2822 PetscValidType(mat,1); 2823 PetscValidPointer(t,2); 2824 *t = mat->factortype; 2825 PetscFunctionReturn(0); 2826 } 2827 2828 /*@C 2829 MatSetFactorType - sets the type of factorization it is 2830 2831 Logically Collective on Mat 2832 2833 Input Parameters: 2834 + mat - the matrix 2835 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2836 2837 Level: intermediate 2838 2839 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2840 @*/ 2841 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2842 { 2843 PetscFunctionBegin; 2844 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2845 PetscValidType(mat,1); 2846 mat->factortype = t; 2847 PetscFunctionReturn(0); 2848 } 2849 2850 /* ------------------------------------------------------------*/ 2851 /*@C 2852 MatGetInfo - Returns information about matrix storage (number of 2853 nonzeros, memory, etc.). 2854 2855 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2856 2857 Input Parameters: 2858 . mat - the matrix 2859 2860 Output Parameters: 2861 + flag - flag indicating the type of parameters to be returned 2862 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2863 MAT_GLOBAL_SUM - sum over all processors) 2864 - info - matrix information context 2865 2866 Notes: 2867 The MatInfo context contains a variety of matrix data, including 2868 number of nonzeros allocated and used, number of mallocs during 2869 matrix assembly, etc. Additional information for factored matrices 2870 is provided (such as the fill ratio, number of mallocs during 2871 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2872 when using the runtime options 2873 $ -info -mat_view ::ascii_info 2874 2875 Example for C/C++ Users: 2876 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2877 data within the MatInfo context. For example, 2878 .vb 2879 MatInfo info; 2880 Mat A; 2881 double mal, nz_a, nz_u; 2882 2883 MatGetInfo(A,MAT_LOCAL,&info); 2884 mal = info.mallocs; 2885 nz_a = info.nz_allocated; 2886 .ve 2887 2888 Example for Fortran Users: 2889 Fortran users should declare info as a double precision 2890 array of dimension MAT_INFO_SIZE, and then extract the parameters 2891 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2892 a complete list of parameter names. 2893 .vb 2894 double precision info(MAT_INFO_SIZE) 2895 double precision mal, nz_a 2896 Mat A 2897 integer ierr 2898 2899 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2900 mal = info(MAT_INFO_MALLOCS) 2901 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2902 .ve 2903 2904 Level: intermediate 2905 2906 Concepts: matrices^getting information on 2907 2908 Developer Note: fortran interface is not autogenerated as the f90 2909 interface defintion cannot be generated correctly [due to MatInfo] 2910 2911 .seealso: MatStashGetInfo() 2912 2913 @*/ 2914 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2915 { 2916 PetscErrorCode ierr; 2917 2918 PetscFunctionBegin; 2919 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2920 PetscValidType(mat,1); 2921 PetscValidPointer(info,3); 2922 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2923 MatCheckPreallocated(mat,1); 2924 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2925 PetscFunctionReturn(0); 2926 } 2927 2928 /* 2929 This is used by external packages where it is not easy to get the info from the actual 2930 matrix factorization. 2931 */ 2932 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2933 { 2934 PetscErrorCode ierr; 2935 2936 PetscFunctionBegin; 2937 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2938 PetscFunctionReturn(0); 2939 } 2940 2941 /* ----------------------------------------------------------*/ 2942 2943 /*@C 2944 MatLUFactor - Performs in-place LU factorization of matrix. 2945 2946 Collective on Mat 2947 2948 Input Parameters: 2949 + mat - the matrix 2950 . row - row permutation 2951 . col - column permutation 2952 - info - options for factorization, includes 2953 $ fill - expected fill as ratio of original fill. 2954 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2955 $ Run with the option -info to determine an optimal value to use 2956 2957 Notes: 2958 Most users should employ the simplified KSP interface for linear solvers 2959 instead of working directly with matrix algebra routines such as this. 2960 See, e.g., KSPCreate(). 2961 2962 This changes the state of the matrix to a factored matrix; it cannot be used 2963 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2964 2965 Level: developer 2966 2967 Concepts: matrices^LU factorization 2968 2969 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2970 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2971 2972 Developer Note: fortran interface is not autogenerated as the f90 2973 interface defintion cannot be generated correctly [due to MatFactorInfo] 2974 2975 @*/ 2976 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2977 { 2978 PetscErrorCode ierr; 2979 MatFactorInfo tinfo; 2980 2981 PetscFunctionBegin; 2982 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2983 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2984 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2985 if (info) PetscValidPointer(info,4); 2986 PetscValidType(mat,1); 2987 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2988 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2989 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2990 MatCheckPreallocated(mat,1); 2991 if (!info) { 2992 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2993 info = &tinfo; 2994 } 2995 2996 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2997 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2998 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2999 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3000 PetscFunctionReturn(0); 3001 } 3002 3003 /*@C 3004 MatILUFactor - Performs in-place ILU factorization of matrix. 3005 3006 Collective on Mat 3007 3008 Input Parameters: 3009 + mat - the matrix 3010 . row - row permutation 3011 . col - column permutation 3012 - info - structure containing 3013 $ levels - number of levels of fill. 3014 $ expected fill - as ratio of original fill. 3015 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 3016 missing diagonal entries) 3017 3018 Notes: 3019 Probably really in-place only when level of fill is zero, otherwise allocates 3020 new space to store factored matrix and deletes previous memory. 3021 3022 Most users should employ the simplified KSP interface for linear solvers 3023 instead of working directly with matrix algebra routines such as this. 3024 See, e.g., KSPCreate(). 3025 3026 Level: developer 3027 3028 Concepts: matrices^ILU factorization 3029 3030 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 3031 3032 Developer Note: fortran interface is not autogenerated as the f90 3033 interface defintion cannot be generated correctly [due to MatFactorInfo] 3034 3035 @*/ 3036 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3037 { 3038 PetscErrorCode ierr; 3039 3040 PetscFunctionBegin; 3041 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3042 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3043 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3044 PetscValidPointer(info,4); 3045 PetscValidType(mat,1); 3046 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3047 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3048 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3049 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3050 MatCheckPreallocated(mat,1); 3051 3052 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 3053 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 3054 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 3055 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3056 PetscFunctionReturn(0); 3057 } 3058 3059 /*@C 3060 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3061 Call this routine before calling MatLUFactorNumeric(). 3062 3063 Collective on Mat 3064 3065 Input Parameters: 3066 + fact - the factor matrix obtained with MatGetFactor() 3067 . mat - the matrix 3068 . row, col - row and column permutations 3069 - info - options for factorization, includes 3070 $ fill - expected fill as ratio of original fill. 3071 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3072 $ Run with the option -info to determine an optimal value to use 3073 3074 3075 Notes: 3076 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3077 3078 Most users should employ the simplified KSP interface for linear solvers 3079 instead of working directly with matrix algebra routines such as this. 3080 See, e.g., KSPCreate(). 3081 3082 Level: developer 3083 3084 Concepts: matrices^LU symbolic factorization 3085 3086 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 3087 3088 Developer Note: fortran interface is not autogenerated as the f90 3089 interface defintion cannot be generated correctly [due to MatFactorInfo] 3090 3091 @*/ 3092 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3093 { 3094 PetscErrorCode ierr; 3095 3096 PetscFunctionBegin; 3097 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3098 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3099 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3100 if (info) PetscValidPointer(info,4); 3101 PetscValidType(mat,1); 3102 PetscValidPointer(fact,5); 3103 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3104 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3105 if (!(fact)->ops->lufactorsymbolic) { 3106 MatSolverType spackage; 3107 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3108 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 3109 } 3110 MatCheckPreallocated(mat,2); 3111 3112 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3113 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3114 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3115 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3116 PetscFunctionReturn(0); 3117 } 3118 3119 /*@C 3120 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3121 Call this routine after first calling MatLUFactorSymbolic(). 3122 3123 Collective on Mat 3124 3125 Input Parameters: 3126 + fact - the factor matrix obtained with MatGetFactor() 3127 . mat - the matrix 3128 - info - options for factorization 3129 3130 Notes: 3131 See MatLUFactor() for in-place factorization. See 3132 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3133 3134 Most users should employ the simplified KSP interface for linear solvers 3135 instead of working directly with matrix algebra routines such as this. 3136 See, e.g., KSPCreate(). 3137 3138 Level: developer 3139 3140 Concepts: matrices^LU numeric factorization 3141 3142 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3143 3144 Developer Note: fortran interface is not autogenerated as the f90 3145 interface defintion cannot be generated correctly [due to MatFactorInfo] 3146 3147 @*/ 3148 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3149 { 3150 PetscErrorCode ierr; 3151 3152 PetscFunctionBegin; 3153 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3154 PetscValidType(mat,1); 3155 PetscValidPointer(fact,2); 3156 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3157 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3158 if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3159 3160 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3161 MatCheckPreallocated(mat,2); 3162 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3163 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3164 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3165 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3166 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3167 PetscFunctionReturn(0); 3168 } 3169 3170 /*@C 3171 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3172 symmetric matrix. 3173 3174 Collective on Mat 3175 3176 Input Parameters: 3177 + mat - the matrix 3178 . perm - row and column permutations 3179 - f - expected fill as ratio of original fill 3180 3181 Notes: 3182 See MatLUFactor() for the nonsymmetric case. See also 3183 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3184 3185 Most users should employ the simplified KSP interface for linear solvers 3186 instead of working directly with matrix algebra routines such as this. 3187 See, e.g., KSPCreate(). 3188 3189 Level: developer 3190 3191 Concepts: matrices^Cholesky factorization 3192 3193 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3194 MatGetOrdering() 3195 3196 Developer Note: fortran interface is not autogenerated as the f90 3197 interface defintion cannot be generated correctly [due to MatFactorInfo] 3198 3199 @*/ 3200 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3201 { 3202 PetscErrorCode ierr; 3203 3204 PetscFunctionBegin; 3205 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3206 PetscValidType(mat,1); 3207 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3208 if (info) PetscValidPointer(info,3); 3209 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3210 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3211 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3212 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); 3213 MatCheckPreallocated(mat,1); 3214 3215 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3216 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3217 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3218 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3219 PetscFunctionReturn(0); 3220 } 3221 3222 /*@C 3223 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3224 of a symmetric matrix. 3225 3226 Collective on Mat 3227 3228 Input Parameters: 3229 + fact - the factor matrix obtained with MatGetFactor() 3230 . mat - the matrix 3231 . perm - row and column permutations 3232 - info - options for factorization, includes 3233 $ fill - expected fill as ratio of original fill. 3234 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3235 $ Run with the option -info to determine an optimal value to use 3236 3237 Notes: 3238 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3239 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3240 3241 Most users should employ the simplified KSP interface for linear solvers 3242 instead of working directly with matrix algebra routines such as this. 3243 See, e.g., KSPCreate(). 3244 3245 Level: developer 3246 3247 Concepts: matrices^Cholesky symbolic factorization 3248 3249 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3250 MatGetOrdering() 3251 3252 Developer Note: fortran interface is not autogenerated as the f90 3253 interface defintion cannot be generated correctly [due to MatFactorInfo] 3254 3255 @*/ 3256 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3257 { 3258 PetscErrorCode ierr; 3259 3260 PetscFunctionBegin; 3261 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3262 PetscValidType(mat,1); 3263 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3264 if (info) PetscValidPointer(info,3); 3265 PetscValidPointer(fact,4); 3266 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3267 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3268 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3269 if (!(fact)->ops->choleskyfactorsymbolic) { 3270 MatSolverType spackage; 3271 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3272 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3273 } 3274 MatCheckPreallocated(mat,2); 3275 3276 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3277 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3278 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3279 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3280 PetscFunctionReturn(0); 3281 } 3282 3283 /*@C 3284 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3285 of a symmetric matrix. Call this routine after first calling 3286 MatCholeskyFactorSymbolic(). 3287 3288 Collective on Mat 3289 3290 Input Parameters: 3291 + fact - the factor matrix obtained with MatGetFactor() 3292 . mat - the initial matrix 3293 . info - options for factorization 3294 - fact - the symbolic factor of mat 3295 3296 3297 Notes: 3298 Most users should employ the simplified KSP interface for linear solvers 3299 instead of working directly with matrix algebra routines such as this. 3300 See, e.g., KSPCreate(). 3301 3302 Level: developer 3303 3304 Concepts: matrices^Cholesky numeric factorization 3305 3306 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3307 3308 Developer Note: fortran interface is not autogenerated as the f90 3309 interface defintion cannot be generated correctly [due to MatFactorInfo] 3310 3311 @*/ 3312 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3313 { 3314 PetscErrorCode ierr; 3315 3316 PetscFunctionBegin; 3317 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3318 PetscValidType(mat,1); 3319 PetscValidPointer(fact,2); 3320 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3321 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3322 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3323 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); 3324 MatCheckPreallocated(mat,2); 3325 3326 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3327 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3328 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3329 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3330 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3331 PetscFunctionReturn(0); 3332 } 3333 3334 /* ----------------------------------------------------------------*/ 3335 /*@ 3336 MatSolve - Solves A x = b, given a factored matrix. 3337 3338 Neighbor-wise Collective on Mat and Vec 3339 3340 Input Parameters: 3341 + mat - the factored matrix 3342 - b - the right-hand-side vector 3343 3344 Output Parameter: 3345 . x - the result vector 3346 3347 Notes: 3348 The vectors b and x cannot be the same. I.e., one cannot 3349 call MatSolve(A,x,x). 3350 3351 Notes: 3352 Most users should employ the simplified KSP interface for linear solvers 3353 instead of working directly with matrix algebra routines such as this. 3354 See, e.g., KSPCreate(). 3355 3356 Level: developer 3357 3358 Concepts: matrices^triangular solves 3359 3360 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3361 @*/ 3362 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3363 { 3364 PetscErrorCode ierr; 3365 3366 PetscFunctionBegin; 3367 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3368 PetscValidType(mat,1); 3369 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3370 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3371 PetscCheckSameComm(mat,1,b,2); 3372 PetscCheckSameComm(mat,1,x,3); 3373 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3374 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); 3375 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); 3376 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); 3377 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3378 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3379 MatCheckPreallocated(mat,1); 3380 3381 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3382 if (mat->factorerrortype) { 3383 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3384 ierr = VecSetInf(x);CHKERRQ(ierr); 3385 } else { 3386 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3387 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3388 } 3389 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3390 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3391 PetscFunctionReturn(0); 3392 } 3393 3394 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans) 3395 { 3396 PetscErrorCode ierr; 3397 Vec b,x; 3398 PetscInt m,N,i; 3399 PetscScalar *bb,*xx; 3400 PetscBool flg; 3401 3402 PetscFunctionBegin; 3403 ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3404 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 3405 ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3406 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); 3407 3408 ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr); 3409 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3410 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3411 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3412 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3413 for (i=0; i<N; i++) { 3414 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3415 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3416 if (trans) { 3417 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3418 } else { 3419 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3420 } 3421 ierr = VecResetArray(x);CHKERRQ(ierr); 3422 ierr = VecResetArray(b);CHKERRQ(ierr); 3423 } 3424 ierr = VecDestroy(&b);CHKERRQ(ierr); 3425 ierr = VecDestroy(&x);CHKERRQ(ierr); 3426 ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr); 3427 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3428 PetscFunctionReturn(0); 3429 } 3430 3431 /*@ 3432 MatMatSolve - Solves A X = B, given a factored matrix. 3433 3434 Neighbor-wise Collective on Mat 3435 3436 Input Parameters: 3437 + A - the factored matrix 3438 - B - the right-hand-side matrix (dense matrix) 3439 3440 Output Parameter: 3441 . X - the result matrix (dense matrix) 3442 3443 Notes: 3444 The matrices b and x cannot be the same. I.e., one cannot 3445 call MatMatSolve(A,x,x). 3446 3447 Notes: 3448 Most users should usually employ the simplified KSP interface for linear solvers 3449 instead of working directly with matrix algebra routines such as this. 3450 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3451 at a time. 3452 3453 When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 3454 it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides. 3455 3456 Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B. 3457 3458 Level: developer 3459 3460 Concepts: matrices^triangular solves 3461 3462 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3463 @*/ 3464 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3465 { 3466 PetscErrorCode ierr; 3467 3468 PetscFunctionBegin; 3469 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3470 PetscValidType(A,1); 3471 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3472 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3473 PetscCheckSameComm(A,1,B,2); 3474 PetscCheckSameComm(A,1,X,3); 3475 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3476 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); 3477 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); 3478 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"); 3479 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3480 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3481 MatCheckPreallocated(A,1); 3482 3483 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3484 if (!A->ops->matsolve) { 3485 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3486 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3487 } else { 3488 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3489 } 3490 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3491 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3492 PetscFunctionReturn(0); 3493 } 3494 3495 /*@ 3496 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3497 3498 Neighbor-wise Collective on Mat 3499 3500 Input Parameters: 3501 + A - the factored matrix 3502 - B - the right-hand-side matrix (dense matrix) 3503 3504 Output Parameter: 3505 . X - the result matrix (dense matrix) 3506 3507 Notes: 3508 The matrices B and X cannot be the same. I.e., one cannot 3509 call MatMatSolveTranspose(A,X,X). 3510 3511 Notes: 3512 Most users should usually employ the simplified KSP interface for linear solvers 3513 instead of working directly with matrix algebra routines such as this. 3514 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3515 at a time. 3516 3517 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3518 3519 Level: developer 3520 3521 Concepts: matrices^triangular solves 3522 3523 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3524 @*/ 3525 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3526 { 3527 PetscErrorCode ierr; 3528 3529 PetscFunctionBegin; 3530 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3531 PetscValidType(A,1); 3532 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3533 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3534 PetscCheckSameComm(A,1,B,2); 3535 PetscCheckSameComm(A,1,X,3); 3536 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3537 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); 3538 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); 3539 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); 3540 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"); 3541 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3542 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3543 MatCheckPreallocated(A,1); 3544 3545 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3546 if (!A->ops->matsolvetranspose) { 3547 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3548 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3549 } else { 3550 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3551 } 3552 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3553 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3554 PetscFunctionReturn(0); 3555 } 3556 3557 /*@ 3558 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3559 3560 Neighbor-wise Collective on Mat 3561 3562 Input Parameters: 3563 + A - the factored matrix 3564 - Bt - the transpose of right-hand-side matrix 3565 3566 Output Parameter: 3567 . X - the result matrix (dense matrix) 3568 3569 Notes: 3570 Most users should usually employ the simplified KSP interface for linear solvers 3571 instead of working directly with matrix algebra routines such as this. 3572 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3573 at a time. 3574 3575 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(). 3576 3577 Level: developer 3578 3579 Concepts: matrices^triangular solves 3580 3581 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3582 @*/ 3583 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3584 { 3585 PetscErrorCode ierr; 3586 3587 PetscFunctionBegin; 3588 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3589 PetscValidType(A,1); 3590 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3591 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3592 PetscCheckSameComm(A,1,Bt,2); 3593 PetscCheckSameComm(A,1,X,3); 3594 3595 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3596 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); 3597 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); 3598 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"); 3599 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3600 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3601 MatCheckPreallocated(A,1); 3602 3603 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3604 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3605 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3606 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3607 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3608 PetscFunctionReturn(0); 3609 } 3610 3611 /*@ 3612 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3613 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3614 3615 Neighbor-wise Collective on Mat and Vec 3616 3617 Input Parameters: 3618 + mat - the factored matrix 3619 - b - the right-hand-side vector 3620 3621 Output Parameter: 3622 . x - the result vector 3623 3624 Notes: 3625 MatSolve() should be used for most applications, as it performs 3626 a forward solve followed by a backward solve. 3627 3628 The vectors b and x cannot be the same, i.e., one cannot 3629 call MatForwardSolve(A,x,x). 3630 3631 For matrix in seqsbaij format with block size larger than 1, 3632 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3633 MatForwardSolve() solves U^T*D y = b, and 3634 MatBackwardSolve() solves U x = y. 3635 Thus they do not provide a symmetric preconditioner. 3636 3637 Most users should employ the simplified KSP interface for linear solvers 3638 instead of working directly with matrix algebra routines such as this. 3639 See, e.g., KSPCreate(). 3640 3641 Level: developer 3642 3643 Concepts: matrices^forward solves 3644 3645 .seealso: MatSolve(), MatBackwardSolve() 3646 @*/ 3647 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3648 { 3649 PetscErrorCode ierr; 3650 3651 PetscFunctionBegin; 3652 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3653 PetscValidType(mat,1); 3654 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3655 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3656 PetscCheckSameComm(mat,1,b,2); 3657 PetscCheckSameComm(mat,1,x,3); 3658 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3659 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); 3660 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); 3661 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); 3662 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3663 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3664 MatCheckPreallocated(mat,1); 3665 3666 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3667 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3668 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3669 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3670 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3671 PetscFunctionReturn(0); 3672 } 3673 3674 /*@ 3675 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3676 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3677 3678 Neighbor-wise Collective on Mat and Vec 3679 3680 Input Parameters: 3681 + mat - the factored matrix 3682 - b - the right-hand-side vector 3683 3684 Output Parameter: 3685 . x - the result vector 3686 3687 Notes: 3688 MatSolve() should be used for most applications, as it performs 3689 a forward solve followed by a backward solve. 3690 3691 The vectors b and x cannot be the same. I.e., one cannot 3692 call MatBackwardSolve(A,x,x). 3693 3694 For matrix in seqsbaij format with block size larger than 1, 3695 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3696 MatForwardSolve() solves U^T*D y = b, and 3697 MatBackwardSolve() solves U x = y. 3698 Thus they do not provide a symmetric preconditioner. 3699 3700 Most users should employ the simplified KSP interface for linear solvers 3701 instead of working directly with matrix algebra routines such as this. 3702 See, e.g., KSPCreate(). 3703 3704 Level: developer 3705 3706 Concepts: matrices^backward solves 3707 3708 .seealso: MatSolve(), MatForwardSolve() 3709 @*/ 3710 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3711 { 3712 PetscErrorCode ierr; 3713 3714 PetscFunctionBegin; 3715 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3716 PetscValidType(mat,1); 3717 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3718 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3719 PetscCheckSameComm(mat,1,b,2); 3720 PetscCheckSameComm(mat,1,x,3); 3721 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3722 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); 3723 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); 3724 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); 3725 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3726 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3727 MatCheckPreallocated(mat,1); 3728 3729 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3730 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3731 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3732 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3733 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3734 PetscFunctionReturn(0); 3735 } 3736 3737 /*@ 3738 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3739 3740 Neighbor-wise Collective on Mat and Vec 3741 3742 Input Parameters: 3743 + mat - the factored matrix 3744 . b - the right-hand-side vector 3745 - y - the vector to be added to 3746 3747 Output Parameter: 3748 . x - the result vector 3749 3750 Notes: 3751 The vectors b and x cannot be the same. I.e., one cannot 3752 call MatSolveAdd(A,x,y,x). 3753 3754 Most users should employ the simplified KSP interface for linear solvers 3755 instead of working directly with matrix algebra routines such as this. 3756 See, e.g., KSPCreate(). 3757 3758 Level: developer 3759 3760 Concepts: matrices^triangular solves 3761 3762 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3763 @*/ 3764 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3765 { 3766 PetscScalar one = 1.0; 3767 Vec tmp; 3768 PetscErrorCode ierr; 3769 3770 PetscFunctionBegin; 3771 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3772 PetscValidType(mat,1); 3773 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3774 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3775 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3776 PetscCheckSameComm(mat,1,b,2); 3777 PetscCheckSameComm(mat,1,y,2); 3778 PetscCheckSameComm(mat,1,x,3); 3779 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3780 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); 3781 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); 3782 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); 3783 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); 3784 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); 3785 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3786 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3787 MatCheckPreallocated(mat,1); 3788 3789 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3790 if (mat->ops->solveadd) { 3791 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3792 } else { 3793 /* do the solve then the add manually */ 3794 if (x != y) { 3795 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3796 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3797 } else { 3798 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3799 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3800 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3801 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3802 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3803 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3804 } 3805 } 3806 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3807 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3808 PetscFunctionReturn(0); 3809 } 3810 3811 /*@ 3812 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3813 3814 Neighbor-wise Collective on Mat and Vec 3815 3816 Input Parameters: 3817 + mat - the factored matrix 3818 - b - the right-hand-side vector 3819 3820 Output Parameter: 3821 . x - the result vector 3822 3823 Notes: 3824 The vectors b and x cannot be the same. I.e., one cannot 3825 call MatSolveTranspose(A,x,x). 3826 3827 Most users should employ the simplified KSP interface for linear solvers 3828 instead of working directly with matrix algebra routines such as this. 3829 See, e.g., KSPCreate(). 3830 3831 Level: developer 3832 3833 Concepts: matrices^triangular solves 3834 3835 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3836 @*/ 3837 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3838 { 3839 PetscErrorCode ierr; 3840 3841 PetscFunctionBegin; 3842 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3843 PetscValidType(mat,1); 3844 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3845 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3846 PetscCheckSameComm(mat,1,b,2); 3847 PetscCheckSameComm(mat,1,x,3); 3848 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3849 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); 3850 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); 3851 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3852 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3853 MatCheckPreallocated(mat,1); 3854 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3855 if (mat->factorerrortype) { 3856 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3857 ierr = VecSetInf(x);CHKERRQ(ierr); 3858 } else { 3859 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3860 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3861 } 3862 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3863 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3864 PetscFunctionReturn(0); 3865 } 3866 3867 /*@ 3868 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3869 factored matrix. 3870 3871 Neighbor-wise Collective on Mat and Vec 3872 3873 Input Parameters: 3874 + mat - the factored matrix 3875 . b - the right-hand-side vector 3876 - y - the vector to be added to 3877 3878 Output Parameter: 3879 . x - the result vector 3880 3881 Notes: 3882 The vectors b and x cannot be the same. I.e., one cannot 3883 call MatSolveTransposeAdd(A,x,y,x). 3884 3885 Most users should employ the simplified KSP interface for linear solvers 3886 instead of working directly with matrix algebra routines such as this. 3887 See, e.g., KSPCreate(). 3888 3889 Level: developer 3890 3891 Concepts: matrices^triangular solves 3892 3893 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3894 @*/ 3895 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3896 { 3897 PetscScalar one = 1.0; 3898 PetscErrorCode ierr; 3899 Vec tmp; 3900 3901 PetscFunctionBegin; 3902 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3903 PetscValidType(mat,1); 3904 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3905 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3906 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3907 PetscCheckSameComm(mat,1,b,2); 3908 PetscCheckSameComm(mat,1,y,3); 3909 PetscCheckSameComm(mat,1,x,4); 3910 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3911 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); 3912 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); 3913 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); 3914 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); 3915 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3916 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3917 MatCheckPreallocated(mat,1); 3918 3919 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3920 if (mat->ops->solvetransposeadd) { 3921 if (mat->factorerrortype) { 3922 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3923 ierr = VecSetInf(x);CHKERRQ(ierr); 3924 } else { 3925 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3926 } 3927 } else { 3928 /* do the solve then the add manually */ 3929 if (x != y) { 3930 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3931 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3932 } else { 3933 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3934 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3935 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3936 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3937 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3938 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3939 } 3940 } 3941 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3942 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3943 PetscFunctionReturn(0); 3944 } 3945 /* ----------------------------------------------------------------*/ 3946 3947 /*@ 3948 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3949 3950 Neighbor-wise Collective on Mat and Vec 3951 3952 Input Parameters: 3953 + mat - the matrix 3954 . b - the right hand side 3955 . omega - the relaxation factor 3956 . flag - flag indicating the type of SOR (see below) 3957 . shift - diagonal shift 3958 . its - the number of iterations 3959 - lits - the number of local iterations 3960 3961 Output Parameters: 3962 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3963 3964 SOR Flags: 3965 . SOR_FORWARD_SWEEP - forward SOR 3966 . SOR_BACKWARD_SWEEP - backward SOR 3967 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3968 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3969 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3970 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3971 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3972 upper/lower triangular part of matrix to 3973 vector (with omega) 3974 . SOR_ZERO_INITIAL_GUESS - zero initial guess 3975 3976 Notes: 3977 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3978 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3979 on each processor. 3980 3981 Application programmers will not generally use MatSOR() directly, 3982 but instead will employ the KSP/PC interface. 3983 3984 Notes: 3985 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3986 3987 Notes for Advanced Users: 3988 The flags are implemented as bitwise inclusive or operations. 3989 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3990 to specify a zero initial guess for SSOR. 3991 3992 Most users should employ the simplified KSP interface for linear solvers 3993 instead of working directly with matrix algebra routines such as this. 3994 See, e.g., KSPCreate(). 3995 3996 Vectors x and b CANNOT be the same 3997 3998 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3999 4000 Level: developer 4001 4002 Concepts: matrices^relaxation 4003 Concepts: matrices^SOR 4004 Concepts: matrices^Gauss-Seidel 4005 4006 @*/ 4007 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 4008 { 4009 PetscErrorCode ierr; 4010 4011 PetscFunctionBegin; 4012 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4013 PetscValidType(mat,1); 4014 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4015 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 4016 PetscCheckSameComm(mat,1,b,2); 4017 PetscCheckSameComm(mat,1,x,8); 4018 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4019 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4020 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4021 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); 4022 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); 4023 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); 4024 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 4025 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 4026 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4027 4028 MatCheckPreallocated(mat,1); 4029 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 4030 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 4031 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 4032 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 4033 PetscFunctionReturn(0); 4034 } 4035 4036 /* 4037 Default matrix copy routine. 4038 */ 4039 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4040 { 4041 PetscErrorCode ierr; 4042 PetscInt i,rstart = 0,rend = 0,nz; 4043 const PetscInt *cwork; 4044 const PetscScalar *vwork; 4045 4046 PetscFunctionBegin; 4047 if (B->assembled) { 4048 ierr = MatZeroEntries(B);CHKERRQ(ierr); 4049 } 4050 if (str == SAME_NONZERO_PATTERN) { 4051 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 4052 for (i=rstart; i<rend; i++) { 4053 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 4054 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 4055 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 4056 } 4057 } else { 4058 ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr); 4059 } 4060 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4061 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4062 PetscFunctionReturn(0); 4063 } 4064 4065 /*@ 4066 MatCopy - Copies a matrix to another matrix. 4067 4068 Collective on Mat 4069 4070 Input Parameters: 4071 + A - the matrix 4072 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4073 4074 Output Parameter: 4075 . B - where the copy is put 4076 4077 Notes: 4078 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 4079 same nonzero pattern or the routine will crash. 4080 4081 MatCopy() copies the matrix entries of a matrix to another existing 4082 matrix (after first zeroing the second matrix). A related routine is 4083 MatConvert(), which first creates a new matrix and then copies the data. 4084 4085 Level: intermediate 4086 4087 Concepts: matrices^copying 4088 4089 .seealso: MatConvert(), MatDuplicate() 4090 4091 @*/ 4092 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4093 { 4094 PetscErrorCode ierr; 4095 PetscInt i; 4096 4097 PetscFunctionBegin; 4098 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4099 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4100 PetscValidType(A,1); 4101 PetscValidType(B,2); 4102 PetscCheckSameComm(A,1,B,2); 4103 MatCheckPreallocated(B,2); 4104 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4105 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4106 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); 4107 MatCheckPreallocated(A,1); 4108 if (A == B) PetscFunctionReturn(0); 4109 4110 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4111 if (A->ops->copy) { 4112 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 4113 } else { /* generic conversion */ 4114 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 4115 } 4116 4117 B->stencil.dim = A->stencil.dim; 4118 B->stencil.noc = A->stencil.noc; 4119 for (i=0; i<=A->stencil.dim; i++) { 4120 B->stencil.dims[i] = A->stencil.dims[i]; 4121 B->stencil.starts[i] = A->stencil.starts[i]; 4122 } 4123 4124 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4125 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4126 PetscFunctionReturn(0); 4127 } 4128 4129 /*@C 4130 MatConvert - Converts a matrix to another matrix, either of the same 4131 or different type. 4132 4133 Collective on Mat 4134 4135 Input Parameters: 4136 + mat - the matrix 4137 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4138 same type as the original matrix. 4139 - reuse - denotes if the destination matrix is to be created or reused. 4140 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 4141 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). 4142 4143 Output Parameter: 4144 . M - pointer to place new matrix 4145 4146 Notes: 4147 MatConvert() first creates a new matrix and then copies the data from 4148 the first matrix. A related routine is MatCopy(), which copies the matrix 4149 entries of one matrix to another already existing matrix context. 4150 4151 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4152 the MPI communicator of the generated matrix is always the same as the communicator 4153 of the input matrix. 4154 4155 Level: intermediate 4156 4157 Concepts: matrices^converting between storage formats 4158 4159 .seealso: MatCopy(), MatDuplicate() 4160 @*/ 4161 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4162 { 4163 PetscErrorCode ierr; 4164 PetscBool sametype,issame,flg; 4165 char convname[256],mtype[256]; 4166 Mat B; 4167 4168 PetscFunctionBegin; 4169 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4170 PetscValidType(mat,1); 4171 PetscValidPointer(M,3); 4172 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4173 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4174 MatCheckPreallocated(mat,1); 4175 4176 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4177 if (flg) { 4178 newtype = mtype; 4179 } 4180 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4181 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4182 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4183 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"); 4184 4185 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0); 4186 4187 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4188 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4189 } else { 4190 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4191 const char *prefix[3] = {"seq","mpi",""}; 4192 PetscInt i; 4193 /* 4194 Order of precedence: 4195 0) See if newtype is a superclass of the current matrix. 4196 1) See if a specialized converter is known to the current matrix. 4197 2) See if a specialized converter is known to the desired matrix class. 4198 3) See if a good general converter is registered for the desired class 4199 (as of 6/27/03 only MATMPIADJ falls into this category). 4200 4) See if a good general converter is known for the current matrix. 4201 5) Use a really basic converter. 4202 */ 4203 4204 /* 0) See if newtype is a superclass of the current matrix. 4205 i.e mat is mpiaij and newtype is aij */ 4206 for (i=0; i<2; i++) { 4207 ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4208 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4209 ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr); 4210 ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr); 4211 if (flg) { 4212 if (reuse == MAT_INPLACE_MATRIX) { 4213 PetscFunctionReturn(0); 4214 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4215 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4216 PetscFunctionReturn(0); 4217 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4218 ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4219 PetscFunctionReturn(0); 4220 } 4221 } 4222 } 4223 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4224 for (i=0; i<3; i++) { 4225 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4226 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4227 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4228 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4229 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4230 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4231 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4232 ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4233 if (conv) goto foundconv; 4234 } 4235 4236 /* 2) See if a specialized converter is known to the desired matrix class. */ 4237 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4238 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4239 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4240 for (i=0; i<3; i++) { 4241 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4242 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4243 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4244 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4245 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4246 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4247 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4248 ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4249 if (conv) { 4250 ierr = MatDestroy(&B);CHKERRQ(ierr); 4251 goto foundconv; 4252 } 4253 } 4254 4255 /* 3) See if a good general converter is registered for the desired class */ 4256 conv = B->ops->convertfrom; 4257 ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4258 ierr = MatDestroy(&B);CHKERRQ(ierr); 4259 if (conv) goto foundconv; 4260 4261 /* 4) See if a good general converter is known for the current matrix */ 4262 if (mat->ops->convert) { 4263 conv = mat->ops->convert; 4264 } 4265 ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4266 if (conv) goto foundconv; 4267 4268 /* 5) Use a really basic converter. */ 4269 ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr); 4270 conv = MatConvert_Basic; 4271 4272 foundconv: 4273 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4274 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4275 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4276 /* the block sizes must be same if the mappings are copied over */ 4277 (*M)->rmap->bs = mat->rmap->bs; 4278 (*M)->cmap->bs = mat->cmap->bs; 4279 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4280 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4281 (*M)->rmap->mapping = mat->rmap->mapping; 4282 (*M)->cmap->mapping = mat->cmap->mapping; 4283 } 4284 (*M)->stencil.dim = mat->stencil.dim; 4285 (*M)->stencil.noc = mat->stencil.noc; 4286 for (i=0; i<=mat->stencil.dim; i++) { 4287 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4288 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4289 } 4290 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4291 } 4292 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4293 4294 /* Copy Mat options */ 4295 if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);} 4296 if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);} 4297 PetscFunctionReturn(0); 4298 } 4299 4300 /*@C 4301 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4302 4303 Not Collective 4304 4305 Input Parameter: 4306 . mat - the matrix, must be a factored matrix 4307 4308 Output Parameter: 4309 . type - the string name of the package (do not free this string) 4310 4311 Notes: 4312 In Fortran you pass in a empty string and the package name will be copied into it. 4313 (Make sure the string is long enough) 4314 4315 Level: intermediate 4316 4317 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4318 @*/ 4319 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4320 { 4321 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4322 4323 PetscFunctionBegin; 4324 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4325 PetscValidType(mat,1); 4326 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4327 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4328 if (!conv) { 4329 *type = MATSOLVERPETSC; 4330 } else { 4331 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4332 } 4333 PetscFunctionReturn(0); 4334 } 4335 4336 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4337 struct _MatSolverTypeForSpecifcType { 4338 MatType mtype; 4339 PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*); 4340 MatSolverTypeForSpecifcType next; 4341 }; 4342 4343 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4344 struct _MatSolverTypeHolder { 4345 char *name; 4346 MatSolverTypeForSpecifcType handlers; 4347 MatSolverTypeHolder next; 4348 }; 4349 4350 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4351 4352 /*@C 4353 MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type 4354 4355 Input Parameters: 4356 + package - name of the package, for example petsc or superlu 4357 . mtype - the matrix type that works with this package 4358 . ftype - the type of factorization supported by the package 4359 - getfactor - routine that will create the factored matrix ready to be used 4360 4361 Level: intermediate 4362 4363 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4364 @*/ 4365 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*)) 4366 { 4367 PetscErrorCode ierr; 4368 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4369 PetscBool flg; 4370 MatSolverTypeForSpecifcType inext,iprev = NULL; 4371 4372 PetscFunctionBegin; 4373 ierr = MatInitializePackage();CHKERRQ(ierr); 4374 if (!next) { 4375 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4376 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4377 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4378 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4379 MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor; 4380 PetscFunctionReturn(0); 4381 } 4382 while (next) { 4383 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4384 if (flg) { 4385 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4386 inext = next->handlers; 4387 while (inext) { 4388 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4389 if (flg) { 4390 inext->getfactor[(int)ftype-1] = getfactor; 4391 PetscFunctionReturn(0); 4392 } 4393 iprev = inext; 4394 inext = inext->next; 4395 } 4396 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4397 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4398 iprev->next->getfactor[(int)ftype-1] = getfactor; 4399 PetscFunctionReturn(0); 4400 } 4401 prev = next; 4402 next = next->next; 4403 } 4404 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4405 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4406 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4407 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4408 prev->next->handlers->getfactor[(int)ftype-1] = getfactor; 4409 PetscFunctionReturn(0); 4410 } 4411 4412 /*@C 4413 MatSolvePackageGet - Get's the function that creates the factor matrix if it exist 4414 4415 Input Parameters: 4416 + package - name of the package, for example petsc or superlu 4417 . ftype - the type of factorization supported by the package 4418 - mtype - the matrix type that works with this package 4419 4420 Output Parameters: 4421 + foundpackage - PETSC_TRUE if the package was registered 4422 . foundmtype - PETSC_TRUE if the package supports the requested mtype 4423 - getfactor - routine that will create the factored matrix ready to be used or NULL if not found 4424 4425 Level: intermediate 4426 4427 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4428 @*/ 4429 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*)) 4430 { 4431 PetscErrorCode ierr; 4432 MatSolverTypeHolder next = MatSolverTypeHolders; 4433 PetscBool flg; 4434 MatSolverTypeForSpecifcType inext; 4435 4436 PetscFunctionBegin; 4437 if (foundpackage) *foundpackage = PETSC_FALSE; 4438 if (foundmtype) *foundmtype = PETSC_FALSE; 4439 if (getfactor) *getfactor = NULL; 4440 4441 if (package) { 4442 while (next) { 4443 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4444 if (flg) { 4445 if (foundpackage) *foundpackage = PETSC_TRUE; 4446 inext = next->handlers; 4447 while (inext) { 4448 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4449 if (flg) { 4450 if (foundmtype) *foundmtype = PETSC_TRUE; 4451 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4452 PetscFunctionReturn(0); 4453 } 4454 inext = inext->next; 4455 } 4456 } 4457 next = next->next; 4458 } 4459 } else { 4460 while (next) { 4461 inext = next->handlers; 4462 while (inext) { 4463 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4464 if (flg && inext->getfactor[(int)ftype-1]) { 4465 if (foundpackage) *foundpackage = PETSC_TRUE; 4466 if (foundmtype) *foundmtype = PETSC_TRUE; 4467 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4468 PetscFunctionReturn(0); 4469 } 4470 inext = inext->next; 4471 } 4472 next = next->next; 4473 } 4474 } 4475 PetscFunctionReturn(0); 4476 } 4477 4478 PetscErrorCode MatSolverTypeDestroy(void) 4479 { 4480 PetscErrorCode ierr; 4481 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4482 MatSolverTypeForSpecifcType inext,iprev; 4483 4484 PetscFunctionBegin; 4485 while (next) { 4486 ierr = PetscFree(next->name);CHKERRQ(ierr); 4487 inext = next->handlers; 4488 while (inext) { 4489 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4490 iprev = inext; 4491 inext = inext->next; 4492 ierr = PetscFree(iprev);CHKERRQ(ierr); 4493 } 4494 prev = next; 4495 next = next->next; 4496 ierr = PetscFree(prev);CHKERRQ(ierr); 4497 } 4498 MatSolverTypeHolders = NULL; 4499 PetscFunctionReturn(0); 4500 } 4501 4502 /*@C 4503 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4504 4505 Collective on Mat 4506 4507 Input Parameters: 4508 + mat - the matrix 4509 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4510 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4511 4512 Output Parameters: 4513 . f - the factor matrix used with MatXXFactorSymbolic() calls 4514 4515 Notes: 4516 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4517 such as pastix, superlu, mumps etc. 4518 4519 PETSc must have been ./configure to use the external solver, using the option --download-package 4520 4521 Level: intermediate 4522 4523 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4524 @*/ 4525 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4526 { 4527 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4528 PetscBool foundpackage,foundmtype; 4529 4530 PetscFunctionBegin; 4531 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4532 PetscValidType(mat,1); 4533 4534 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4535 MatCheckPreallocated(mat,1); 4536 4537 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr); 4538 if (!foundpackage) { 4539 if (type) { 4540 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4541 } else { 4542 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>"); 4543 } 4544 } 4545 4546 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4547 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); 4548 4549 #if defined(PETSC_USE_COMPLEX) 4550 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"); 4551 #endif 4552 4553 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4554 PetscFunctionReturn(0); 4555 } 4556 4557 /*@C 4558 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4559 4560 Not Collective 4561 4562 Input Parameters: 4563 + mat - the matrix 4564 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4565 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4566 4567 Output Parameter: 4568 . flg - PETSC_TRUE if the factorization is available 4569 4570 Notes: 4571 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4572 such as pastix, superlu, mumps etc. 4573 4574 PETSc must have been ./configure to use the external solver, using the option --download-package 4575 4576 Level: intermediate 4577 4578 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4579 @*/ 4580 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4581 { 4582 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4583 4584 PetscFunctionBegin; 4585 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4586 PetscValidType(mat,1); 4587 4588 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4589 MatCheckPreallocated(mat,1); 4590 4591 *flg = PETSC_FALSE; 4592 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4593 if (gconv) { 4594 *flg = PETSC_TRUE; 4595 } 4596 PetscFunctionReturn(0); 4597 } 4598 4599 #include <petscdmtypes.h> 4600 4601 /*@ 4602 MatDuplicate - Duplicates a matrix including the non-zero structure. 4603 4604 Collective on Mat 4605 4606 Input Parameters: 4607 + mat - the matrix 4608 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4609 See the manual page for MatDuplicateOption for an explanation of these options. 4610 4611 Output Parameter: 4612 . M - pointer to place new matrix 4613 4614 Level: intermediate 4615 4616 Concepts: matrices^duplicating 4617 4618 Notes: 4619 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4620 When original mat is a product of matrix operation, e.g., an output of MatMatMult() or MatCreateSubMatrix(), only the simple matrix data structure of mat is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. User should not use MatDuplicate() to create new matrix M if M is intended to be reused as the product of matrix operation. 4621 4622 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4623 @*/ 4624 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4625 { 4626 PetscErrorCode ierr; 4627 Mat B; 4628 PetscInt i; 4629 DM dm; 4630 void (*viewf)(void); 4631 4632 PetscFunctionBegin; 4633 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4634 PetscValidType(mat,1); 4635 PetscValidPointer(M,3); 4636 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4637 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4638 MatCheckPreallocated(mat,1); 4639 4640 *M = 0; 4641 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4642 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4643 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4644 B = *M; 4645 4646 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4647 if (viewf) { 4648 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4649 } 4650 4651 B->stencil.dim = mat->stencil.dim; 4652 B->stencil.noc = mat->stencil.noc; 4653 for (i=0; i<=mat->stencil.dim; i++) { 4654 B->stencil.dims[i] = mat->stencil.dims[i]; 4655 B->stencil.starts[i] = mat->stencil.starts[i]; 4656 } 4657 4658 B->nooffproczerorows = mat->nooffproczerorows; 4659 B->nooffprocentries = mat->nooffprocentries; 4660 4661 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4662 if (dm) { 4663 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4664 } 4665 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4666 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4667 PetscFunctionReturn(0); 4668 } 4669 4670 /*@ 4671 MatGetDiagonal - Gets the diagonal of a matrix. 4672 4673 Logically Collective on Mat and Vec 4674 4675 Input Parameters: 4676 + mat - the matrix 4677 - v - the vector for storing the diagonal 4678 4679 Output Parameter: 4680 . v - the diagonal of the matrix 4681 4682 Level: intermediate 4683 4684 Note: 4685 Currently only correct in parallel for square matrices. 4686 4687 Concepts: matrices^accessing diagonals 4688 4689 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4690 @*/ 4691 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4692 { 4693 PetscErrorCode ierr; 4694 4695 PetscFunctionBegin; 4696 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4697 PetscValidType(mat,1); 4698 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4699 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4700 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4701 MatCheckPreallocated(mat,1); 4702 4703 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4704 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4705 PetscFunctionReturn(0); 4706 } 4707 4708 /*@C 4709 MatGetRowMin - Gets the minimum value (of the real part) of each 4710 row of the matrix 4711 4712 Logically Collective on Mat and Vec 4713 4714 Input Parameters: 4715 . mat - the matrix 4716 4717 Output Parameter: 4718 + v - the vector for storing the maximums 4719 - idx - the indices of the column found for each row (optional) 4720 4721 Level: intermediate 4722 4723 Notes: 4724 The result of this call are the same as if one converted the matrix to dense format 4725 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4726 4727 This code is only implemented for a couple of matrix formats. 4728 4729 Concepts: matrices^getting row maximums 4730 4731 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4732 MatGetRowMax() 4733 @*/ 4734 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4735 { 4736 PetscErrorCode ierr; 4737 4738 PetscFunctionBegin; 4739 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4740 PetscValidType(mat,1); 4741 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4742 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4743 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4744 MatCheckPreallocated(mat,1); 4745 4746 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4747 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4748 PetscFunctionReturn(0); 4749 } 4750 4751 /*@C 4752 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4753 row of the matrix 4754 4755 Logically Collective on Mat and Vec 4756 4757 Input Parameters: 4758 . mat - the matrix 4759 4760 Output Parameter: 4761 + v - the vector for storing the minimums 4762 - idx - the indices of the column found for each row (or NULL if not needed) 4763 4764 Level: intermediate 4765 4766 Notes: 4767 if a row is completely empty or has only 0.0 values then the idx[] value for that 4768 row is 0 (the first column). 4769 4770 This code is only implemented for a couple of matrix formats. 4771 4772 Concepts: matrices^getting row maximums 4773 4774 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4775 @*/ 4776 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4777 { 4778 PetscErrorCode ierr; 4779 4780 PetscFunctionBegin; 4781 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4782 PetscValidType(mat,1); 4783 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4784 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4785 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4786 MatCheckPreallocated(mat,1); 4787 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4788 4789 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4790 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4791 PetscFunctionReturn(0); 4792 } 4793 4794 /*@C 4795 MatGetRowMax - Gets the maximum value (of the real part) of each 4796 row of the matrix 4797 4798 Logically Collective on Mat and Vec 4799 4800 Input Parameters: 4801 . mat - the matrix 4802 4803 Output Parameter: 4804 + v - the vector for storing the maximums 4805 - idx - the indices of the column found for each row (optional) 4806 4807 Level: intermediate 4808 4809 Notes: 4810 The result of this call are the same as if one converted the matrix to dense format 4811 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4812 4813 This code is only implemented for a couple of matrix formats. 4814 4815 Concepts: matrices^getting row maximums 4816 4817 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4818 @*/ 4819 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4820 { 4821 PetscErrorCode ierr; 4822 4823 PetscFunctionBegin; 4824 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4825 PetscValidType(mat,1); 4826 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4827 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4828 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4829 MatCheckPreallocated(mat,1); 4830 4831 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4832 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4833 PetscFunctionReturn(0); 4834 } 4835 4836 /*@C 4837 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4838 row of the matrix 4839 4840 Logically Collective on Mat and Vec 4841 4842 Input Parameters: 4843 . mat - the matrix 4844 4845 Output Parameter: 4846 + v - the vector for storing the maximums 4847 - idx - the indices of the column found for each row (or NULL if not needed) 4848 4849 Level: intermediate 4850 4851 Notes: 4852 if a row is completely empty or has only 0.0 values then the idx[] value for that 4853 row is 0 (the first column). 4854 4855 This code is only implemented for a couple of matrix formats. 4856 4857 Concepts: matrices^getting row maximums 4858 4859 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4860 @*/ 4861 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4862 { 4863 PetscErrorCode ierr; 4864 4865 PetscFunctionBegin; 4866 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4867 PetscValidType(mat,1); 4868 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4869 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4870 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4871 MatCheckPreallocated(mat,1); 4872 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4873 4874 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4875 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4876 PetscFunctionReturn(0); 4877 } 4878 4879 /*@ 4880 MatGetRowSum - Gets the sum of each row of the matrix 4881 4882 Logically or Neighborhood Collective on Mat and Vec 4883 4884 Input Parameters: 4885 . mat - the matrix 4886 4887 Output Parameter: 4888 . v - the vector for storing the sum of rows 4889 4890 Level: intermediate 4891 4892 Notes: 4893 This code is slow since it is not currently specialized for different formats 4894 4895 Concepts: matrices^getting row sums 4896 4897 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4898 @*/ 4899 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4900 { 4901 Vec ones; 4902 PetscErrorCode ierr; 4903 4904 PetscFunctionBegin; 4905 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4906 PetscValidType(mat,1); 4907 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4908 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4909 MatCheckPreallocated(mat,1); 4910 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4911 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4912 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4913 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4914 PetscFunctionReturn(0); 4915 } 4916 4917 /*@ 4918 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4919 4920 Collective on Mat 4921 4922 Input Parameter: 4923 + mat - the matrix to transpose 4924 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4925 4926 Output Parameters: 4927 . B - the transpose 4928 4929 Notes: 4930 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4931 4932 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4933 4934 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4935 4936 Level: intermediate 4937 4938 Concepts: matrices^transposing 4939 4940 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4941 @*/ 4942 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4943 { 4944 PetscErrorCode ierr; 4945 4946 PetscFunctionBegin; 4947 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4948 PetscValidType(mat,1); 4949 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4950 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4951 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4952 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4953 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4954 MatCheckPreallocated(mat,1); 4955 4956 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4957 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4958 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4959 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4960 PetscFunctionReturn(0); 4961 } 4962 4963 /*@ 4964 MatIsTranspose - Test whether a matrix is another one's transpose, 4965 or its own, in which case it tests symmetry. 4966 4967 Collective on Mat 4968 4969 Input Parameter: 4970 + A - the matrix to test 4971 - B - the matrix to test against, this can equal the first parameter 4972 4973 Output Parameters: 4974 . flg - the result 4975 4976 Notes: 4977 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4978 has a running time of the order of the number of nonzeros; the parallel 4979 test involves parallel copies of the block-offdiagonal parts of the matrix. 4980 4981 Level: intermediate 4982 4983 Concepts: matrices^transposing, matrix^symmetry 4984 4985 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4986 @*/ 4987 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4988 { 4989 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4990 4991 PetscFunctionBegin; 4992 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4993 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4994 PetscValidPointer(flg,3); 4995 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4996 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4997 *flg = PETSC_FALSE; 4998 if (f && g) { 4999 if (f == g) { 5000 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 5001 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5002 } else { 5003 MatType mattype; 5004 if (!f) { 5005 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 5006 } else { 5007 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 5008 } 5009 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 5010 } 5011 PetscFunctionReturn(0); 5012 } 5013 5014 /*@ 5015 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5016 5017 Collective on Mat 5018 5019 Input Parameter: 5020 + mat - the matrix to transpose and complex conjugate 5021 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 5022 5023 Output Parameters: 5024 . B - the Hermitian 5025 5026 Level: intermediate 5027 5028 Concepts: matrices^transposing, complex conjugatex 5029 5030 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 5031 @*/ 5032 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5033 { 5034 PetscErrorCode ierr; 5035 5036 PetscFunctionBegin; 5037 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 5038 #if defined(PETSC_USE_COMPLEX) 5039 ierr = MatConjugate(*B);CHKERRQ(ierr); 5040 #endif 5041 PetscFunctionReturn(0); 5042 } 5043 5044 /*@ 5045 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5046 5047 Collective on Mat 5048 5049 Input Parameter: 5050 + A - the matrix to test 5051 - B - the matrix to test against, this can equal the first parameter 5052 5053 Output Parameters: 5054 . flg - the result 5055 5056 Notes: 5057 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5058 has a running time of the order of the number of nonzeros; the parallel 5059 test involves parallel copies of the block-offdiagonal parts of the matrix. 5060 5061 Level: intermediate 5062 5063 Concepts: matrices^transposing, matrix^symmetry 5064 5065 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 5066 @*/ 5067 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5068 { 5069 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5070 5071 PetscFunctionBegin; 5072 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5073 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5074 PetscValidPointer(flg,3); 5075 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 5076 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 5077 if (f && g) { 5078 if (f==g) { 5079 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 5080 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5081 } 5082 PetscFunctionReturn(0); 5083 } 5084 5085 /*@ 5086 MatPermute - Creates a new matrix with rows and columns permuted from the 5087 original. 5088 5089 Collective on Mat 5090 5091 Input Parameters: 5092 + mat - the matrix to permute 5093 . row - row permutation, each processor supplies only the permutation for its rows 5094 - col - column permutation, each processor supplies only the permutation for its columns 5095 5096 Output Parameters: 5097 . B - the permuted matrix 5098 5099 Level: advanced 5100 5101 Note: 5102 The index sets map from row/col of permuted matrix to row/col of original matrix. 5103 The index sets should be on the same communicator as Mat and have the same local sizes. 5104 5105 Concepts: matrices^permuting 5106 5107 .seealso: MatGetOrdering(), ISAllGather() 5108 5109 @*/ 5110 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5111 { 5112 PetscErrorCode ierr; 5113 5114 PetscFunctionBegin; 5115 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5116 PetscValidType(mat,1); 5117 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5118 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5119 PetscValidPointer(B,4); 5120 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5121 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5122 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5123 MatCheckPreallocated(mat,1); 5124 5125 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 5126 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 5127 PetscFunctionReturn(0); 5128 } 5129 5130 /*@ 5131 MatEqual - Compares two matrices. 5132 5133 Collective on Mat 5134 5135 Input Parameters: 5136 + A - the first matrix 5137 - B - the second matrix 5138 5139 Output Parameter: 5140 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5141 5142 Level: intermediate 5143 5144 Concepts: matrices^equality between 5145 @*/ 5146 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5147 { 5148 PetscErrorCode ierr; 5149 5150 PetscFunctionBegin; 5151 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5152 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5153 PetscValidType(A,1); 5154 PetscValidType(B,2); 5155 PetscValidIntPointer(flg,3); 5156 PetscCheckSameComm(A,1,B,2); 5157 MatCheckPreallocated(B,2); 5158 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5159 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5160 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); 5161 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5162 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5163 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); 5164 MatCheckPreallocated(A,1); 5165 5166 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5167 PetscFunctionReturn(0); 5168 } 5169 5170 /*@ 5171 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5172 matrices that are stored as vectors. Either of the two scaling 5173 matrices can be NULL. 5174 5175 Collective on Mat 5176 5177 Input Parameters: 5178 + mat - the matrix to be scaled 5179 . l - the left scaling vector (or NULL) 5180 - r - the right scaling vector (or NULL) 5181 5182 Notes: 5183 MatDiagonalScale() computes A = LAR, where 5184 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5185 The L scales the rows of the matrix, the R scales the columns of the matrix. 5186 5187 Level: intermediate 5188 5189 Concepts: matrices^diagonal scaling 5190 Concepts: diagonal scaling of matrices 5191 5192 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5193 @*/ 5194 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5195 { 5196 PetscErrorCode ierr; 5197 5198 PetscFunctionBegin; 5199 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5200 PetscValidType(mat,1); 5201 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5202 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5203 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5204 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5205 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5206 MatCheckPreallocated(mat,1); 5207 5208 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5209 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5210 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5211 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5212 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5213 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5214 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5215 } 5216 #endif 5217 PetscFunctionReturn(0); 5218 } 5219 5220 /*@ 5221 MatScale - Scales all elements of a matrix by a given number. 5222 5223 Logically Collective on Mat 5224 5225 Input Parameters: 5226 + mat - the matrix to be scaled 5227 - a - the scaling value 5228 5229 Output Parameter: 5230 . mat - the scaled matrix 5231 5232 Level: intermediate 5233 5234 Concepts: matrices^scaling all entries 5235 5236 .seealso: MatDiagonalScale() 5237 @*/ 5238 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5239 { 5240 PetscErrorCode ierr; 5241 5242 PetscFunctionBegin; 5243 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5244 PetscValidType(mat,1); 5245 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5246 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5247 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5248 PetscValidLogicalCollectiveScalar(mat,a,2); 5249 MatCheckPreallocated(mat,1); 5250 5251 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5252 if (a != (PetscScalar)1.0) { 5253 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5254 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5255 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5256 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5257 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5258 } 5259 #endif 5260 } 5261 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5262 PetscFunctionReturn(0); 5263 } 5264 5265 /*@ 5266 MatNorm - Calculates various norms of a matrix. 5267 5268 Collective on Mat 5269 5270 Input Parameters: 5271 + mat - the matrix 5272 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5273 5274 Output Parameters: 5275 . nrm - the resulting norm 5276 5277 Level: intermediate 5278 5279 Concepts: matrices^norm 5280 Concepts: norm^of matrix 5281 @*/ 5282 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5283 { 5284 PetscErrorCode ierr; 5285 5286 PetscFunctionBegin; 5287 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5288 PetscValidType(mat,1); 5289 PetscValidScalarPointer(nrm,3); 5290 5291 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5292 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5293 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5294 MatCheckPreallocated(mat,1); 5295 5296 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5297 PetscFunctionReturn(0); 5298 } 5299 5300 /* 5301 This variable is used to prevent counting of MatAssemblyBegin() that 5302 are called from within a MatAssemblyEnd(). 5303 */ 5304 static PetscInt MatAssemblyEnd_InUse = 0; 5305 /*@ 5306 MatAssemblyBegin - Begins assembling the matrix. This routine should 5307 be called after completing all calls to MatSetValues(). 5308 5309 Collective on Mat 5310 5311 Input Parameters: 5312 + mat - the matrix 5313 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5314 5315 Notes: 5316 MatSetValues() generally caches the values. The matrix is ready to 5317 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5318 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5319 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5320 using the matrix. 5321 5322 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5323 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 5324 a global collective operation requring all processes that share the matrix. 5325 5326 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5327 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5328 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5329 5330 Level: beginner 5331 5332 Concepts: matrices^assembling 5333 5334 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5335 @*/ 5336 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5337 { 5338 PetscErrorCode ierr; 5339 5340 PetscFunctionBegin; 5341 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5342 PetscValidType(mat,1); 5343 MatCheckPreallocated(mat,1); 5344 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5345 if (mat->assembled) { 5346 mat->was_assembled = PETSC_TRUE; 5347 mat->assembled = PETSC_FALSE; 5348 } 5349 if (!MatAssemblyEnd_InUse) { 5350 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5351 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5352 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5353 } else if (mat->ops->assemblybegin) { 5354 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5355 } 5356 PetscFunctionReturn(0); 5357 } 5358 5359 /*@ 5360 MatAssembled - Indicates if a matrix has been assembled and is ready for 5361 use; for example, in matrix-vector product. 5362 5363 Not Collective 5364 5365 Input Parameter: 5366 . mat - the matrix 5367 5368 Output Parameter: 5369 . assembled - PETSC_TRUE or PETSC_FALSE 5370 5371 Level: advanced 5372 5373 Concepts: matrices^assembled? 5374 5375 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5376 @*/ 5377 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5378 { 5379 PetscFunctionBegin; 5380 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5381 PetscValidPointer(assembled,2); 5382 *assembled = mat->assembled; 5383 PetscFunctionReturn(0); 5384 } 5385 5386 /*@ 5387 MatAssemblyEnd - Completes assembling the matrix. This routine should 5388 be called after MatAssemblyBegin(). 5389 5390 Collective on Mat 5391 5392 Input Parameters: 5393 + mat - the matrix 5394 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5395 5396 Options Database Keys: 5397 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5398 . -mat_view ::ascii_info_detail - Prints more detailed info 5399 . -mat_view - Prints matrix in ASCII format 5400 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5401 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5402 . -display <name> - Sets display name (default is host) 5403 . -draw_pause <sec> - Sets number of seconds to pause after display 5404 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5405 . -viewer_socket_machine <machine> - Machine to use for socket 5406 . -viewer_socket_port <port> - Port number to use for socket 5407 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5408 5409 Notes: 5410 MatSetValues() generally caches the values. The matrix is ready to 5411 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5412 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5413 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5414 using the matrix. 5415 5416 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5417 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5418 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5419 5420 Level: beginner 5421 5422 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5423 @*/ 5424 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5425 { 5426 PetscErrorCode ierr; 5427 static PetscInt inassm = 0; 5428 PetscBool flg = PETSC_FALSE; 5429 5430 PetscFunctionBegin; 5431 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5432 PetscValidType(mat,1); 5433 5434 inassm++; 5435 MatAssemblyEnd_InUse++; 5436 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5437 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5438 if (mat->ops->assemblyend) { 5439 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5440 } 5441 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5442 } else if (mat->ops->assemblyend) { 5443 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5444 } 5445 5446 /* Flush assembly is not a true assembly */ 5447 if (type != MAT_FLUSH_ASSEMBLY) { 5448 mat->assembled = PETSC_TRUE; mat->num_ass++; 5449 } 5450 mat->insertmode = NOT_SET_VALUES; 5451 MatAssemblyEnd_InUse--; 5452 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5453 if (!mat->symmetric_eternal) { 5454 mat->symmetric_set = PETSC_FALSE; 5455 mat->hermitian_set = PETSC_FALSE; 5456 mat->structurally_symmetric_set = PETSC_FALSE; 5457 } 5458 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5459 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5460 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5461 } 5462 #endif 5463 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5464 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5465 5466 if (mat->checksymmetryonassembly) { 5467 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5468 if (flg) { 5469 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5470 } else { 5471 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5472 } 5473 } 5474 if (mat->nullsp && mat->checknullspaceonassembly) { 5475 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5476 } 5477 } 5478 inassm--; 5479 PetscFunctionReturn(0); 5480 } 5481 5482 /*@ 5483 MatSetOption - Sets a parameter option for a matrix. Some options 5484 may be specific to certain storage formats. Some options 5485 determine how values will be inserted (or added). Sorted, 5486 row-oriented input will generally assemble the fastest. The default 5487 is row-oriented. 5488 5489 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5490 5491 Input Parameters: 5492 + mat - the matrix 5493 . option - the option, one of those listed below (and possibly others), 5494 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5495 5496 Options Describing Matrix Structure: 5497 + MAT_SPD - symmetric positive definite 5498 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5499 . MAT_HERMITIAN - transpose is the complex conjugation 5500 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5501 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5502 you set to be kept with all future use of the matrix 5503 including after MatAssemblyBegin/End() which could 5504 potentially change the symmetry structure, i.e. you 5505 KNOW the matrix will ALWAYS have the property you set. 5506 5507 5508 Options For Use with MatSetValues(): 5509 Insert a logically dense subblock, which can be 5510 . MAT_ROW_ORIENTED - row-oriented (default) 5511 5512 Note these options reflect the data you pass in with MatSetValues(); it has 5513 nothing to do with how the data is stored internally in the matrix 5514 data structure. 5515 5516 When (re)assembling a matrix, we can restrict the input for 5517 efficiency/debugging purposes. These options include: 5518 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5519 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5520 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5521 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5522 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5523 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5524 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5525 performance for very large process counts. 5526 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5527 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5528 functions, instead sending only neighbor messages. 5529 5530 Notes: 5531 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5532 5533 Some options are relevant only for particular matrix types and 5534 are thus ignored by others. Other options are not supported by 5535 certain matrix types and will generate an error message if set. 5536 5537 If using a Fortran 77 module to compute a matrix, one may need to 5538 use the column-oriented option (or convert to the row-oriented 5539 format). 5540 5541 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5542 that would generate a new entry in the nonzero structure is instead 5543 ignored. Thus, if memory has not alredy been allocated for this particular 5544 data, then the insertion is ignored. For dense matrices, in which 5545 the entire array is allocated, no entries are ever ignored. 5546 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5547 5548 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5549 that would generate a new entry in the nonzero structure instead produces 5550 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 5551 5552 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5553 that would generate a new entry that has not been preallocated will 5554 instead produce an error. (Currently supported for AIJ and BAIJ formats 5555 only.) This is a useful flag when debugging matrix memory preallocation. 5556 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5557 5558 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5559 other processors should be dropped, rather than stashed. 5560 This is useful if you know that the "owning" processor is also 5561 always generating the correct matrix entries, so that PETSc need 5562 not transfer duplicate entries generated on another processor. 5563 5564 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5565 searches during matrix assembly. When this flag is set, the hash table 5566 is created during the first Matrix Assembly. This hash table is 5567 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5568 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5569 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5570 supported by MATMPIBAIJ format only. 5571 5572 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5573 are kept in the nonzero structure 5574 5575 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5576 a zero location in the matrix 5577 5578 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5579 5580 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5581 zero row routines and thus improves performance for very large process counts. 5582 5583 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5584 part of the matrix (since they should match the upper triangular part). 5585 5586 Notes: 5587 Can only be called after MatSetSizes() and MatSetType() have been set. 5588 5589 Level: intermediate 5590 5591 Concepts: matrices^setting options 5592 5593 .seealso: MatOption, Mat 5594 5595 @*/ 5596 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5597 { 5598 PetscErrorCode ierr; 5599 5600 PetscFunctionBegin; 5601 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5602 PetscValidType(mat,1); 5603 if (op > 0) { 5604 PetscValidLogicalCollectiveEnum(mat,op,2); 5605 PetscValidLogicalCollectiveBool(mat,flg,3); 5606 } 5607 5608 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); 5609 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()"); 5610 5611 switch (op) { 5612 case MAT_NO_OFF_PROC_ENTRIES: 5613 mat->nooffprocentries = flg; 5614 PetscFunctionReturn(0); 5615 break; 5616 case MAT_SUBSET_OFF_PROC_ENTRIES: 5617 mat->assembly_subset = flg; 5618 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5619 #if !defined(PETSC_HAVE_MPIUNI) 5620 ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr); 5621 #endif 5622 mat->stash.first_assembly_done = PETSC_FALSE; 5623 } 5624 PetscFunctionReturn(0); 5625 case MAT_NO_OFF_PROC_ZERO_ROWS: 5626 mat->nooffproczerorows = flg; 5627 PetscFunctionReturn(0); 5628 break; 5629 case MAT_SPD: 5630 mat->spd_set = PETSC_TRUE; 5631 mat->spd = flg; 5632 if (flg) { 5633 mat->symmetric = PETSC_TRUE; 5634 mat->structurally_symmetric = PETSC_TRUE; 5635 mat->symmetric_set = PETSC_TRUE; 5636 mat->structurally_symmetric_set = PETSC_TRUE; 5637 } 5638 break; 5639 case MAT_SYMMETRIC: 5640 mat->symmetric = flg; 5641 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5642 mat->symmetric_set = PETSC_TRUE; 5643 mat->structurally_symmetric_set = flg; 5644 #if !defined(PETSC_USE_COMPLEX) 5645 mat->hermitian = flg; 5646 mat->hermitian_set = PETSC_TRUE; 5647 #endif 5648 break; 5649 case MAT_HERMITIAN: 5650 mat->hermitian = flg; 5651 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5652 mat->hermitian_set = PETSC_TRUE; 5653 mat->structurally_symmetric_set = flg; 5654 #if !defined(PETSC_USE_COMPLEX) 5655 mat->symmetric = flg; 5656 mat->symmetric_set = PETSC_TRUE; 5657 #endif 5658 break; 5659 case MAT_STRUCTURALLY_SYMMETRIC: 5660 mat->structurally_symmetric = flg; 5661 mat->structurally_symmetric_set = PETSC_TRUE; 5662 break; 5663 case MAT_SYMMETRY_ETERNAL: 5664 mat->symmetric_eternal = flg; 5665 break; 5666 case MAT_STRUCTURE_ONLY: 5667 mat->structure_only = flg; 5668 break; 5669 default: 5670 break; 5671 } 5672 if (mat->ops->setoption) { 5673 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5674 } 5675 PetscFunctionReturn(0); 5676 } 5677 5678 /*@ 5679 MatGetOption - Gets a parameter option that has been set for a matrix. 5680 5681 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5682 5683 Input Parameters: 5684 + mat - the matrix 5685 - option - the option, this only responds to certain options, check the code for which ones 5686 5687 Output Parameter: 5688 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5689 5690 Notes: 5691 Can only be called after MatSetSizes() and MatSetType() have been set. 5692 5693 Level: intermediate 5694 5695 Concepts: matrices^setting options 5696 5697 .seealso: MatOption, MatSetOption() 5698 5699 @*/ 5700 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5701 { 5702 PetscFunctionBegin; 5703 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5704 PetscValidType(mat,1); 5705 5706 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); 5707 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()"); 5708 5709 switch (op) { 5710 case MAT_NO_OFF_PROC_ENTRIES: 5711 *flg = mat->nooffprocentries; 5712 break; 5713 case MAT_NO_OFF_PROC_ZERO_ROWS: 5714 *flg = mat->nooffproczerorows; 5715 break; 5716 case MAT_SYMMETRIC: 5717 *flg = mat->symmetric; 5718 break; 5719 case MAT_HERMITIAN: 5720 *flg = mat->hermitian; 5721 break; 5722 case MAT_STRUCTURALLY_SYMMETRIC: 5723 *flg = mat->structurally_symmetric; 5724 break; 5725 case MAT_SYMMETRY_ETERNAL: 5726 *flg = mat->symmetric_eternal; 5727 break; 5728 case MAT_SPD: 5729 *flg = mat->spd; 5730 break; 5731 default: 5732 break; 5733 } 5734 PetscFunctionReturn(0); 5735 } 5736 5737 /*@ 5738 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5739 this routine retains the old nonzero structure. 5740 5741 Logically Collective on Mat 5742 5743 Input Parameters: 5744 . mat - the matrix 5745 5746 Level: intermediate 5747 5748 Notes: 5749 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. 5750 See the Performance chapter of the users manual for information on preallocating matrices. 5751 5752 Concepts: matrices^zeroing 5753 5754 .seealso: MatZeroRows() 5755 @*/ 5756 PetscErrorCode MatZeroEntries(Mat mat) 5757 { 5758 PetscErrorCode ierr; 5759 5760 PetscFunctionBegin; 5761 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5762 PetscValidType(mat,1); 5763 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5764 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"); 5765 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5766 MatCheckPreallocated(mat,1); 5767 5768 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5769 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5770 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5771 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5772 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5773 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5774 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5775 } 5776 #endif 5777 PetscFunctionReturn(0); 5778 } 5779 5780 /*@ 5781 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5782 of a set of rows and columns of a matrix. 5783 5784 Collective on Mat 5785 5786 Input Parameters: 5787 + mat - the matrix 5788 . numRows - the number of rows to remove 5789 . rows - the global row indices 5790 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5791 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5792 - b - optional vector of right hand side, that will be adjusted by provided solution 5793 5794 Notes: 5795 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5796 5797 The user can set a value in the diagonal entry (or for the AIJ and 5798 row formats can optionally remove the main diagonal entry from the 5799 nonzero structure as well, by passing 0.0 as the final argument). 5800 5801 For the parallel case, all processes that share the matrix (i.e., 5802 those in the communicator used for matrix creation) MUST call this 5803 routine, regardless of whether any rows being zeroed are owned by 5804 them. 5805 5806 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5807 list only rows local to itself). 5808 5809 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5810 5811 Level: intermediate 5812 5813 Concepts: matrices^zeroing rows 5814 5815 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5816 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5817 @*/ 5818 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5819 { 5820 PetscErrorCode ierr; 5821 5822 PetscFunctionBegin; 5823 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5824 PetscValidType(mat,1); 5825 if (numRows) PetscValidIntPointer(rows,3); 5826 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5827 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5828 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5829 MatCheckPreallocated(mat,1); 5830 5831 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5832 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5833 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5834 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5835 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5836 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5837 } 5838 #endif 5839 PetscFunctionReturn(0); 5840 } 5841 5842 /*@ 5843 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5844 of a set of rows and columns of a matrix. 5845 5846 Collective on Mat 5847 5848 Input Parameters: 5849 + mat - the matrix 5850 . is - the rows to zero 5851 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5852 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5853 - b - optional vector of right hand side, that will be adjusted by provided solution 5854 5855 Notes: 5856 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5857 5858 The user can set a value in the diagonal entry (or for the AIJ and 5859 row formats can optionally remove the main diagonal entry from the 5860 nonzero structure as well, by passing 0.0 as the final argument). 5861 5862 For the parallel case, all processes that share the matrix (i.e., 5863 those in the communicator used for matrix creation) MUST call this 5864 routine, regardless of whether any rows being zeroed are owned by 5865 them. 5866 5867 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5868 list only rows local to itself). 5869 5870 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5871 5872 Level: intermediate 5873 5874 Concepts: matrices^zeroing rows 5875 5876 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5877 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5878 @*/ 5879 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5880 { 5881 PetscErrorCode ierr; 5882 PetscInt numRows; 5883 const PetscInt *rows; 5884 5885 PetscFunctionBegin; 5886 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5887 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5888 PetscValidType(mat,1); 5889 PetscValidType(is,2); 5890 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5891 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5892 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5893 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5894 PetscFunctionReturn(0); 5895 } 5896 5897 /*@ 5898 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5899 of a set of rows of a matrix. 5900 5901 Collective on Mat 5902 5903 Input Parameters: 5904 + mat - the matrix 5905 . numRows - the number of rows to remove 5906 . rows - the global row indices 5907 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5908 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5909 - b - optional vector of right hand side, that will be adjusted by provided solution 5910 5911 Notes: 5912 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5913 but does not release memory. For the dense and block diagonal 5914 formats this does not alter the nonzero structure. 5915 5916 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5917 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5918 merely zeroed. 5919 5920 The user can set a value in the diagonal entry (or for the AIJ and 5921 row formats can optionally remove the main diagonal entry from the 5922 nonzero structure as well, by passing 0.0 as the final argument). 5923 5924 For the parallel case, all processes that share the matrix (i.e., 5925 those in the communicator used for matrix creation) MUST call this 5926 routine, regardless of whether any rows being zeroed are owned by 5927 them. 5928 5929 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5930 list only rows local to itself). 5931 5932 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5933 owns that are to be zeroed. This saves a global synchronization in the implementation. 5934 5935 Level: intermediate 5936 5937 Concepts: matrices^zeroing rows 5938 5939 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5940 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5941 @*/ 5942 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5943 { 5944 PetscErrorCode ierr; 5945 5946 PetscFunctionBegin; 5947 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5948 PetscValidType(mat,1); 5949 if (numRows) PetscValidIntPointer(rows,3); 5950 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5951 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5952 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5953 MatCheckPreallocated(mat,1); 5954 5955 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5956 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5957 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5958 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5959 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5960 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5961 } 5962 #endif 5963 PetscFunctionReturn(0); 5964 } 5965 5966 /*@ 5967 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5968 of a set of rows of a matrix. 5969 5970 Collective on Mat 5971 5972 Input Parameters: 5973 + mat - the matrix 5974 . is - index set of rows to remove 5975 . diag - value put in all diagonals of eliminated rows 5976 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5977 - b - optional vector of right hand side, that will be adjusted by provided solution 5978 5979 Notes: 5980 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5981 but does not release memory. For the dense and block diagonal 5982 formats this does not alter the nonzero structure. 5983 5984 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5985 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5986 merely zeroed. 5987 5988 The user can set a value in the diagonal entry (or for the AIJ and 5989 row formats can optionally remove the main diagonal entry from the 5990 nonzero structure as well, by passing 0.0 as the final argument). 5991 5992 For the parallel case, all processes that share the matrix (i.e., 5993 those in the communicator used for matrix creation) MUST call this 5994 routine, regardless of whether any rows being zeroed are owned by 5995 them. 5996 5997 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5998 list only rows local to itself). 5999 6000 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6001 owns that are to be zeroed. This saves a global synchronization in the implementation. 6002 6003 Level: intermediate 6004 6005 Concepts: matrices^zeroing rows 6006 6007 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6008 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6009 @*/ 6010 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6011 { 6012 PetscInt numRows; 6013 const PetscInt *rows; 6014 PetscErrorCode ierr; 6015 6016 PetscFunctionBegin; 6017 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6018 PetscValidType(mat,1); 6019 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6020 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6021 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6022 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6023 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6024 PetscFunctionReturn(0); 6025 } 6026 6027 /*@ 6028 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6029 of a set of rows of a matrix. These rows must be local to the process. 6030 6031 Collective on Mat 6032 6033 Input Parameters: 6034 + mat - the matrix 6035 . numRows - the number of rows to remove 6036 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6037 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6038 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6039 - b - optional vector of right hand side, that will be adjusted by provided solution 6040 6041 Notes: 6042 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6043 but does not release memory. For the dense and block diagonal 6044 formats this does not alter the nonzero structure. 6045 6046 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6047 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6048 merely zeroed. 6049 6050 The user can set a value in the diagonal entry (or for the AIJ and 6051 row formats can optionally remove the main diagonal entry from the 6052 nonzero structure as well, by passing 0.0 as the final argument). 6053 6054 For the parallel case, all processes that share the matrix (i.e., 6055 those in the communicator used for matrix creation) MUST call this 6056 routine, regardless of whether any rows being zeroed are owned by 6057 them. 6058 6059 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6060 list only rows local to itself). 6061 6062 The grid coordinates are across the entire grid, not just the local portion 6063 6064 In Fortran idxm and idxn should be declared as 6065 $ MatStencil idxm(4,m) 6066 and the values inserted using 6067 $ idxm(MatStencil_i,1) = i 6068 $ idxm(MatStencil_j,1) = j 6069 $ idxm(MatStencil_k,1) = k 6070 $ idxm(MatStencil_c,1) = c 6071 etc 6072 6073 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6074 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6075 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6076 DM_BOUNDARY_PERIODIC boundary type. 6077 6078 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 6079 a single value per point) you can skip filling those indices. 6080 6081 Level: intermediate 6082 6083 Concepts: matrices^zeroing rows 6084 6085 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6086 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6087 @*/ 6088 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6089 { 6090 PetscInt dim = mat->stencil.dim; 6091 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6092 PetscInt *dims = mat->stencil.dims+1; 6093 PetscInt *starts = mat->stencil.starts; 6094 PetscInt *dxm = (PetscInt*) rows; 6095 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6096 PetscErrorCode ierr; 6097 6098 PetscFunctionBegin; 6099 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6100 PetscValidType(mat,1); 6101 if (numRows) PetscValidIntPointer(rows,3); 6102 6103 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6104 for (i = 0; i < numRows; ++i) { 6105 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6106 for (j = 0; j < 3-sdim; ++j) dxm++; 6107 /* Local index in X dir */ 6108 tmp = *dxm++ - starts[0]; 6109 /* Loop over remaining dimensions */ 6110 for (j = 0; j < dim-1; ++j) { 6111 /* If nonlocal, set index to be negative */ 6112 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6113 /* Update local index */ 6114 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6115 } 6116 /* Skip component slot if necessary */ 6117 if (mat->stencil.noc) dxm++; 6118 /* Local row number */ 6119 if (tmp >= 0) { 6120 jdxm[numNewRows++] = tmp; 6121 } 6122 } 6123 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6124 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6125 PetscFunctionReturn(0); 6126 } 6127 6128 /*@ 6129 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6130 of a set of rows and columns of a matrix. 6131 6132 Collective on Mat 6133 6134 Input Parameters: 6135 + mat - the matrix 6136 . numRows - the number of rows/columns to remove 6137 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6138 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6139 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6140 - b - optional vector of right hand side, that will be adjusted by provided solution 6141 6142 Notes: 6143 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6144 but does not release memory. For the dense and block diagonal 6145 formats this does not alter the nonzero structure. 6146 6147 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6148 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6149 merely zeroed. 6150 6151 The user can set a value in the diagonal entry (or for the AIJ and 6152 row formats can optionally remove the main diagonal entry from the 6153 nonzero structure as well, by passing 0.0 as the final argument). 6154 6155 For the parallel case, all processes that share the matrix (i.e., 6156 those in the communicator used for matrix creation) MUST call this 6157 routine, regardless of whether any rows being zeroed are owned by 6158 them. 6159 6160 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6161 list only rows local to itself, but the row/column numbers are given in local numbering). 6162 6163 The grid coordinates are across the entire grid, not just the local portion 6164 6165 In Fortran idxm and idxn should be declared as 6166 $ MatStencil idxm(4,m) 6167 and the values inserted using 6168 $ idxm(MatStencil_i,1) = i 6169 $ idxm(MatStencil_j,1) = j 6170 $ idxm(MatStencil_k,1) = k 6171 $ idxm(MatStencil_c,1) = c 6172 etc 6173 6174 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6175 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6176 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6177 DM_BOUNDARY_PERIODIC boundary type. 6178 6179 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 6180 a single value per point) you can skip filling those indices. 6181 6182 Level: intermediate 6183 6184 Concepts: matrices^zeroing rows 6185 6186 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6187 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6188 @*/ 6189 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6190 { 6191 PetscInt dim = mat->stencil.dim; 6192 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6193 PetscInt *dims = mat->stencil.dims+1; 6194 PetscInt *starts = mat->stencil.starts; 6195 PetscInt *dxm = (PetscInt*) rows; 6196 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6197 PetscErrorCode ierr; 6198 6199 PetscFunctionBegin; 6200 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6201 PetscValidType(mat,1); 6202 if (numRows) PetscValidIntPointer(rows,3); 6203 6204 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6205 for (i = 0; i < numRows; ++i) { 6206 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6207 for (j = 0; j < 3-sdim; ++j) dxm++; 6208 /* Local index in X dir */ 6209 tmp = *dxm++ - starts[0]; 6210 /* Loop over remaining dimensions */ 6211 for (j = 0; j < dim-1; ++j) { 6212 /* If nonlocal, set index to be negative */ 6213 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6214 /* Update local index */ 6215 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6216 } 6217 /* Skip component slot if necessary */ 6218 if (mat->stencil.noc) dxm++; 6219 /* Local row number */ 6220 if (tmp >= 0) { 6221 jdxm[numNewRows++] = tmp; 6222 } 6223 } 6224 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6225 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6226 PetscFunctionReturn(0); 6227 } 6228 6229 /*@C 6230 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6231 of a set of rows of a matrix; using local numbering of rows. 6232 6233 Collective on Mat 6234 6235 Input Parameters: 6236 + mat - the matrix 6237 . numRows - the number of rows to remove 6238 . rows - the global row indices 6239 . diag - value put in all diagonals of eliminated rows 6240 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6241 - b - optional vector of right hand side, that will be adjusted by provided solution 6242 6243 Notes: 6244 Before calling MatZeroRowsLocal(), the user must first set the 6245 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6246 6247 For the AIJ matrix formats this removes the old nonzero structure, 6248 but does not release memory. For the dense and block diagonal 6249 formats this does not alter the nonzero structure. 6250 6251 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6252 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6253 merely zeroed. 6254 6255 The user can set a value in the diagonal entry (or for the AIJ and 6256 row formats can optionally remove the main diagonal entry from the 6257 nonzero structure as well, by passing 0.0 as the final argument). 6258 6259 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6260 owns that are to be zeroed. This saves a global synchronization in the implementation. 6261 6262 Level: intermediate 6263 6264 Concepts: matrices^zeroing 6265 6266 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6267 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6268 @*/ 6269 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6270 { 6271 PetscErrorCode ierr; 6272 6273 PetscFunctionBegin; 6274 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6275 PetscValidType(mat,1); 6276 if (numRows) PetscValidIntPointer(rows,3); 6277 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6278 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6279 MatCheckPreallocated(mat,1); 6280 6281 if (mat->ops->zerorowslocal) { 6282 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6283 } else { 6284 IS is, newis; 6285 const PetscInt *newRows; 6286 6287 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6288 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6289 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6290 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6291 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6292 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6293 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6294 ierr = ISDestroy(&is);CHKERRQ(ierr); 6295 } 6296 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6297 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6298 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6299 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6300 } 6301 #endif 6302 PetscFunctionReturn(0); 6303 } 6304 6305 /*@ 6306 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6307 of a set of rows of a matrix; using local numbering of rows. 6308 6309 Collective on Mat 6310 6311 Input Parameters: 6312 + mat - the matrix 6313 . is - index set of rows to remove 6314 . diag - value put in all diagonals of eliminated rows 6315 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6316 - b - optional vector of right hand side, that will be adjusted by provided solution 6317 6318 Notes: 6319 Before calling MatZeroRowsLocalIS(), the user must first set the 6320 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6321 6322 For the AIJ matrix formats this removes the old nonzero structure, 6323 but does not release memory. For the dense and block diagonal 6324 formats this does not alter the nonzero structure. 6325 6326 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6327 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6328 merely zeroed. 6329 6330 The user can set a value in the diagonal entry (or for the AIJ and 6331 row formats can optionally remove the main diagonal entry from the 6332 nonzero structure as well, by passing 0.0 as the final argument). 6333 6334 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6335 owns that are to be zeroed. This saves a global synchronization in the implementation. 6336 6337 Level: intermediate 6338 6339 Concepts: matrices^zeroing 6340 6341 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6342 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6343 @*/ 6344 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6345 { 6346 PetscErrorCode ierr; 6347 PetscInt numRows; 6348 const PetscInt *rows; 6349 6350 PetscFunctionBegin; 6351 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6352 PetscValidType(mat,1); 6353 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6354 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6355 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6356 MatCheckPreallocated(mat,1); 6357 6358 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6359 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6360 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6361 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6362 PetscFunctionReturn(0); 6363 } 6364 6365 /*@ 6366 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6367 of a set of rows and columns of a matrix; using local numbering of rows. 6368 6369 Collective on Mat 6370 6371 Input Parameters: 6372 + mat - the matrix 6373 . numRows - the number of rows to remove 6374 . rows - the global row indices 6375 . diag - value put in all diagonals of eliminated rows 6376 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6377 - b - optional vector of right hand side, that will be adjusted by provided solution 6378 6379 Notes: 6380 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6381 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6382 6383 The user can set a value in the diagonal entry (or for the AIJ and 6384 row formats can optionally remove the main diagonal entry from the 6385 nonzero structure as well, by passing 0.0 as the final argument). 6386 6387 Level: intermediate 6388 6389 Concepts: matrices^zeroing 6390 6391 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6392 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6393 @*/ 6394 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6395 { 6396 PetscErrorCode ierr; 6397 IS is, newis; 6398 const PetscInt *newRows; 6399 6400 PetscFunctionBegin; 6401 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6402 PetscValidType(mat,1); 6403 if (numRows) PetscValidIntPointer(rows,3); 6404 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6405 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6406 MatCheckPreallocated(mat,1); 6407 6408 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6409 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6410 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6411 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6412 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6413 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6414 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6415 ierr = ISDestroy(&is);CHKERRQ(ierr); 6416 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6417 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6418 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6419 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6420 } 6421 #endif 6422 PetscFunctionReturn(0); 6423 } 6424 6425 /*@ 6426 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6427 of a set of rows and columns of a matrix; using local numbering of rows. 6428 6429 Collective on Mat 6430 6431 Input Parameters: 6432 + mat - the matrix 6433 . is - index set of rows to remove 6434 . diag - value put in all diagonals of eliminated rows 6435 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6436 - b - optional vector of right hand side, that will be adjusted by provided solution 6437 6438 Notes: 6439 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6440 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6441 6442 The user can set a value in the diagonal entry (or for the AIJ and 6443 row formats can optionally remove the main diagonal entry from the 6444 nonzero structure as well, by passing 0.0 as the final argument). 6445 6446 Level: intermediate 6447 6448 Concepts: matrices^zeroing 6449 6450 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6451 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6452 @*/ 6453 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6454 { 6455 PetscErrorCode ierr; 6456 PetscInt numRows; 6457 const PetscInt *rows; 6458 6459 PetscFunctionBegin; 6460 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6461 PetscValidType(mat,1); 6462 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6463 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6464 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6465 MatCheckPreallocated(mat,1); 6466 6467 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6468 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6469 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6470 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6471 PetscFunctionReturn(0); 6472 } 6473 6474 /*@C 6475 MatGetSize - Returns the numbers of rows and columns in a matrix. 6476 6477 Not Collective 6478 6479 Input Parameter: 6480 . mat - the matrix 6481 6482 Output Parameters: 6483 + m - the number of global rows 6484 - n - the number of global columns 6485 6486 Note: both output parameters can be NULL on input. 6487 6488 Level: beginner 6489 6490 Concepts: matrices^size 6491 6492 .seealso: MatGetLocalSize() 6493 @*/ 6494 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6495 { 6496 PetscFunctionBegin; 6497 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6498 if (m) *m = mat->rmap->N; 6499 if (n) *n = mat->cmap->N; 6500 PetscFunctionReturn(0); 6501 } 6502 6503 /*@C 6504 MatGetLocalSize - Returns the number of rows and columns in a matrix 6505 stored locally. This information may be implementation dependent, so 6506 use with care. 6507 6508 Not Collective 6509 6510 Input Parameters: 6511 . mat - the matrix 6512 6513 Output Parameters: 6514 + m - the number of local rows 6515 - n - the number of local columns 6516 6517 Note: both output parameters can be NULL on input. 6518 6519 Level: beginner 6520 6521 Concepts: matrices^local size 6522 6523 .seealso: MatGetSize() 6524 @*/ 6525 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6526 { 6527 PetscFunctionBegin; 6528 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6529 if (m) PetscValidIntPointer(m,2); 6530 if (n) PetscValidIntPointer(n,3); 6531 if (m) *m = mat->rmap->n; 6532 if (n) *n = mat->cmap->n; 6533 PetscFunctionReturn(0); 6534 } 6535 6536 /*@C 6537 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6538 this processor. (The columns of the "diagonal block") 6539 6540 Not Collective, unless matrix has not been allocated, then collective on Mat 6541 6542 Input Parameters: 6543 . mat - the matrix 6544 6545 Output Parameters: 6546 + m - the global index of the first local column 6547 - n - one more than the global index of the last local column 6548 6549 Notes: 6550 both output parameters can be NULL on input. 6551 6552 Level: developer 6553 6554 Concepts: matrices^column ownership 6555 6556 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6557 6558 @*/ 6559 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6560 { 6561 PetscFunctionBegin; 6562 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6563 PetscValidType(mat,1); 6564 if (m) PetscValidIntPointer(m,2); 6565 if (n) PetscValidIntPointer(n,3); 6566 MatCheckPreallocated(mat,1); 6567 if (m) *m = mat->cmap->rstart; 6568 if (n) *n = mat->cmap->rend; 6569 PetscFunctionReturn(0); 6570 } 6571 6572 /*@C 6573 MatGetOwnershipRange - Returns the range of matrix rows owned by 6574 this processor, assuming that the matrix is laid out with the first 6575 n1 rows on the first processor, the next n2 rows on the second, etc. 6576 For certain parallel layouts this range may not be well defined. 6577 6578 Not Collective 6579 6580 Input Parameters: 6581 . mat - the matrix 6582 6583 Output Parameters: 6584 + m - the global index of the first local row 6585 - n - one more than the global index of the last local row 6586 6587 Note: Both output parameters can be NULL on input. 6588 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6589 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6590 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6591 6592 Level: beginner 6593 6594 Concepts: matrices^row ownership 6595 6596 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6597 6598 @*/ 6599 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6600 { 6601 PetscFunctionBegin; 6602 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6603 PetscValidType(mat,1); 6604 if (m) PetscValidIntPointer(m,2); 6605 if (n) PetscValidIntPointer(n,3); 6606 MatCheckPreallocated(mat,1); 6607 if (m) *m = mat->rmap->rstart; 6608 if (n) *n = mat->rmap->rend; 6609 PetscFunctionReturn(0); 6610 } 6611 6612 /*@C 6613 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6614 each process 6615 6616 Not Collective, unless matrix has not been allocated, then collective on Mat 6617 6618 Input Parameters: 6619 . mat - the matrix 6620 6621 Output Parameters: 6622 . ranges - start of each processors portion plus one more than the total length at the end 6623 6624 Level: beginner 6625 6626 Concepts: matrices^row ownership 6627 6628 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6629 6630 @*/ 6631 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6632 { 6633 PetscErrorCode ierr; 6634 6635 PetscFunctionBegin; 6636 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6637 PetscValidType(mat,1); 6638 MatCheckPreallocated(mat,1); 6639 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6640 PetscFunctionReturn(0); 6641 } 6642 6643 /*@C 6644 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6645 this processor. (The columns of the "diagonal blocks" for each process) 6646 6647 Not Collective, unless matrix has not been allocated, then collective on Mat 6648 6649 Input Parameters: 6650 . mat - the matrix 6651 6652 Output Parameters: 6653 . ranges - start of each processors portion plus one more then the total length at the end 6654 6655 Level: beginner 6656 6657 Concepts: matrices^column ownership 6658 6659 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6660 6661 @*/ 6662 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6663 { 6664 PetscErrorCode ierr; 6665 6666 PetscFunctionBegin; 6667 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6668 PetscValidType(mat,1); 6669 MatCheckPreallocated(mat,1); 6670 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6671 PetscFunctionReturn(0); 6672 } 6673 6674 /*@C 6675 MatGetOwnershipIS - Get row and column ownership as index sets 6676 6677 Not Collective 6678 6679 Input Arguments: 6680 . A - matrix of type Elemental 6681 6682 Output Arguments: 6683 + rows - rows in which this process owns elements 6684 . cols - columns in which this process owns elements 6685 6686 Level: intermediate 6687 6688 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6689 @*/ 6690 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6691 { 6692 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6693 6694 PetscFunctionBegin; 6695 MatCheckPreallocated(A,1); 6696 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6697 if (f) { 6698 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6699 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6700 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6701 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6702 } 6703 PetscFunctionReturn(0); 6704 } 6705 6706 /*@C 6707 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6708 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6709 to complete the factorization. 6710 6711 Collective on Mat 6712 6713 Input Parameters: 6714 + mat - the matrix 6715 . row - row permutation 6716 . column - column permutation 6717 - info - structure containing 6718 $ levels - number of levels of fill. 6719 $ expected fill - as ratio of original fill. 6720 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6721 missing diagonal entries) 6722 6723 Output Parameters: 6724 . fact - new matrix that has been symbolically factored 6725 6726 Notes: 6727 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6728 6729 Most users should employ the simplified KSP interface for linear solvers 6730 instead of working directly with matrix algebra routines such as this. 6731 See, e.g., KSPCreate(). 6732 6733 Level: developer 6734 6735 Concepts: matrices^symbolic LU factorization 6736 Concepts: matrices^factorization 6737 Concepts: LU^symbolic factorization 6738 6739 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6740 MatGetOrdering(), MatFactorInfo 6741 6742 Note: this uses the definition of level of fill as in Y. Saad, 2003 6743 6744 Developer Note: fortran interface is not autogenerated as the f90 6745 interface defintion cannot be generated correctly [due to MatFactorInfo] 6746 6747 References: 6748 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6749 @*/ 6750 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6751 { 6752 PetscErrorCode ierr; 6753 6754 PetscFunctionBegin; 6755 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6756 PetscValidType(mat,1); 6757 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6758 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6759 PetscValidPointer(info,4); 6760 PetscValidPointer(fact,5); 6761 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6762 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6763 if (!(fact)->ops->ilufactorsymbolic) { 6764 MatSolverType spackage; 6765 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6766 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6767 } 6768 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6769 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6770 MatCheckPreallocated(mat,2); 6771 6772 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6773 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6774 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6775 PetscFunctionReturn(0); 6776 } 6777 6778 /*@C 6779 MatICCFactorSymbolic - Performs symbolic incomplete 6780 Cholesky factorization for a symmetric matrix. Use 6781 MatCholeskyFactorNumeric() to complete the factorization. 6782 6783 Collective on Mat 6784 6785 Input Parameters: 6786 + mat - the matrix 6787 . perm - row and column permutation 6788 - info - structure containing 6789 $ levels - number of levels of fill. 6790 $ expected fill - as ratio of original fill. 6791 6792 Output Parameter: 6793 . fact - the factored matrix 6794 6795 Notes: 6796 Most users should employ the KSP interface for linear solvers 6797 instead of working directly with matrix algebra routines such as this. 6798 See, e.g., KSPCreate(). 6799 6800 Level: developer 6801 6802 Concepts: matrices^symbolic incomplete Cholesky factorization 6803 Concepts: matrices^factorization 6804 Concepts: Cholsky^symbolic factorization 6805 6806 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6807 6808 Note: this uses the definition of level of fill as in Y. Saad, 2003 6809 6810 Developer Note: fortran interface is not autogenerated as the f90 6811 interface defintion cannot be generated correctly [due to MatFactorInfo] 6812 6813 References: 6814 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6815 @*/ 6816 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6817 { 6818 PetscErrorCode ierr; 6819 6820 PetscFunctionBegin; 6821 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6822 PetscValidType(mat,1); 6823 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6824 PetscValidPointer(info,3); 6825 PetscValidPointer(fact,4); 6826 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6827 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6828 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6829 if (!(fact)->ops->iccfactorsymbolic) { 6830 MatSolverType spackage; 6831 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6832 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6833 } 6834 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6835 MatCheckPreallocated(mat,2); 6836 6837 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6838 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6839 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6840 PetscFunctionReturn(0); 6841 } 6842 6843 /*@C 6844 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6845 points to an array of valid matrices, they may be reused to store the new 6846 submatrices. 6847 6848 Collective on Mat 6849 6850 Input Parameters: 6851 + mat - the matrix 6852 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6853 . irow, icol - index sets of rows and columns to extract 6854 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6855 6856 Output Parameter: 6857 . submat - the array of submatrices 6858 6859 Notes: 6860 MatCreateSubMatrices() can extract ONLY sequential submatrices 6861 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6862 to extract a parallel submatrix. 6863 6864 Some matrix types place restrictions on the row and column 6865 indices, such as that they be sorted or that they be equal to each other. 6866 6867 The index sets may not have duplicate entries. 6868 6869 When extracting submatrices from a parallel matrix, each processor can 6870 form a different submatrix by setting the rows and columns of its 6871 individual index sets according to the local submatrix desired. 6872 6873 When finished using the submatrices, the user should destroy 6874 them with MatDestroySubMatrices(). 6875 6876 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6877 original matrix has not changed from that last call to MatCreateSubMatrices(). 6878 6879 This routine creates the matrices in submat; you should NOT create them before 6880 calling it. It also allocates the array of matrix pointers submat. 6881 6882 For BAIJ matrices the index sets must respect the block structure, that is if they 6883 request one row/column in a block, they must request all rows/columns that are in 6884 that block. For example, if the block size is 2 you cannot request just row 0 and 6885 column 0. 6886 6887 Fortran Note: 6888 The Fortran interface is slightly different from that given below; it 6889 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6890 6891 Level: advanced 6892 6893 Concepts: matrices^accessing submatrices 6894 Concepts: submatrices 6895 6896 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6897 @*/ 6898 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6899 { 6900 PetscErrorCode ierr; 6901 PetscInt i; 6902 PetscBool eq; 6903 6904 PetscFunctionBegin; 6905 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6906 PetscValidType(mat,1); 6907 if (n) { 6908 PetscValidPointer(irow,3); 6909 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6910 PetscValidPointer(icol,4); 6911 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6912 } 6913 PetscValidPointer(submat,6); 6914 if (n && scall == MAT_REUSE_MATRIX) { 6915 PetscValidPointer(*submat,6); 6916 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6917 } 6918 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6919 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6920 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6921 MatCheckPreallocated(mat,1); 6922 6923 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6924 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6925 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6926 for (i=0; i<n; i++) { 6927 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6928 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6929 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6930 if (eq) { 6931 if (mat->symmetric) { 6932 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6933 } else if (mat->hermitian) { 6934 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6935 } else if (mat->structurally_symmetric) { 6936 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6937 } 6938 } 6939 } 6940 } 6941 PetscFunctionReturn(0); 6942 } 6943 6944 /*@C 6945 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6946 6947 Collective on Mat 6948 6949 Input Parameters: 6950 + mat - the matrix 6951 . n - the number of submatrixes to be extracted 6952 . irow, icol - index sets of rows and columns to extract 6953 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6954 6955 Output Parameter: 6956 . submat - the array of submatrices 6957 6958 Level: advanced 6959 6960 Concepts: matrices^accessing submatrices 6961 Concepts: submatrices 6962 6963 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6964 @*/ 6965 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6966 { 6967 PetscErrorCode ierr; 6968 PetscInt i; 6969 PetscBool eq; 6970 6971 PetscFunctionBegin; 6972 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6973 PetscValidType(mat,1); 6974 if (n) { 6975 PetscValidPointer(irow,3); 6976 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6977 PetscValidPointer(icol,4); 6978 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6979 } 6980 PetscValidPointer(submat,6); 6981 if (n && scall == MAT_REUSE_MATRIX) { 6982 PetscValidPointer(*submat,6); 6983 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6984 } 6985 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6986 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6987 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6988 MatCheckPreallocated(mat,1); 6989 6990 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6991 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6992 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6993 for (i=0; i<n; i++) { 6994 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6995 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6996 if (eq) { 6997 if (mat->symmetric) { 6998 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6999 } else if (mat->hermitian) { 7000 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 7001 } else if (mat->structurally_symmetric) { 7002 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 7003 } 7004 } 7005 } 7006 } 7007 PetscFunctionReturn(0); 7008 } 7009 7010 /*@C 7011 MatDestroyMatrices - Destroys an array of matrices. 7012 7013 Collective on Mat 7014 7015 Input Parameters: 7016 + n - the number of local matrices 7017 - mat - the matrices (note that this is a pointer to the array of matrices) 7018 7019 Level: advanced 7020 7021 Notes: 7022 Frees not only the matrices, but also the array that contains the matrices 7023 In Fortran will not free the array. 7024 7025 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 7026 @*/ 7027 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7028 { 7029 PetscErrorCode ierr; 7030 PetscInt i; 7031 7032 PetscFunctionBegin; 7033 if (!*mat) PetscFunctionReturn(0); 7034 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 7035 PetscValidPointer(mat,2); 7036 7037 for (i=0; i<n; i++) { 7038 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 7039 } 7040 7041 /* memory is allocated even if n = 0 */ 7042 ierr = PetscFree(*mat);CHKERRQ(ierr); 7043 PetscFunctionReturn(0); 7044 } 7045 7046 /*@C 7047 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7048 7049 Collective on Mat 7050 7051 Input Parameters: 7052 + n - the number of local matrices 7053 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7054 sequence of MatCreateSubMatrices()) 7055 7056 Level: advanced 7057 7058 Notes: 7059 Frees not only the matrices, but also the array that contains the matrices 7060 In Fortran will not free the array. 7061 7062 .seealso: MatCreateSubMatrices() 7063 @*/ 7064 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7065 { 7066 PetscErrorCode ierr; 7067 Mat mat0; 7068 7069 PetscFunctionBegin; 7070 if (!*mat) PetscFunctionReturn(0); 7071 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7072 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 7073 PetscValidPointer(mat,2); 7074 7075 mat0 = (*mat)[0]; 7076 if (mat0 && mat0->ops->destroysubmatrices) { 7077 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 7078 } else { 7079 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 7080 } 7081 PetscFunctionReturn(0); 7082 } 7083 7084 /*@C 7085 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 7086 7087 Collective on Mat 7088 7089 Input Parameters: 7090 . mat - the matrix 7091 7092 Output Parameter: 7093 . matstruct - the sequential matrix with the nonzero structure of mat 7094 7095 Level: intermediate 7096 7097 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 7098 @*/ 7099 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7100 { 7101 PetscErrorCode ierr; 7102 7103 PetscFunctionBegin; 7104 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7105 PetscValidPointer(matstruct,2); 7106 7107 PetscValidType(mat,1); 7108 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7109 MatCheckPreallocated(mat,1); 7110 7111 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 7112 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7113 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 7114 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7115 PetscFunctionReturn(0); 7116 } 7117 7118 /*@C 7119 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7120 7121 Collective on Mat 7122 7123 Input Parameters: 7124 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7125 sequence of MatGetSequentialNonzeroStructure()) 7126 7127 Level: advanced 7128 7129 Notes: 7130 Frees not only the matrices, but also the array that contains the matrices 7131 7132 .seealso: MatGetSeqNonzeroStructure() 7133 @*/ 7134 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7135 { 7136 PetscErrorCode ierr; 7137 7138 PetscFunctionBegin; 7139 PetscValidPointer(mat,1); 7140 ierr = MatDestroy(mat);CHKERRQ(ierr); 7141 PetscFunctionReturn(0); 7142 } 7143 7144 /*@ 7145 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7146 replaces the index sets by larger ones that represent submatrices with 7147 additional overlap. 7148 7149 Collective on Mat 7150 7151 Input Parameters: 7152 + mat - the matrix 7153 . n - the number of index sets 7154 . is - the array of index sets (these index sets will changed during the call) 7155 - ov - the additional overlap requested 7156 7157 Options Database: 7158 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7159 7160 Level: developer 7161 7162 Concepts: overlap 7163 Concepts: ASM^computing overlap 7164 7165 .seealso: MatCreateSubMatrices() 7166 @*/ 7167 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7168 { 7169 PetscErrorCode ierr; 7170 7171 PetscFunctionBegin; 7172 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7173 PetscValidType(mat,1); 7174 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7175 if (n) { 7176 PetscValidPointer(is,3); 7177 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7178 } 7179 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7180 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7181 MatCheckPreallocated(mat,1); 7182 7183 if (!ov) PetscFunctionReturn(0); 7184 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7185 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7186 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 7187 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7188 PetscFunctionReturn(0); 7189 } 7190 7191 7192 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7193 7194 /*@ 7195 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7196 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7197 additional overlap. 7198 7199 Collective on Mat 7200 7201 Input Parameters: 7202 + mat - the matrix 7203 . n - the number of index sets 7204 . is - the array of index sets (these index sets will changed during the call) 7205 - ov - the additional overlap requested 7206 7207 Options Database: 7208 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7209 7210 Level: developer 7211 7212 Concepts: overlap 7213 Concepts: ASM^computing overlap 7214 7215 .seealso: MatCreateSubMatrices() 7216 @*/ 7217 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7218 { 7219 PetscInt i; 7220 PetscErrorCode ierr; 7221 7222 PetscFunctionBegin; 7223 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7224 PetscValidType(mat,1); 7225 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7226 if (n) { 7227 PetscValidPointer(is,3); 7228 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7229 } 7230 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7231 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7232 MatCheckPreallocated(mat,1); 7233 if (!ov) PetscFunctionReturn(0); 7234 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7235 for(i=0; i<n; i++){ 7236 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7237 } 7238 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7239 PetscFunctionReturn(0); 7240 } 7241 7242 7243 7244 7245 /*@ 7246 MatGetBlockSize - Returns the matrix block size. 7247 7248 Not Collective 7249 7250 Input Parameter: 7251 . mat - the matrix 7252 7253 Output Parameter: 7254 . bs - block size 7255 7256 Notes: 7257 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7258 7259 If the block size has not been set yet this routine returns 1. 7260 7261 Level: intermediate 7262 7263 Concepts: matrices^block size 7264 7265 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7266 @*/ 7267 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7268 { 7269 PetscFunctionBegin; 7270 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7271 PetscValidIntPointer(bs,2); 7272 *bs = PetscAbs(mat->rmap->bs); 7273 PetscFunctionReturn(0); 7274 } 7275 7276 /*@ 7277 MatGetBlockSizes - Returns the matrix block row and column sizes. 7278 7279 Not Collective 7280 7281 Input Parameter: 7282 . mat - the matrix 7283 7284 Output Parameter: 7285 . rbs - row block size 7286 . cbs - column block size 7287 7288 Notes: 7289 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7290 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7291 7292 If a block size has not been set yet this routine returns 1. 7293 7294 Level: intermediate 7295 7296 Concepts: matrices^block size 7297 7298 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7299 @*/ 7300 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7301 { 7302 PetscFunctionBegin; 7303 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7304 if (rbs) PetscValidIntPointer(rbs,2); 7305 if (cbs) PetscValidIntPointer(cbs,3); 7306 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7307 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7308 PetscFunctionReturn(0); 7309 } 7310 7311 /*@ 7312 MatSetBlockSize - Sets the matrix block size. 7313 7314 Logically Collective on Mat 7315 7316 Input Parameters: 7317 + mat - the matrix 7318 - bs - block size 7319 7320 Notes: 7321 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7322 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7323 7324 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7325 is compatible with the matrix local sizes. 7326 7327 Level: intermediate 7328 7329 Concepts: matrices^block size 7330 7331 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7332 @*/ 7333 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7334 { 7335 PetscErrorCode ierr; 7336 7337 PetscFunctionBegin; 7338 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7339 PetscValidLogicalCollectiveInt(mat,bs,2); 7340 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7341 PetscFunctionReturn(0); 7342 } 7343 7344 /*@ 7345 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7346 7347 Logically Collective on Mat 7348 7349 Input Parameters: 7350 + mat - the matrix 7351 . nblocks - the number of blocks on this process 7352 - bsizes - the block sizes 7353 7354 Notes: 7355 Currently used by PCVPBJACOBI for SeqAIJ matrices 7356 7357 Level: intermediate 7358 7359 Concepts: matrices^block size 7360 7361 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7362 @*/ 7363 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7364 { 7365 PetscErrorCode ierr; 7366 PetscInt i,ncnt = 0, nlocal; 7367 7368 PetscFunctionBegin; 7369 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7370 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7371 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7372 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7373 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); 7374 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7375 mat->nblocks = nblocks; 7376 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7377 ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr); 7378 PetscFunctionReturn(0); 7379 } 7380 7381 /*@C 7382 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7383 7384 Logically Collective on Mat 7385 7386 Input Parameters: 7387 . mat - the matrix 7388 7389 Output Parameters: 7390 + nblocks - the number of blocks on this process 7391 - bsizes - the block sizes 7392 7393 Notes: Currently not supported from Fortran 7394 7395 Level: intermediate 7396 7397 Concepts: matrices^block size 7398 7399 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7400 @*/ 7401 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7402 { 7403 PetscFunctionBegin; 7404 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7405 *nblocks = mat->nblocks; 7406 *bsizes = mat->bsizes; 7407 PetscFunctionReturn(0); 7408 } 7409 7410 /*@ 7411 MatSetBlockSizes - Sets the matrix block row and column sizes. 7412 7413 Logically Collective on Mat 7414 7415 Input Parameters: 7416 + mat - the matrix 7417 - rbs - row block size 7418 - cbs - column block size 7419 7420 Notes: 7421 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7422 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7423 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7424 7425 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7426 are compatible with the matrix local sizes. 7427 7428 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7429 7430 Level: intermediate 7431 7432 Concepts: matrices^block size 7433 7434 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7435 @*/ 7436 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7437 { 7438 PetscErrorCode ierr; 7439 7440 PetscFunctionBegin; 7441 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7442 PetscValidLogicalCollectiveInt(mat,rbs,2); 7443 PetscValidLogicalCollectiveInt(mat,cbs,3); 7444 if (mat->ops->setblocksizes) { 7445 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7446 } 7447 if (mat->rmap->refcnt) { 7448 ISLocalToGlobalMapping l2g = NULL; 7449 PetscLayout nmap = NULL; 7450 7451 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7452 if (mat->rmap->mapping) { 7453 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7454 } 7455 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7456 mat->rmap = nmap; 7457 mat->rmap->mapping = l2g; 7458 } 7459 if (mat->cmap->refcnt) { 7460 ISLocalToGlobalMapping l2g = NULL; 7461 PetscLayout nmap = NULL; 7462 7463 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7464 if (mat->cmap->mapping) { 7465 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7466 } 7467 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7468 mat->cmap = nmap; 7469 mat->cmap->mapping = l2g; 7470 } 7471 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7472 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7473 PetscFunctionReturn(0); 7474 } 7475 7476 /*@ 7477 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7478 7479 Logically Collective on Mat 7480 7481 Input Parameters: 7482 + mat - the matrix 7483 . fromRow - matrix from which to copy row block size 7484 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7485 7486 Level: developer 7487 7488 Concepts: matrices^block size 7489 7490 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7491 @*/ 7492 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7493 { 7494 PetscErrorCode ierr; 7495 7496 PetscFunctionBegin; 7497 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7498 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7499 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7500 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7501 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7502 PetscFunctionReturn(0); 7503 } 7504 7505 /*@ 7506 MatResidual - Default routine to calculate the residual. 7507 7508 Collective on Mat and Vec 7509 7510 Input Parameters: 7511 + mat - the matrix 7512 . b - the right-hand-side 7513 - x - the approximate solution 7514 7515 Output Parameter: 7516 . r - location to store the residual 7517 7518 Level: developer 7519 7520 .keywords: MG, default, multigrid, residual 7521 7522 .seealso: PCMGSetResidual() 7523 @*/ 7524 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7525 { 7526 PetscErrorCode ierr; 7527 7528 PetscFunctionBegin; 7529 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7530 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7531 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7532 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7533 PetscValidType(mat,1); 7534 MatCheckPreallocated(mat,1); 7535 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7536 if (!mat->ops->residual) { 7537 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7538 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7539 } else { 7540 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7541 } 7542 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7543 PetscFunctionReturn(0); 7544 } 7545 7546 /*@C 7547 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7548 7549 Collective on Mat 7550 7551 Input Parameters: 7552 + mat - the matrix 7553 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7554 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7555 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7556 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7557 always used. 7558 7559 Output Parameters: 7560 + n - number of rows in the (possibly compressed) matrix 7561 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7562 . ja - the column indices 7563 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7564 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7565 7566 Level: developer 7567 7568 Notes: 7569 You CANNOT change any of the ia[] or ja[] values. 7570 7571 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7572 7573 Fortran Notes: 7574 In Fortran use 7575 $ 7576 $ PetscInt ia(1), ja(1) 7577 $ PetscOffset iia, jja 7578 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7579 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7580 7581 or 7582 $ 7583 $ PetscInt, pointer :: ia(:),ja(:) 7584 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7585 $ ! Access the ith and jth entries via ia(i) and ja(j) 7586 7587 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7588 @*/ 7589 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7590 { 7591 PetscErrorCode ierr; 7592 7593 PetscFunctionBegin; 7594 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7595 PetscValidType(mat,1); 7596 PetscValidIntPointer(n,5); 7597 if (ia) PetscValidIntPointer(ia,6); 7598 if (ja) PetscValidIntPointer(ja,7); 7599 PetscValidIntPointer(done,8); 7600 MatCheckPreallocated(mat,1); 7601 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7602 else { 7603 *done = PETSC_TRUE; 7604 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7605 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7606 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7607 } 7608 PetscFunctionReturn(0); 7609 } 7610 7611 /*@C 7612 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7613 7614 Collective on Mat 7615 7616 Input Parameters: 7617 + mat - the matrix 7618 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7619 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7620 symmetrized 7621 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7622 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7623 always used. 7624 . n - number of columns in the (possibly compressed) matrix 7625 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7626 - ja - the row indices 7627 7628 Output Parameters: 7629 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7630 7631 Level: developer 7632 7633 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7634 @*/ 7635 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7636 { 7637 PetscErrorCode ierr; 7638 7639 PetscFunctionBegin; 7640 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7641 PetscValidType(mat,1); 7642 PetscValidIntPointer(n,4); 7643 if (ia) PetscValidIntPointer(ia,5); 7644 if (ja) PetscValidIntPointer(ja,6); 7645 PetscValidIntPointer(done,7); 7646 MatCheckPreallocated(mat,1); 7647 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7648 else { 7649 *done = PETSC_TRUE; 7650 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7651 } 7652 PetscFunctionReturn(0); 7653 } 7654 7655 /*@C 7656 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7657 MatGetRowIJ(). 7658 7659 Collective on Mat 7660 7661 Input Parameters: 7662 + mat - the matrix 7663 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7664 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7665 symmetrized 7666 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7667 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7668 always used. 7669 . n - size of (possibly compressed) matrix 7670 . ia - the row pointers 7671 - ja - the column indices 7672 7673 Output Parameters: 7674 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7675 7676 Note: 7677 This routine zeros out n, ia, and ja. This is to prevent accidental 7678 us of the array after it has been restored. If you pass NULL, it will 7679 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7680 7681 Level: developer 7682 7683 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7684 @*/ 7685 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7686 { 7687 PetscErrorCode ierr; 7688 7689 PetscFunctionBegin; 7690 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7691 PetscValidType(mat,1); 7692 if (ia) PetscValidIntPointer(ia,6); 7693 if (ja) PetscValidIntPointer(ja,7); 7694 PetscValidIntPointer(done,8); 7695 MatCheckPreallocated(mat,1); 7696 7697 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7698 else { 7699 *done = PETSC_TRUE; 7700 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7701 if (n) *n = 0; 7702 if (ia) *ia = NULL; 7703 if (ja) *ja = NULL; 7704 } 7705 PetscFunctionReturn(0); 7706 } 7707 7708 /*@C 7709 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7710 MatGetColumnIJ(). 7711 7712 Collective on Mat 7713 7714 Input Parameters: 7715 + mat - the matrix 7716 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7717 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7718 symmetrized 7719 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7720 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7721 always used. 7722 7723 Output Parameters: 7724 + n - size of (possibly compressed) matrix 7725 . ia - the column pointers 7726 . ja - the row indices 7727 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7728 7729 Level: developer 7730 7731 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7732 @*/ 7733 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7734 { 7735 PetscErrorCode ierr; 7736 7737 PetscFunctionBegin; 7738 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7739 PetscValidType(mat,1); 7740 if (ia) PetscValidIntPointer(ia,5); 7741 if (ja) PetscValidIntPointer(ja,6); 7742 PetscValidIntPointer(done,7); 7743 MatCheckPreallocated(mat,1); 7744 7745 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7746 else { 7747 *done = PETSC_TRUE; 7748 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7749 if (n) *n = 0; 7750 if (ia) *ia = NULL; 7751 if (ja) *ja = NULL; 7752 } 7753 PetscFunctionReturn(0); 7754 } 7755 7756 /*@C 7757 MatColoringPatch -Used inside matrix coloring routines that 7758 use MatGetRowIJ() and/or MatGetColumnIJ(). 7759 7760 Collective on Mat 7761 7762 Input Parameters: 7763 + mat - the matrix 7764 . ncolors - max color value 7765 . n - number of entries in colorarray 7766 - colorarray - array indicating color for each column 7767 7768 Output Parameters: 7769 . iscoloring - coloring generated using colorarray information 7770 7771 Level: developer 7772 7773 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7774 7775 @*/ 7776 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7777 { 7778 PetscErrorCode ierr; 7779 7780 PetscFunctionBegin; 7781 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7782 PetscValidType(mat,1); 7783 PetscValidIntPointer(colorarray,4); 7784 PetscValidPointer(iscoloring,5); 7785 MatCheckPreallocated(mat,1); 7786 7787 if (!mat->ops->coloringpatch) { 7788 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7789 } else { 7790 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7791 } 7792 PetscFunctionReturn(0); 7793 } 7794 7795 7796 /*@ 7797 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7798 7799 Logically Collective on Mat 7800 7801 Input Parameter: 7802 . mat - the factored matrix to be reset 7803 7804 Notes: 7805 This routine should be used only with factored matrices formed by in-place 7806 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7807 format). This option can save memory, for example, when solving nonlinear 7808 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7809 ILU(0) preconditioner. 7810 7811 Note that one can specify in-place ILU(0) factorization by calling 7812 .vb 7813 PCType(pc,PCILU); 7814 PCFactorSeUseInPlace(pc); 7815 .ve 7816 or by using the options -pc_type ilu -pc_factor_in_place 7817 7818 In-place factorization ILU(0) can also be used as a local 7819 solver for the blocks within the block Jacobi or additive Schwarz 7820 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7821 for details on setting local solver options. 7822 7823 Most users should employ the simplified KSP interface for linear solvers 7824 instead of working directly with matrix algebra routines such as this. 7825 See, e.g., KSPCreate(). 7826 7827 Level: developer 7828 7829 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7830 7831 Concepts: matrices^unfactored 7832 7833 @*/ 7834 PetscErrorCode MatSetUnfactored(Mat mat) 7835 { 7836 PetscErrorCode ierr; 7837 7838 PetscFunctionBegin; 7839 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7840 PetscValidType(mat,1); 7841 MatCheckPreallocated(mat,1); 7842 mat->factortype = MAT_FACTOR_NONE; 7843 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7844 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7845 PetscFunctionReturn(0); 7846 } 7847 7848 /*MC 7849 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7850 7851 Synopsis: 7852 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7853 7854 Not collective 7855 7856 Input Parameter: 7857 . x - matrix 7858 7859 Output Parameters: 7860 + xx_v - the Fortran90 pointer to the array 7861 - ierr - error code 7862 7863 Example of Usage: 7864 .vb 7865 PetscScalar, pointer xx_v(:,:) 7866 .... 7867 call MatDenseGetArrayF90(x,xx_v,ierr) 7868 a = xx_v(3) 7869 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7870 .ve 7871 7872 Level: advanced 7873 7874 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7875 7876 Concepts: matrices^accessing array 7877 7878 M*/ 7879 7880 /*MC 7881 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7882 accessed with MatDenseGetArrayF90(). 7883 7884 Synopsis: 7885 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7886 7887 Not collective 7888 7889 Input Parameters: 7890 + x - matrix 7891 - xx_v - the Fortran90 pointer to the array 7892 7893 Output Parameter: 7894 . ierr - error code 7895 7896 Example of Usage: 7897 .vb 7898 PetscScalar, pointer xx_v(:,:) 7899 .... 7900 call MatDenseGetArrayF90(x,xx_v,ierr) 7901 a = xx_v(3) 7902 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7903 .ve 7904 7905 Level: advanced 7906 7907 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7908 7909 M*/ 7910 7911 7912 /*MC 7913 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7914 7915 Synopsis: 7916 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7917 7918 Not collective 7919 7920 Input Parameter: 7921 . x - matrix 7922 7923 Output Parameters: 7924 + xx_v - the Fortran90 pointer to the array 7925 - ierr - error code 7926 7927 Example of Usage: 7928 .vb 7929 PetscScalar, pointer xx_v(:) 7930 .... 7931 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7932 a = xx_v(3) 7933 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7934 .ve 7935 7936 Level: advanced 7937 7938 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7939 7940 Concepts: matrices^accessing array 7941 7942 M*/ 7943 7944 /*MC 7945 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7946 accessed with MatSeqAIJGetArrayF90(). 7947 7948 Synopsis: 7949 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7950 7951 Not collective 7952 7953 Input Parameters: 7954 + x - matrix 7955 - xx_v - the Fortran90 pointer to the array 7956 7957 Output Parameter: 7958 . ierr - error code 7959 7960 Example of Usage: 7961 .vb 7962 PetscScalar, pointer xx_v(:) 7963 .... 7964 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7965 a = xx_v(3) 7966 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7967 .ve 7968 7969 Level: advanced 7970 7971 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7972 7973 M*/ 7974 7975 7976 /*@ 7977 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7978 as the original matrix. 7979 7980 Collective on Mat 7981 7982 Input Parameters: 7983 + mat - the original matrix 7984 . isrow - parallel IS containing the rows this processor should obtain 7985 . 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. 7986 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7987 7988 Output Parameter: 7989 . newmat - the new submatrix, of the same type as the old 7990 7991 Level: advanced 7992 7993 Notes: 7994 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7995 7996 Some matrix types place restrictions on the row and column indices, such 7997 as that they be sorted or that they be equal to each other. 7998 7999 The index sets may not have duplicate entries. 8000 8001 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8002 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8003 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8004 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8005 you are finished using it. 8006 8007 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8008 the input matrix. 8009 8010 If iscol is NULL then all columns are obtained (not supported in Fortran). 8011 8012 Example usage: 8013 Consider the following 8x8 matrix with 34 non-zero values, that is 8014 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8015 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8016 as follows: 8017 8018 .vb 8019 1 2 0 | 0 3 0 | 0 4 8020 Proc0 0 5 6 | 7 0 0 | 8 0 8021 9 0 10 | 11 0 0 | 12 0 8022 ------------------------------------- 8023 13 0 14 | 15 16 17 | 0 0 8024 Proc1 0 18 0 | 19 20 21 | 0 0 8025 0 0 0 | 22 23 0 | 24 0 8026 ------------------------------------- 8027 Proc2 25 26 27 | 0 0 28 | 29 0 8028 30 0 0 | 31 32 33 | 0 34 8029 .ve 8030 8031 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8032 8033 .vb 8034 2 0 | 0 3 0 | 0 8035 Proc0 5 6 | 7 0 0 | 8 8036 ------------------------------- 8037 Proc1 18 0 | 19 20 21 | 0 8038 ------------------------------- 8039 Proc2 26 27 | 0 0 28 | 29 8040 0 0 | 31 32 33 | 0 8041 .ve 8042 8043 8044 Concepts: matrices^submatrices 8045 8046 .seealso: MatCreateSubMatrices() 8047 @*/ 8048 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8049 { 8050 PetscErrorCode ierr; 8051 PetscMPIInt size; 8052 Mat *local; 8053 IS iscoltmp; 8054 8055 PetscFunctionBegin; 8056 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8057 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8058 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8059 PetscValidPointer(newmat,5); 8060 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8061 PetscValidType(mat,1); 8062 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8063 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8064 8065 MatCheckPreallocated(mat,1); 8066 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8067 8068 if (!iscol || isrow == iscol) { 8069 PetscBool stride; 8070 PetscMPIInt grabentirematrix = 0,grab; 8071 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 8072 if (stride) { 8073 PetscInt first,step,n,rstart,rend; 8074 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 8075 if (step == 1) { 8076 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 8077 if (rstart == first) { 8078 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 8079 if (n == rend-rstart) { 8080 grabentirematrix = 1; 8081 } 8082 } 8083 } 8084 } 8085 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 8086 if (grab) { 8087 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 8088 if (cll == MAT_INITIAL_MATRIX) { 8089 *newmat = mat; 8090 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 8091 } 8092 PetscFunctionReturn(0); 8093 } 8094 } 8095 8096 if (!iscol) { 8097 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 8098 } else { 8099 iscoltmp = iscol; 8100 } 8101 8102 /* if original matrix is on just one processor then use submatrix generated */ 8103 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8104 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 8105 goto setproperties; 8106 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8107 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 8108 *newmat = *local; 8109 ierr = PetscFree(local);CHKERRQ(ierr); 8110 goto setproperties; 8111 } else if (!mat->ops->createsubmatrix) { 8112 /* Create a new matrix type that implements the operation using the full matrix */ 8113 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8114 switch (cll) { 8115 case MAT_INITIAL_MATRIX: 8116 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 8117 break; 8118 case MAT_REUSE_MATRIX: 8119 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 8120 break; 8121 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8122 } 8123 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8124 goto setproperties; 8125 } 8126 8127 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8128 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8129 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 8130 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8131 8132 /* Propagate symmetry information for diagonal blocks */ 8133 setproperties: 8134 if (isrow == iscoltmp) { 8135 if (mat->symmetric_set && mat->symmetric) { 8136 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8137 } 8138 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 8139 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8140 } 8141 if (mat->hermitian_set && mat->hermitian) { 8142 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 8143 } 8144 if (mat->spd_set && mat->spd) { 8145 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 8146 } 8147 } 8148 8149 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8150 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 8151 PetscFunctionReturn(0); 8152 } 8153 8154 /*@ 8155 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8156 used during the assembly process to store values that belong to 8157 other processors. 8158 8159 Not Collective 8160 8161 Input Parameters: 8162 + mat - the matrix 8163 . size - the initial size of the stash. 8164 - bsize - the initial size of the block-stash(if used). 8165 8166 Options Database Keys: 8167 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8168 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8169 8170 Level: intermediate 8171 8172 Notes: 8173 The block-stash is used for values set with MatSetValuesBlocked() while 8174 the stash is used for values set with MatSetValues() 8175 8176 Run with the option -info and look for output of the form 8177 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8178 to determine the appropriate value, MM, to use for size and 8179 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8180 to determine the value, BMM to use for bsize 8181 8182 Concepts: stash^setting matrix size 8183 Concepts: matrices^stash 8184 8185 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 8186 8187 @*/ 8188 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8189 { 8190 PetscErrorCode ierr; 8191 8192 PetscFunctionBegin; 8193 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8194 PetscValidType(mat,1); 8195 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 8196 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 8197 PetscFunctionReturn(0); 8198 } 8199 8200 /*@ 8201 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8202 the matrix 8203 8204 Neighbor-wise Collective on Mat 8205 8206 Input Parameters: 8207 + mat - the matrix 8208 . x,y - the vectors 8209 - w - where the result is stored 8210 8211 Level: intermediate 8212 8213 Notes: 8214 w may be the same vector as y. 8215 8216 This allows one to use either the restriction or interpolation (its transpose) 8217 matrix to do the interpolation 8218 8219 Concepts: interpolation 8220 8221 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8222 8223 @*/ 8224 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8225 { 8226 PetscErrorCode ierr; 8227 PetscInt M,N,Ny; 8228 8229 PetscFunctionBegin; 8230 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8231 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8232 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8233 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8234 PetscValidType(A,1); 8235 MatCheckPreallocated(A,1); 8236 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8237 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8238 if (M == Ny) { 8239 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8240 } else { 8241 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8242 } 8243 PetscFunctionReturn(0); 8244 } 8245 8246 /*@ 8247 MatInterpolate - y = A*x or A'*x depending on the shape of 8248 the matrix 8249 8250 Neighbor-wise Collective on Mat 8251 8252 Input Parameters: 8253 + mat - the matrix 8254 - x,y - the vectors 8255 8256 Level: intermediate 8257 8258 Notes: 8259 This allows one to use either the restriction or interpolation (its transpose) 8260 matrix to do the interpolation 8261 8262 Concepts: matrices^interpolation 8263 8264 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8265 8266 @*/ 8267 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8268 { 8269 PetscErrorCode ierr; 8270 PetscInt M,N,Ny; 8271 8272 PetscFunctionBegin; 8273 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8274 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8275 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8276 PetscValidType(A,1); 8277 MatCheckPreallocated(A,1); 8278 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8279 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8280 if (M == Ny) { 8281 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8282 } else { 8283 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8284 } 8285 PetscFunctionReturn(0); 8286 } 8287 8288 /*@ 8289 MatRestrict - y = A*x or A'*x 8290 8291 Neighbor-wise Collective on Mat 8292 8293 Input Parameters: 8294 + mat - the matrix 8295 - x,y - the vectors 8296 8297 Level: intermediate 8298 8299 Notes: 8300 This allows one to use either the restriction or interpolation (its transpose) 8301 matrix to do the restriction 8302 8303 Concepts: matrices^restriction 8304 8305 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8306 8307 @*/ 8308 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8309 { 8310 PetscErrorCode ierr; 8311 PetscInt M,N,Ny; 8312 8313 PetscFunctionBegin; 8314 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8315 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8316 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8317 PetscValidType(A,1); 8318 MatCheckPreallocated(A,1); 8319 8320 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8321 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8322 if (M == Ny) { 8323 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8324 } else { 8325 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8326 } 8327 PetscFunctionReturn(0); 8328 } 8329 8330 /*@ 8331 MatGetNullSpace - retrieves the null space of a matrix. 8332 8333 Logically Collective on Mat and MatNullSpace 8334 8335 Input Parameters: 8336 + mat - the matrix 8337 - nullsp - the null space object 8338 8339 Level: developer 8340 8341 Concepts: null space^attaching to matrix 8342 8343 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8344 @*/ 8345 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8346 { 8347 PetscFunctionBegin; 8348 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8349 PetscValidPointer(nullsp,2); 8350 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8351 PetscFunctionReturn(0); 8352 } 8353 8354 /*@ 8355 MatSetNullSpace - attaches a null space to a matrix. 8356 8357 Logically Collective on Mat and MatNullSpace 8358 8359 Input Parameters: 8360 + mat - the matrix 8361 - nullsp - the null space object 8362 8363 Level: advanced 8364 8365 Notes: 8366 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8367 8368 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8369 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8370 8371 You can remove the null space by calling this routine with an nullsp of NULL 8372 8373 8374 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8375 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). 8376 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 8377 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 8378 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). 8379 8380 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8381 8382 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 8383 routine also automatically calls MatSetTransposeNullSpace(). 8384 8385 Concepts: null space^attaching to matrix 8386 8387 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8388 @*/ 8389 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8390 { 8391 PetscErrorCode ierr; 8392 8393 PetscFunctionBegin; 8394 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8395 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8396 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8397 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8398 mat->nullsp = nullsp; 8399 if (mat->symmetric_set && mat->symmetric) { 8400 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8401 } 8402 PetscFunctionReturn(0); 8403 } 8404 8405 /*@ 8406 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8407 8408 Logically Collective on Mat and MatNullSpace 8409 8410 Input Parameters: 8411 + mat - the matrix 8412 - nullsp - the null space object 8413 8414 Level: developer 8415 8416 Concepts: null space^attaching to matrix 8417 8418 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8419 @*/ 8420 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8421 { 8422 PetscFunctionBegin; 8423 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8424 PetscValidType(mat,1); 8425 PetscValidPointer(nullsp,2); 8426 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8427 PetscFunctionReturn(0); 8428 } 8429 8430 /*@ 8431 MatSetTransposeNullSpace - attaches a null space to a matrix. 8432 8433 Logically Collective on Mat and MatNullSpace 8434 8435 Input Parameters: 8436 + mat - the matrix 8437 - nullsp - the null space object 8438 8439 Level: advanced 8440 8441 Notes: 8442 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. 8443 You must also call MatSetNullSpace() 8444 8445 8446 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8447 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). 8448 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 8449 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 8450 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). 8451 8452 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8453 8454 Concepts: null space^attaching to matrix 8455 8456 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8457 @*/ 8458 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8459 { 8460 PetscErrorCode ierr; 8461 8462 PetscFunctionBegin; 8463 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8464 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8465 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8466 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8467 mat->transnullsp = nullsp; 8468 PetscFunctionReturn(0); 8469 } 8470 8471 /*@ 8472 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8473 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8474 8475 Logically Collective on Mat and MatNullSpace 8476 8477 Input Parameters: 8478 + mat - the matrix 8479 - nullsp - the null space object 8480 8481 Level: advanced 8482 8483 Notes: 8484 Overwrites any previous near null space that may have been attached 8485 8486 You can remove the null space by calling this routine with an nullsp of NULL 8487 8488 Concepts: null space^attaching to matrix 8489 8490 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8491 @*/ 8492 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8493 { 8494 PetscErrorCode ierr; 8495 8496 PetscFunctionBegin; 8497 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8498 PetscValidType(mat,1); 8499 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8500 MatCheckPreallocated(mat,1); 8501 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8502 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8503 mat->nearnullsp = nullsp; 8504 PetscFunctionReturn(0); 8505 } 8506 8507 /*@ 8508 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8509 8510 Not Collective 8511 8512 Input Parameters: 8513 . mat - the matrix 8514 8515 Output Parameters: 8516 . nullsp - the null space object, NULL if not set 8517 8518 Level: developer 8519 8520 Concepts: null space^attaching to matrix 8521 8522 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8523 @*/ 8524 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8525 { 8526 PetscFunctionBegin; 8527 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8528 PetscValidType(mat,1); 8529 PetscValidPointer(nullsp,2); 8530 MatCheckPreallocated(mat,1); 8531 *nullsp = mat->nearnullsp; 8532 PetscFunctionReturn(0); 8533 } 8534 8535 /*@C 8536 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8537 8538 Collective on Mat 8539 8540 Input Parameters: 8541 + mat - the matrix 8542 . row - row/column permutation 8543 . fill - expected fill factor >= 1.0 8544 - level - level of fill, for ICC(k) 8545 8546 Notes: 8547 Probably really in-place only when level of fill is zero, otherwise allocates 8548 new space to store factored matrix and deletes previous memory. 8549 8550 Most users should employ the simplified KSP interface for linear solvers 8551 instead of working directly with matrix algebra routines such as this. 8552 See, e.g., KSPCreate(). 8553 8554 Level: developer 8555 8556 Concepts: matrices^incomplete Cholesky factorization 8557 Concepts: Cholesky factorization 8558 8559 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8560 8561 Developer Note: fortran interface is not autogenerated as the f90 8562 interface defintion cannot be generated correctly [due to MatFactorInfo] 8563 8564 @*/ 8565 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8566 { 8567 PetscErrorCode ierr; 8568 8569 PetscFunctionBegin; 8570 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8571 PetscValidType(mat,1); 8572 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8573 PetscValidPointer(info,3); 8574 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8575 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8576 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8577 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8578 MatCheckPreallocated(mat,1); 8579 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8580 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8581 PetscFunctionReturn(0); 8582 } 8583 8584 /*@ 8585 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8586 ghosted ones. 8587 8588 Not Collective 8589 8590 Input Parameters: 8591 + mat - the matrix 8592 - diag = the diagonal values, including ghost ones 8593 8594 Level: developer 8595 8596 Notes: 8597 Works only for MPIAIJ and MPIBAIJ matrices 8598 8599 .seealso: MatDiagonalScale() 8600 @*/ 8601 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8602 { 8603 PetscErrorCode ierr; 8604 PetscMPIInt size; 8605 8606 PetscFunctionBegin; 8607 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8608 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8609 PetscValidType(mat,1); 8610 8611 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8612 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8613 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8614 if (size == 1) { 8615 PetscInt n,m; 8616 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8617 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8618 if (m == n) { 8619 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8620 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8621 } else { 8622 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8623 } 8624 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8625 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8626 PetscFunctionReturn(0); 8627 } 8628 8629 /*@ 8630 MatGetInertia - Gets the inertia from a factored matrix 8631 8632 Collective on Mat 8633 8634 Input Parameter: 8635 . mat - the matrix 8636 8637 Output Parameters: 8638 + nneg - number of negative eigenvalues 8639 . nzero - number of zero eigenvalues 8640 - npos - number of positive eigenvalues 8641 8642 Level: advanced 8643 8644 Notes: 8645 Matrix must have been factored by MatCholeskyFactor() 8646 8647 8648 @*/ 8649 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8650 { 8651 PetscErrorCode ierr; 8652 8653 PetscFunctionBegin; 8654 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8655 PetscValidType(mat,1); 8656 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8657 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8658 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8659 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8660 PetscFunctionReturn(0); 8661 } 8662 8663 /* ----------------------------------------------------------------*/ 8664 /*@C 8665 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8666 8667 Neighbor-wise Collective on Mat and Vecs 8668 8669 Input Parameters: 8670 + mat - the factored matrix 8671 - b - the right-hand-side vectors 8672 8673 Output Parameter: 8674 . x - the result vectors 8675 8676 Notes: 8677 The vectors b and x cannot be the same. I.e., one cannot 8678 call MatSolves(A,x,x). 8679 8680 Notes: 8681 Most users should employ the simplified KSP interface for linear solvers 8682 instead of working directly with matrix algebra routines such as this. 8683 See, e.g., KSPCreate(). 8684 8685 Level: developer 8686 8687 Concepts: matrices^triangular solves 8688 8689 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8690 @*/ 8691 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8692 { 8693 PetscErrorCode ierr; 8694 8695 PetscFunctionBegin; 8696 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8697 PetscValidType(mat,1); 8698 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8699 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8700 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8701 8702 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8703 MatCheckPreallocated(mat,1); 8704 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8705 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8706 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8707 PetscFunctionReturn(0); 8708 } 8709 8710 /*@ 8711 MatIsSymmetric - Test whether a matrix is symmetric 8712 8713 Collective on Mat 8714 8715 Input Parameter: 8716 + A - the matrix to test 8717 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8718 8719 Output Parameters: 8720 . flg - the result 8721 8722 Notes: 8723 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8724 8725 Level: intermediate 8726 8727 Concepts: matrix^symmetry 8728 8729 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8730 @*/ 8731 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8732 { 8733 PetscErrorCode ierr; 8734 8735 PetscFunctionBegin; 8736 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8737 PetscValidPointer(flg,2); 8738 8739 if (!A->symmetric_set) { 8740 if (!A->ops->issymmetric) { 8741 MatType mattype; 8742 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8743 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8744 } 8745 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8746 if (!tol) { 8747 A->symmetric_set = PETSC_TRUE; 8748 A->symmetric = *flg; 8749 if (A->symmetric) { 8750 A->structurally_symmetric_set = PETSC_TRUE; 8751 A->structurally_symmetric = PETSC_TRUE; 8752 } 8753 } 8754 } else if (A->symmetric) { 8755 *flg = PETSC_TRUE; 8756 } else if (!tol) { 8757 *flg = PETSC_FALSE; 8758 } else { 8759 if (!A->ops->issymmetric) { 8760 MatType mattype; 8761 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8762 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8763 } 8764 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8765 } 8766 PetscFunctionReturn(0); 8767 } 8768 8769 /*@ 8770 MatIsHermitian - Test whether a matrix is Hermitian 8771 8772 Collective on Mat 8773 8774 Input Parameter: 8775 + A - the matrix to test 8776 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8777 8778 Output Parameters: 8779 . flg - the result 8780 8781 Level: intermediate 8782 8783 Concepts: matrix^symmetry 8784 8785 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8786 MatIsSymmetricKnown(), MatIsSymmetric() 8787 @*/ 8788 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8789 { 8790 PetscErrorCode ierr; 8791 8792 PetscFunctionBegin; 8793 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8794 PetscValidPointer(flg,2); 8795 8796 if (!A->hermitian_set) { 8797 if (!A->ops->ishermitian) { 8798 MatType mattype; 8799 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8800 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8801 } 8802 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8803 if (!tol) { 8804 A->hermitian_set = PETSC_TRUE; 8805 A->hermitian = *flg; 8806 if (A->hermitian) { 8807 A->structurally_symmetric_set = PETSC_TRUE; 8808 A->structurally_symmetric = PETSC_TRUE; 8809 } 8810 } 8811 } else if (A->hermitian) { 8812 *flg = PETSC_TRUE; 8813 } else if (!tol) { 8814 *flg = PETSC_FALSE; 8815 } else { 8816 if (!A->ops->ishermitian) { 8817 MatType mattype; 8818 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8819 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8820 } 8821 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8822 } 8823 PetscFunctionReturn(0); 8824 } 8825 8826 /*@ 8827 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8828 8829 Not Collective 8830 8831 Input Parameter: 8832 . A - the matrix to check 8833 8834 Output Parameters: 8835 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8836 - flg - the result 8837 8838 Level: advanced 8839 8840 Concepts: matrix^symmetry 8841 8842 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8843 if you want it explicitly checked 8844 8845 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8846 @*/ 8847 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8848 { 8849 PetscFunctionBegin; 8850 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8851 PetscValidPointer(set,2); 8852 PetscValidPointer(flg,3); 8853 if (A->symmetric_set) { 8854 *set = PETSC_TRUE; 8855 *flg = A->symmetric; 8856 } else { 8857 *set = PETSC_FALSE; 8858 } 8859 PetscFunctionReturn(0); 8860 } 8861 8862 /*@ 8863 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8864 8865 Not Collective 8866 8867 Input Parameter: 8868 . A - the matrix to check 8869 8870 Output Parameters: 8871 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8872 - flg - the result 8873 8874 Level: advanced 8875 8876 Concepts: matrix^symmetry 8877 8878 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8879 if you want it explicitly checked 8880 8881 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8882 @*/ 8883 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8884 { 8885 PetscFunctionBegin; 8886 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8887 PetscValidPointer(set,2); 8888 PetscValidPointer(flg,3); 8889 if (A->hermitian_set) { 8890 *set = PETSC_TRUE; 8891 *flg = A->hermitian; 8892 } else { 8893 *set = PETSC_FALSE; 8894 } 8895 PetscFunctionReturn(0); 8896 } 8897 8898 /*@ 8899 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8900 8901 Collective on Mat 8902 8903 Input Parameter: 8904 . A - the matrix to test 8905 8906 Output Parameters: 8907 . flg - the result 8908 8909 Level: intermediate 8910 8911 Concepts: matrix^symmetry 8912 8913 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8914 @*/ 8915 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8916 { 8917 PetscErrorCode ierr; 8918 8919 PetscFunctionBegin; 8920 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8921 PetscValidPointer(flg,2); 8922 if (!A->structurally_symmetric_set) { 8923 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8924 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8925 8926 A->structurally_symmetric_set = PETSC_TRUE; 8927 } 8928 *flg = A->structurally_symmetric; 8929 PetscFunctionReturn(0); 8930 } 8931 8932 /*@ 8933 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8934 to be communicated to other processors during the MatAssemblyBegin/End() process 8935 8936 Not collective 8937 8938 Input Parameter: 8939 . vec - the vector 8940 8941 Output Parameters: 8942 + nstash - the size of the stash 8943 . reallocs - the number of additional mallocs incurred. 8944 . bnstash - the size of the block stash 8945 - breallocs - the number of additional mallocs incurred.in the block stash 8946 8947 Level: advanced 8948 8949 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8950 8951 @*/ 8952 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8953 { 8954 PetscErrorCode ierr; 8955 8956 PetscFunctionBegin; 8957 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8958 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8959 PetscFunctionReturn(0); 8960 } 8961 8962 /*@C 8963 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8964 parallel layout 8965 8966 Collective on Mat 8967 8968 Input Parameter: 8969 . mat - the matrix 8970 8971 Output Parameter: 8972 + right - (optional) vector that the matrix can be multiplied against 8973 - left - (optional) vector that the matrix vector product can be stored in 8974 8975 Notes: 8976 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(). 8977 8978 Notes: 8979 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8980 8981 Level: advanced 8982 8983 .seealso: MatCreate(), VecDestroy() 8984 @*/ 8985 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8986 { 8987 PetscErrorCode ierr; 8988 8989 PetscFunctionBegin; 8990 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8991 PetscValidType(mat,1); 8992 if (mat->ops->getvecs) { 8993 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8994 } else { 8995 PetscInt rbs,cbs; 8996 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8997 if (right) { 8998 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8999 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 9000 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 9001 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 9002 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 9003 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 9004 } 9005 if (left) { 9006 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 9007 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 9008 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 9009 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 9010 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 9011 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 9012 } 9013 } 9014 PetscFunctionReturn(0); 9015 } 9016 9017 /*@C 9018 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9019 with default values. 9020 9021 Not Collective 9022 9023 Input Parameters: 9024 . info - the MatFactorInfo data structure 9025 9026 9027 Notes: 9028 The solvers are generally used through the KSP and PC objects, for example 9029 PCLU, PCILU, PCCHOLESKY, PCICC 9030 9031 Level: developer 9032 9033 .seealso: MatFactorInfo 9034 9035 Developer Note: fortran interface is not autogenerated as the f90 9036 interface defintion cannot be generated correctly [due to MatFactorInfo] 9037 9038 @*/ 9039 9040 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9041 { 9042 PetscErrorCode ierr; 9043 9044 PetscFunctionBegin; 9045 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 9046 PetscFunctionReturn(0); 9047 } 9048 9049 /*@ 9050 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9051 9052 Collective on Mat 9053 9054 Input Parameters: 9055 + mat - the factored matrix 9056 - is - the index set defining the Schur indices (0-based) 9057 9058 Notes: 9059 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9060 9061 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9062 9063 Level: developer 9064 9065 Concepts: 9066 9067 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 9068 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 9069 9070 @*/ 9071 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9072 { 9073 PetscErrorCode ierr,(*f)(Mat,IS); 9074 9075 PetscFunctionBegin; 9076 PetscValidType(mat,1); 9077 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9078 PetscValidType(is,2); 9079 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9080 PetscCheckSameComm(mat,1,is,2); 9081 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9082 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 9083 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"); 9084 if (mat->schur) { 9085 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 9086 } 9087 ierr = (*f)(mat,is);CHKERRQ(ierr); 9088 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9089 ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr); 9090 PetscFunctionReturn(0); 9091 } 9092 9093 /*@ 9094 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9095 9096 Logically Collective on Mat 9097 9098 Input Parameters: 9099 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9100 . S - location where to return the Schur complement, can be NULL 9101 - status - the status of the Schur complement matrix, can be NULL 9102 9103 Notes: 9104 You must call MatFactorSetSchurIS() before calling this routine. 9105 9106 The routine provides a copy of the Schur matrix stored within the solver data structures. 9107 The caller must destroy the object when it is no longer needed. 9108 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9109 9110 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) 9111 9112 Developer Notes: 9113 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9114 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9115 9116 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9117 9118 Level: advanced 9119 9120 References: 9121 9122 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 9123 @*/ 9124 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9125 { 9126 PetscErrorCode ierr; 9127 9128 PetscFunctionBegin; 9129 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9130 if (S) PetscValidPointer(S,2); 9131 if (status) PetscValidPointer(status,3); 9132 if (S) { 9133 PetscErrorCode (*f)(Mat,Mat*); 9134 9135 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 9136 if (f) { 9137 ierr = (*f)(F,S);CHKERRQ(ierr); 9138 } else { 9139 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 9140 } 9141 } 9142 if (status) *status = F->schur_status; 9143 PetscFunctionReturn(0); 9144 } 9145 9146 /*@ 9147 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9148 9149 Logically Collective on Mat 9150 9151 Input Parameters: 9152 + F - the factored matrix obtained by calling MatGetFactor() 9153 . *S - location where to return the Schur complement, can be NULL 9154 - status - the status of the Schur complement matrix, can be NULL 9155 9156 Notes: 9157 You must call MatFactorSetSchurIS() before calling this routine. 9158 9159 Schur complement mode is currently implemented for sequential matrices. 9160 The routine returns a the Schur Complement stored within the data strutures of the solver. 9161 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9162 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9163 9164 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9165 9166 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9167 9168 Level: advanced 9169 9170 References: 9171 9172 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9173 @*/ 9174 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9175 { 9176 PetscFunctionBegin; 9177 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9178 if (S) PetscValidPointer(S,2); 9179 if (status) PetscValidPointer(status,3); 9180 if (S) *S = F->schur; 9181 if (status) *status = F->schur_status; 9182 PetscFunctionReturn(0); 9183 } 9184 9185 /*@ 9186 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9187 9188 Logically Collective on Mat 9189 9190 Input Parameters: 9191 + F - the factored matrix obtained by calling MatGetFactor() 9192 . *S - location where the Schur complement is stored 9193 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9194 9195 Notes: 9196 9197 Level: advanced 9198 9199 References: 9200 9201 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9202 @*/ 9203 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9204 { 9205 PetscErrorCode ierr; 9206 9207 PetscFunctionBegin; 9208 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9209 if (S) { 9210 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9211 *S = NULL; 9212 } 9213 F->schur_status = status; 9214 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 9215 PetscFunctionReturn(0); 9216 } 9217 9218 /*@ 9219 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9220 9221 Logically Collective on Mat 9222 9223 Input Parameters: 9224 + F - the factored matrix obtained by calling MatGetFactor() 9225 . rhs - location where the right hand side of the Schur complement system is stored 9226 - sol - location where the solution of the Schur complement system has to be returned 9227 9228 Notes: 9229 The sizes of the vectors should match the size of the Schur complement 9230 9231 Must be called after MatFactorSetSchurIS() 9232 9233 Level: advanced 9234 9235 References: 9236 9237 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 9238 @*/ 9239 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9240 { 9241 PetscErrorCode ierr; 9242 9243 PetscFunctionBegin; 9244 PetscValidType(F,1); 9245 PetscValidType(rhs,2); 9246 PetscValidType(sol,3); 9247 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9248 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9249 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9250 PetscCheckSameComm(F,1,rhs,2); 9251 PetscCheckSameComm(F,1,sol,3); 9252 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9253 switch (F->schur_status) { 9254 case MAT_FACTOR_SCHUR_FACTORED: 9255 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9256 break; 9257 case MAT_FACTOR_SCHUR_INVERTED: 9258 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9259 break; 9260 default: 9261 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9262 break; 9263 } 9264 PetscFunctionReturn(0); 9265 } 9266 9267 /*@ 9268 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9269 9270 Logically Collective on Mat 9271 9272 Input Parameters: 9273 + F - the factored matrix obtained by calling MatGetFactor() 9274 . rhs - location where the right hand side of the Schur complement system is stored 9275 - sol - location where the solution of the Schur complement system has to be returned 9276 9277 Notes: 9278 The sizes of the vectors should match the size of the Schur complement 9279 9280 Must be called after MatFactorSetSchurIS() 9281 9282 Level: advanced 9283 9284 References: 9285 9286 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9287 @*/ 9288 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9289 { 9290 PetscErrorCode ierr; 9291 9292 PetscFunctionBegin; 9293 PetscValidType(F,1); 9294 PetscValidType(rhs,2); 9295 PetscValidType(sol,3); 9296 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9297 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9298 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9299 PetscCheckSameComm(F,1,rhs,2); 9300 PetscCheckSameComm(F,1,sol,3); 9301 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9302 switch (F->schur_status) { 9303 case MAT_FACTOR_SCHUR_FACTORED: 9304 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9305 break; 9306 case MAT_FACTOR_SCHUR_INVERTED: 9307 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9308 break; 9309 default: 9310 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9311 break; 9312 } 9313 PetscFunctionReturn(0); 9314 } 9315 9316 /*@ 9317 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9318 9319 Logically Collective on Mat 9320 9321 Input Parameters: 9322 + F - the factored matrix obtained by calling MatGetFactor() 9323 9324 Notes: 9325 Must be called after MatFactorSetSchurIS(). 9326 9327 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9328 9329 Level: advanced 9330 9331 References: 9332 9333 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9334 @*/ 9335 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9336 { 9337 PetscErrorCode ierr; 9338 9339 PetscFunctionBegin; 9340 PetscValidType(F,1); 9341 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9342 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9343 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9344 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9345 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9346 PetscFunctionReturn(0); 9347 } 9348 9349 /*@ 9350 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9351 9352 Logically Collective on Mat 9353 9354 Input Parameters: 9355 + F - the factored matrix obtained by calling MatGetFactor() 9356 9357 Notes: 9358 Must be called after MatFactorSetSchurIS(). 9359 9360 Level: advanced 9361 9362 References: 9363 9364 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9365 @*/ 9366 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9367 { 9368 PetscErrorCode ierr; 9369 9370 PetscFunctionBegin; 9371 PetscValidType(F,1); 9372 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9373 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9374 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9375 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9376 PetscFunctionReturn(0); 9377 } 9378 9379 /*@ 9380 MatPtAP - Creates the matrix product C = P^T * A * P 9381 9382 Neighbor-wise Collective on Mat 9383 9384 Input Parameters: 9385 + A - the matrix 9386 . P - the projection matrix 9387 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9388 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9389 if the result is a dense matrix this is irrelevent 9390 9391 Output Parameters: 9392 . C - the product matrix 9393 9394 Notes: 9395 C will be created and must be destroyed by the user with MatDestroy(). 9396 9397 This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes 9398 which inherit from AIJ. 9399 9400 Level: intermediate 9401 9402 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9403 @*/ 9404 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9405 { 9406 PetscErrorCode ierr; 9407 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9408 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9409 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9410 PetscBool sametype; 9411 9412 PetscFunctionBegin; 9413 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9414 PetscValidType(A,1); 9415 MatCheckPreallocated(A,1); 9416 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9417 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9418 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9419 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9420 PetscValidType(P,2); 9421 MatCheckPreallocated(P,2); 9422 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9423 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9424 9425 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); 9426 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); 9427 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9428 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9429 9430 if (scall == MAT_REUSE_MATRIX) { 9431 PetscValidPointer(*C,5); 9432 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9433 9434 if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX"); 9435 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9436 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9437 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9438 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9439 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9440 PetscFunctionReturn(0); 9441 } 9442 9443 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9444 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9445 9446 fA = A->ops->ptap; 9447 fP = P->ops->ptap; 9448 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9449 if (fP == fA && sametype) { 9450 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 9451 ptap = fA; 9452 } else { 9453 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9454 char ptapname[256]; 9455 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9456 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9457 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9458 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9459 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9460 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9461 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); 9462 } 9463 9464 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9465 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9466 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9467 if (A->symmetric_set && A->symmetric) { 9468 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9469 } 9470 PetscFunctionReturn(0); 9471 } 9472 9473 /*@ 9474 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9475 9476 Neighbor-wise Collective on Mat 9477 9478 Input Parameters: 9479 + A - the matrix 9480 - P - the projection matrix 9481 9482 Output Parameters: 9483 . C - the product matrix 9484 9485 Notes: 9486 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9487 the user using MatDeatroy(). 9488 9489 This routine is currently only implemented for pairs of AIJ matrices and classes 9490 which inherit from AIJ. C will be of type MATAIJ. 9491 9492 Level: intermediate 9493 9494 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9495 @*/ 9496 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9497 { 9498 PetscErrorCode ierr; 9499 9500 PetscFunctionBegin; 9501 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9502 PetscValidType(A,1); 9503 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9504 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9505 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9506 PetscValidType(P,2); 9507 MatCheckPreallocated(P,2); 9508 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9509 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9510 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9511 PetscValidType(C,3); 9512 MatCheckPreallocated(C,3); 9513 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9514 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); 9515 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); 9516 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); 9517 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); 9518 MatCheckPreallocated(A,1); 9519 9520 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9521 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9522 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9523 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9524 PetscFunctionReturn(0); 9525 } 9526 9527 /*@ 9528 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9529 9530 Neighbor-wise Collective on Mat 9531 9532 Input Parameters: 9533 + A - the matrix 9534 - P - the projection matrix 9535 9536 Output Parameters: 9537 . C - the (i,j) structure of the product matrix 9538 9539 Notes: 9540 C will be created and must be destroyed by the user with MatDestroy(). 9541 9542 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9543 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9544 this (i,j) structure by calling MatPtAPNumeric(). 9545 9546 Level: intermediate 9547 9548 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9549 @*/ 9550 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9551 { 9552 PetscErrorCode ierr; 9553 9554 PetscFunctionBegin; 9555 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9556 PetscValidType(A,1); 9557 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9558 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9559 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9560 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9561 PetscValidType(P,2); 9562 MatCheckPreallocated(P,2); 9563 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9564 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9565 PetscValidPointer(C,3); 9566 9567 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); 9568 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); 9569 MatCheckPreallocated(A,1); 9570 9571 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9572 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9573 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9574 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9575 9576 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9577 PetscFunctionReturn(0); 9578 } 9579 9580 /*@ 9581 MatRARt - Creates the matrix product C = R * A * R^T 9582 9583 Neighbor-wise Collective on Mat 9584 9585 Input Parameters: 9586 + A - the matrix 9587 . R - the projection matrix 9588 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9589 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9590 if the result is a dense matrix this is irrelevent 9591 9592 Output Parameters: 9593 . C - the product matrix 9594 9595 Notes: 9596 C will be created and must be destroyed by the user with MatDestroy(). 9597 9598 This routine is currently only implemented for pairs of AIJ matrices and classes 9599 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9600 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9601 We recommend using MatPtAP(). 9602 9603 Level: intermediate 9604 9605 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9606 @*/ 9607 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9608 { 9609 PetscErrorCode ierr; 9610 9611 PetscFunctionBegin; 9612 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9613 PetscValidType(A,1); 9614 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9615 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9616 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9617 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9618 PetscValidType(R,2); 9619 MatCheckPreallocated(R,2); 9620 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9621 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9622 PetscValidPointer(C,3); 9623 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); 9624 9625 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9626 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9627 MatCheckPreallocated(A,1); 9628 9629 if (!A->ops->rart) { 9630 Mat Rt; 9631 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9632 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9633 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9634 PetscFunctionReturn(0); 9635 } 9636 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9637 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9638 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9639 PetscFunctionReturn(0); 9640 } 9641 9642 /*@ 9643 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9644 9645 Neighbor-wise Collective on Mat 9646 9647 Input Parameters: 9648 + A - the matrix 9649 - R - the projection matrix 9650 9651 Output Parameters: 9652 . C - the product matrix 9653 9654 Notes: 9655 C must have been created by calling MatRARtSymbolic and must be destroyed by 9656 the user using MatDestroy(). 9657 9658 This routine is currently only implemented for pairs of AIJ matrices and classes 9659 which inherit from AIJ. C will be of type MATAIJ. 9660 9661 Level: intermediate 9662 9663 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9664 @*/ 9665 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9666 { 9667 PetscErrorCode ierr; 9668 9669 PetscFunctionBegin; 9670 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9671 PetscValidType(A,1); 9672 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9673 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9674 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9675 PetscValidType(R,2); 9676 MatCheckPreallocated(R,2); 9677 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9678 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9679 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9680 PetscValidType(C,3); 9681 MatCheckPreallocated(C,3); 9682 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9683 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); 9684 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); 9685 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); 9686 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); 9687 MatCheckPreallocated(A,1); 9688 9689 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9690 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9691 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9692 PetscFunctionReturn(0); 9693 } 9694 9695 /*@ 9696 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9697 9698 Neighbor-wise Collective on Mat 9699 9700 Input Parameters: 9701 + A - the matrix 9702 - R - the projection matrix 9703 9704 Output Parameters: 9705 . C - the (i,j) structure of the product matrix 9706 9707 Notes: 9708 C will be created and must be destroyed by the user with MatDestroy(). 9709 9710 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9711 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9712 this (i,j) structure by calling MatRARtNumeric(). 9713 9714 Level: intermediate 9715 9716 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9717 @*/ 9718 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9719 { 9720 PetscErrorCode ierr; 9721 9722 PetscFunctionBegin; 9723 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9724 PetscValidType(A,1); 9725 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9726 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9727 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9728 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9729 PetscValidType(R,2); 9730 MatCheckPreallocated(R,2); 9731 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9732 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9733 PetscValidPointer(C,3); 9734 9735 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); 9736 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); 9737 MatCheckPreallocated(A,1); 9738 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9739 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9740 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9741 9742 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9743 PetscFunctionReturn(0); 9744 } 9745 9746 /*@ 9747 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9748 9749 Neighbor-wise Collective on Mat 9750 9751 Input Parameters: 9752 + A - the left matrix 9753 . B - the right matrix 9754 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9755 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9756 if the result is a dense matrix this is irrelevent 9757 9758 Output Parameters: 9759 . C - the product matrix 9760 9761 Notes: 9762 Unless scall is MAT_REUSE_MATRIX C will be created. 9763 9764 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 9765 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9766 9767 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9768 actually needed. 9769 9770 If you have many matrices with the same non-zero structure to multiply, you 9771 should either 9772 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9773 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9774 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 9775 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9776 9777 Level: intermediate 9778 9779 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9780 @*/ 9781 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9782 { 9783 PetscErrorCode ierr; 9784 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9785 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9786 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9787 9788 PetscFunctionBegin; 9789 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9790 PetscValidType(A,1); 9791 MatCheckPreallocated(A,1); 9792 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9793 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9794 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9795 PetscValidType(B,2); 9796 MatCheckPreallocated(B,2); 9797 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9798 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9799 PetscValidPointer(C,3); 9800 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9801 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); 9802 if (scall == MAT_REUSE_MATRIX) { 9803 PetscValidPointer(*C,5); 9804 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9805 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9806 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9807 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9808 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9809 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9810 PetscFunctionReturn(0); 9811 } 9812 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9813 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9814 9815 fA = A->ops->matmult; 9816 fB = B->ops->matmult; 9817 if (fB == fA) { 9818 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9819 mult = fB; 9820 } else { 9821 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9822 char multname[256]; 9823 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9824 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9825 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9826 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9827 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9828 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9829 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); 9830 } 9831 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9832 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9833 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9834 PetscFunctionReturn(0); 9835 } 9836 9837 /*@ 9838 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9839 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9840 9841 Neighbor-wise Collective on Mat 9842 9843 Input Parameters: 9844 + A - the left matrix 9845 . B - the right matrix 9846 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9847 if C is a dense matrix this is irrelevent 9848 9849 Output Parameters: 9850 . C - the product matrix 9851 9852 Notes: 9853 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9854 actually needed. 9855 9856 This routine is currently implemented for 9857 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9858 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9859 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9860 9861 Level: intermediate 9862 9863 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 9864 We should incorporate them into PETSc. 9865 9866 .seealso: MatMatMult(), MatMatMultNumeric() 9867 @*/ 9868 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9869 { 9870 PetscErrorCode ierr; 9871 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9872 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9873 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9874 9875 PetscFunctionBegin; 9876 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9877 PetscValidType(A,1); 9878 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9879 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9880 9881 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9882 PetscValidType(B,2); 9883 MatCheckPreallocated(B,2); 9884 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9885 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9886 PetscValidPointer(C,3); 9887 9888 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); 9889 if (fill == PETSC_DEFAULT) fill = 2.0; 9890 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9891 MatCheckPreallocated(A,1); 9892 9893 Asymbolic = A->ops->matmultsymbolic; 9894 Bsymbolic = B->ops->matmultsymbolic; 9895 if (Asymbolic == Bsymbolic) { 9896 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9897 symbolic = Bsymbolic; 9898 } else { /* dispatch based on the type of A and B */ 9899 char symbolicname[256]; 9900 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9901 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9902 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9903 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9904 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9905 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9906 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); 9907 } 9908 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9909 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9910 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9911 PetscFunctionReturn(0); 9912 } 9913 9914 /*@ 9915 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9916 Call this routine after first calling MatMatMultSymbolic(). 9917 9918 Neighbor-wise Collective on Mat 9919 9920 Input Parameters: 9921 + A - the left matrix 9922 - B - the right matrix 9923 9924 Output Parameters: 9925 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9926 9927 Notes: 9928 C must have been created with MatMatMultSymbolic(). 9929 9930 This routine is currently implemented for 9931 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9932 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9933 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9934 9935 Level: intermediate 9936 9937 .seealso: MatMatMult(), MatMatMultSymbolic() 9938 @*/ 9939 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9940 { 9941 PetscErrorCode ierr; 9942 9943 PetscFunctionBegin; 9944 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9945 PetscFunctionReturn(0); 9946 } 9947 9948 /*@ 9949 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9950 9951 Neighbor-wise Collective on Mat 9952 9953 Input Parameters: 9954 + A - the left matrix 9955 . B - the right matrix 9956 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9957 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9958 9959 Output Parameters: 9960 . C - the product matrix 9961 9962 Notes: 9963 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9964 9965 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9966 9967 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9968 actually needed. 9969 9970 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9971 and for pairs of MPIDense matrices. 9972 9973 Options Database Keys: 9974 + -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9975 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9976 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9977 9978 Level: intermediate 9979 9980 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9981 @*/ 9982 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9983 { 9984 PetscErrorCode ierr; 9985 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9986 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9987 9988 PetscFunctionBegin; 9989 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9990 PetscValidType(A,1); 9991 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9992 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9993 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9994 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9995 PetscValidType(B,2); 9996 MatCheckPreallocated(B,2); 9997 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9998 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9999 PetscValidPointer(C,3); 10000 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); 10001 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10002 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 10003 MatCheckPreallocated(A,1); 10004 10005 fA = A->ops->mattransposemult; 10006 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 10007 fB = B->ops->mattransposemult; 10008 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 10009 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); 10010 10011 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 10012 if (scall == MAT_INITIAL_MATRIX) { 10013 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 10014 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 10015 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 10016 } 10017 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 10018 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 10019 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 10020 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 10021 PetscFunctionReturn(0); 10022 } 10023 10024 /*@ 10025 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 10026 10027 Neighbor-wise Collective on Mat 10028 10029 Input Parameters: 10030 + A - the left matrix 10031 . B - the right matrix 10032 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10033 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 10034 10035 Output Parameters: 10036 . C - the product matrix 10037 10038 Notes: 10039 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 10040 10041 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 10042 10043 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10044 actually needed. 10045 10046 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 10047 which inherit from SeqAIJ. C will be of same type as the input matrices. 10048 10049 Level: intermediate 10050 10051 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 10052 @*/ 10053 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10054 { 10055 PetscErrorCode ierr; 10056 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 10057 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 10058 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 10059 10060 PetscFunctionBegin; 10061 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10062 PetscValidType(A,1); 10063 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10064 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10065 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10066 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10067 PetscValidType(B,2); 10068 MatCheckPreallocated(B,2); 10069 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10070 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10071 PetscValidPointer(C,3); 10072 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); 10073 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10074 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 10075 MatCheckPreallocated(A,1); 10076 10077 fA = A->ops->transposematmult; 10078 fB = B->ops->transposematmult; 10079 if (fB==fA) { 10080 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 10081 transposematmult = fA; 10082 } else { 10083 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 10084 char multname[256]; 10085 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 10086 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10087 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10088 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10089 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 10090 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 10091 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); 10092 } 10093 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 10094 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 10095 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 10096 PetscFunctionReturn(0); 10097 } 10098 10099 /*@ 10100 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 10101 10102 Neighbor-wise Collective on Mat 10103 10104 Input Parameters: 10105 + A - the left matrix 10106 . B - the middle matrix 10107 . C - the right matrix 10108 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10109 - 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 10110 if the result is a dense matrix this is irrelevent 10111 10112 Output Parameters: 10113 . D - the product matrix 10114 10115 Notes: 10116 Unless scall is MAT_REUSE_MATRIX D will be created. 10117 10118 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10119 10120 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10121 actually needed. 10122 10123 If you have many matrices with the same non-zero structure to multiply, you 10124 should use MAT_REUSE_MATRIX in all calls but the first or 10125 10126 Level: intermediate 10127 10128 .seealso: MatMatMult, MatPtAP() 10129 @*/ 10130 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10131 { 10132 PetscErrorCode ierr; 10133 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10134 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10135 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10136 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 10137 10138 PetscFunctionBegin; 10139 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10140 PetscValidType(A,1); 10141 MatCheckPreallocated(A,1); 10142 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10143 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10144 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10145 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10146 PetscValidType(B,2); 10147 MatCheckPreallocated(B,2); 10148 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10149 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10150 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10151 PetscValidPointer(C,3); 10152 MatCheckPreallocated(C,3); 10153 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10154 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10155 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); 10156 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); 10157 if (scall == MAT_REUSE_MATRIX) { 10158 PetscValidPointer(*D,6); 10159 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 10160 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10161 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10162 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10163 PetscFunctionReturn(0); 10164 } 10165 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10166 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 10167 10168 fA = A->ops->matmatmult; 10169 fB = B->ops->matmatmult; 10170 fC = C->ops->matmatmult; 10171 if (fA == fB && fA == fC) { 10172 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 10173 mult = fA; 10174 } else { 10175 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 10176 char multname[256]; 10177 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 10178 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10179 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10180 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10181 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10182 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 10183 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 10184 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 10185 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); 10186 } 10187 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10188 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10189 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10190 PetscFunctionReturn(0); 10191 } 10192 10193 /*@ 10194 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10195 10196 Collective on Mat 10197 10198 Input Parameters: 10199 + mat - the matrix 10200 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10201 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10202 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10203 10204 Output Parameter: 10205 . matredundant - redundant matrix 10206 10207 Notes: 10208 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10209 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10210 10211 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 10212 calling it. 10213 10214 Level: advanced 10215 10216 Concepts: subcommunicator 10217 Concepts: duplicate matrix 10218 10219 .seealso: MatDestroy() 10220 @*/ 10221 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10222 { 10223 PetscErrorCode ierr; 10224 MPI_Comm comm; 10225 PetscMPIInt size; 10226 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10227 Mat_Redundant *redund=NULL; 10228 PetscSubcomm psubcomm=NULL; 10229 MPI_Comm subcomm_in=subcomm; 10230 Mat *matseq; 10231 IS isrow,iscol; 10232 PetscBool newsubcomm=PETSC_FALSE; 10233 10234 PetscFunctionBegin; 10235 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10236 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10237 PetscValidPointer(*matredundant,5); 10238 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10239 } 10240 10241 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10242 if (size == 1 || nsubcomm == 1) { 10243 if (reuse == MAT_INITIAL_MATRIX) { 10244 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10245 } else { 10246 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"); 10247 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10248 } 10249 PetscFunctionReturn(0); 10250 } 10251 10252 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10253 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10254 MatCheckPreallocated(mat,1); 10255 10256 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10257 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10258 /* create psubcomm, then get subcomm */ 10259 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10260 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10261 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10262 10263 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10264 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10265 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10266 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10267 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10268 newsubcomm = PETSC_TRUE; 10269 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10270 } 10271 10272 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10273 if (reuse == MAT_INITIAL_MATRIX) { 10274 mloc_sub = PETSC_DECIDE; 10275 nloc_sub = PETSC_DECIDE; 10276 if (bs < 1) { 10277 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10278 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10279 } else { 10280 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10281 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10282 } 10283 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10284 rstart = rend - mloc_sub; 10285 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10286 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10287 } else { /* reuse == MAT_REUSE_MATRIX */ 10288 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"); 10289 /* retrieve subcomm */ 10290 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10291 redund = (*matredundant)->redundant; 10292 isrow = redund->isrow; 10293 iscol = redund->iscol; 10294 matseq = redund->matseq; 10295 } 10296 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10297 10298 /* get matredundant over subcomm */ 10299 if (reuse == MAT_INITIAL_MATRIX) { 10300 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10301 10302 /* create a supporting struct and attach it to C for reuse */ 10303 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10304 (*matredundant)->redundant = redund; 10305 redund->isrow = isrow; 10306 redund->iscol = iscol; 10307 redund->matseq = matseq; 10308 if (newsubcomm) { 10309 redund->subcomm = subcomm; 10310 } else { 10311 redund->subcomm = MPI_COMM_NULL; 10312 } 10313 } else { 10314 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10315 } 10316 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10317 PetscFunctionReturn(0); 10318 } 10319 10320 /*@C 10321 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10322 a given 'mat' object. Each submatrix can span multiple procs. 10323 10324 Collective on Mat 10325 10326 Input Parameters: 10327 + mat - the matrix 10328 . subcomm - the subcommunicator obtained by com_split(comm) 10329 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10330 10331 Output Parameter: 10332 . subMat - 'parallel submatrices each spans a given subcomm 10333 10334 Notes: 10335 The submatrix partition across processors is dictated by 'subComm' a 10336 communicator obtained by com_split(comm). The comm_split 10337 is not restriced to be grouped with consecutive original ranks. 10338 10339 Due the comm_split() usage, the parallel layout of the submatrices 10340 map directly to the layout of the original matrix [wrt the local 10341 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10342 into the 'DiagonalMat' of the subMat, hence it is used directly from 10343 the subMat. However the offDiagMat looses some columns - and this is 10344 reconstructed with MatSetValues() 10345 10346 Level: advanced 10347 10348 Concepts: subcommunicator 10349 Concepts: submatrices 10350 10351 .seealso: MatCreateSubMatrices() 10352 @*/ 10353 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10354 { 10355 PetscErrorCode ierr; 10356 PetscMPIInt commsize,subCommSize; 10357 10358 PetscFunctionBegin; 10359 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10360 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10361 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10362 10363 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"); 10364 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10365 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10366 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10367 PetscFunctionReturn(0); 10368 } 10369 10370 /*@ 10371 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10372 10373 Not Collective 10374 10375 Input Arguments: 10376 mat - matrix to extract local submatrix from 10377 isrow - local row indices for submatrix 10378 iscol - local column indices for submatrix 10379 10380 Output Arguments: 10381 submat - the submatrix 10382 10383 Level: intermediate 10384 10385 Notes: 10386 The submat should be returned with MatRestoreLocalSubMatrix(). 10387 10388 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10389 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10390 10391 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10392 MatSetValuesBlockedLocal() will also be implemented. 10393 10394 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10395 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10396 10397 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10398 @*/ 10399 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10400 { 10401 PetscErrorCode ierr; 10402 10403 PetscFunctionBegin; 10404 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10405 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10406 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10407 PetscCheckSameComm(isrow,2,iscol,3); 10408 PetscValidPointer(submat,4); 10409 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10410 10411 if (mat->ops->getlocalsubmatrix) { 10412 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10413 } else { 10414 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10415 } 10416 PetscFunctionReturn(0); 10417 } 10418 10419 /*@ 10420 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10421 10422 Not Collective 10423 10424 Input Arguments: 10425 mat - matrix to extract local submatrix from 10426 isrow - local row indices for submatrix 10427 iscol - local column indices for submatrix 10428 submat - the submatrix 10429 10430 Level: intermediate 10431 10432 .seealso: MatGetLocalSubMatrix() 10433 @*/ 10434 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10435 { 10436 PetscErrorCode ierr; 10437 10438 PetscFunctionBegin; 10439 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10440 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10441 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10442 PetscCheckSameComm(isrow,2,iscol,3); 10443 PetscValidPointer(submat,4); 10444 if (*submat) { 10445 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10446 } 10447 10448 if (mat->ops->restorelocalsubmatrix) { 10449 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10450 } else { 10451 ierr = MatDestroy(submat);CHKERRQ(ierr); 10452 } 10453 *submat = NULL; 10454 PetscFunctionReturn(0); 10455 } 10456 10457 /* --------------------------------------------------------*/ 10458 /*@ 10459 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10460 10461 Collective on Mat 10462 10463 Input Parameter: 10464 . mat - the matrix 10465 10466 Output Parameter: 10467 . is - if any rows have zero diagonals this contains the list of them 10468 10469 Level: developer 10470 10471 Concepts: matrix-vector product 10472 10473 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10474 @*/ 10475 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10476 { 10477 PetscErrorCode ierr; 10478 10479 PetscFunctionBegin; 10480 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10481 PetscValidType(mat,1); 10482 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10483 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10484 10485 if (!mat->ops->findzerodiagonals) { 10486 Vec diag; 10487 const PetscScalar *a; 10488 PetscInt *rows; 10489 PetscInt rStart, rEnd, r, nrow = 0; 10490 10491 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10492 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10493 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10494 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10495 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10496 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10497 nrow = 0; 10498 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10499 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10500 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10501 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10502 } else { 10503 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10504 } 10505 PetscFunctionReturn(0); 10506 } 10507 10508 /*@ 10509 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10510 10511 Collective on Mat 10512 10513 Input Parameter: 10514 . mat - the matrix 10515 10516 Output Parameter: 10517 . is - contains the list of rows with off block diagonal entries 10518 10519 Level: developer 10520 10521 Concepts: matrix-vector product 10522 10523 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10524 @*/ 10525 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10526 { 10527 PetscErrorCode ierr; 10528 10529 PetscFunctionBegin; 10530 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10531 PetscValidType(mat,1); 10532 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10533 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10534 10535 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10536 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10537 PetscFunctionReturn(0); 10538 } 10539 10540 /*@C 10541 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10542 10543 Collective on Mat 10544 10545 Input Parameters: 10546 . mat - the matrix 10547 10548 Output Parameters: 10549 . values - the block inverses in column major order (FORTRAN-like) 10550 10551 Note: 10552 This routine is not available from Fortran. 10553 10554 Level: advanced 10555 10556 .seealso: MatInvertBockDiagonalMat 10557 @*/ 10558 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10559 { 10560 PetscErrorCode ierr; 10561 10562 PetscFunctionBegin; 10563 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10564 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10565 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10566 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10567 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10568 PetscFunctionReturn(0); 10569 } 10570 10571 /*@C 10572 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10573 10574 Collective on Mat 10575 10576 Input Parameters: 10577 + mat - the matrix 10578 . nblocks - the number of blocks 10579 - bsizes - the size of each block 10580 10581 Output Parameters: 10582 . values - the block inverses in column major order (FORTRAN-like) 10583 10584 Note: 10585 This routine is not available from Fortran. 10586 10587 Level: advanced 10588 10589 .seealso: MatInvertBockDiagonal() 10590 @*/ 10591 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10592 { 10593 PetscErrorCode ierr; 10594 10595 PetscFunctionBegin; 10596 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10597 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10598 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10599 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10600 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10601 PetscFunctionReturn(0); 10602 } 10603 10604 /*@ 10605 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10606 10607 Collective on Mat 10608 10609 Input Parameters: 10610 . A - the matrix 10611 10612 Output Parameters: 10613 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10614 10615 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10616 10617 Level: advanced 10618 10619 .seealso: MatInvertBockDiagonal() 10620 @*/ 10621 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10622 { 10623 PetscErrorCode ierr; 10624 const PetscScalar *vals; 10625 PetscInt *dnnz; 10626 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10627 10628 PetscFunctionBegin; 10629 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10630 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10631 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10632 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10633 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10634 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10635 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10636 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10637 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10638 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10639 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10640 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10641 for (i = rstart/bs; i < rend/bs; i++) { 10642 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10643 } 10644 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10645 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10646 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10647 PetscFunctionReturn(0); 10648 } 10649 10650 /*@C 10651 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10652 via MatTransposeColoringCreate(). 10653 10654 Collective on MatTransposeColoring 10655 10656 Input Parameter: 10657 . c - coloring context 10658 10659 Level: intermediate 10660 10661 .seealso: MatTransposeColoringCreate() 10662 @*/ 10663 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10664 { 10665 PetscErrorCode ierr; 10666 MatTransposeColoring matcolor=*c; 10667 10668 PetscFunctionBegin; 10669 if (!matcolor) PetscFunctionReturn(0); 10670 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10671 10672 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10673 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10674 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10675 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10676 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10677 if (matcolor->brows>0) { 10678 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10679 } 10680 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10681 PetscFunctionReturn(0); 10682 } 10683 10684 /*@C 10685 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10686 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10687 MatTransposeColoring to sparse B. 10688 10689 Collective on MatTransposeColoring 10690 10691 Input Parameters: 10692 + B - sparse matrix B 10693 . Btdense - symbolic dense matrix B^T 10694 - coloring - coloring context created with MatTransposeColoringCreate() 10695 10696 Output Parameter: 10697 . Btdense - dense matrix B^T 10698 10699 Level: advanced 10700 10701 Notes: 10702 These are used internally for some implementations of MatRARt() 10703 10704 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10705 10706 .keywords: coloring 10707 @*/ 10708 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10709 { 10710 PetscErrorCode ierr; 10711 10712 PetscFunctionBegin; 10713 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10714 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10715 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10716 10717 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10718 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10719 PetscFunctionReturn(0); 10720 } 10721 10722 /*@C 10723 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10724 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10725 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10726 Csp from Cden. 10727 10728 Collective on MatTransposeColoring 10729 10730 Input Parameters: 10731 + coloring - coloring context created with MatTransposeColoringCreate() 10732 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10733 10734 Output Parameter: 10735 . Csp - sparse matrix 10736 10737 Level: advanced 10738 10739 Notes: 10740 These are used internally for some implementations of MatRARt() 10741 10742 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10743 10744 .keywords: coloring 10745 @*/ 10746 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10747 { 10748 PetscErrorCode ierr; 10749 10750 PetscFunctionBegin; 10751 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10752 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10753 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10754 10755 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10756 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10757 PetscFunctionReturn(0); 10758 } 10759 10760 /*@C 10761 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10762 10763 Collective on Mat 10764 10765 Input Parameters: 10766 + mat - the matrix product C 10767 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10768 10769 Output Parameter: 10770 . color - the new coloring context 10771 10772 Level: intermediate 10773 10774 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10775 MatTransColoringApplyDenToSp() 10776 @*/ 10777 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10778 { 10779 MatTransposeColoring c; 10780 MPI_Comm comm; 10781 PetscErrorCode ierr; 10782 10783 PetscFunctionBegin; 10784 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10785 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10786 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10787 10788 c->ctype = iscoloring->ctype; 10789 if (mat->ops->transposecoloringcreate) { 10790 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10791 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10792 10793 *color = c; 10794 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10795 PetscFunctionReturn(0); 10796 } 10797 10798 /*@ 10799 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10800 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10801 same, otherwise it will be larger 10802 10803 Not Collective 10804 10805 Input Parameter: 10806 . A - the matrix 10807 10808 Output Parameter: 10809 . state - the current state 10810 10811 Notes: 10812 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10813 different matrices 10814 10815 Level: intermediate 10816 10817 @*/ 10818 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10819 { 10820 PetscFunctionBegin; 10821 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10822 *state = mat->nonzerostate; 10823 PetscFunctionReturn(0); 10824 } 10825 10826 /*@ 10827 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10828 matrices from each processor 10829 10830 Collective on MPI_Comm 10831 10832 Input Parameters: 10833 + comm - the communicators the parallel matrix will live on 10834 . seqmat - the input sequential matrices 10835 . n - number of local columns (or PETSC_DECIDE) 10836 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10837 10838 Output Parameter: 10839 . mpimat - the parallel matrix generated 10840 10841 Level: advanced 10842 10843 Notes: 10844 The number of columns of the matrix in EACH processor MUST be the same. 10845 10846 @*/ 10847 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10848 { 10849 PetscErrorCode ierr; 10850 10851 PetscFunctionBegin; 10852 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10853 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"); 10854 10855 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10856 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10857 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10858 PetscFunctionReturn(0); 10859 } 10860 10861 /*@ 10862 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10863 ranks' ownership ranges. 10864 10865 Collective on A 10866 10867 Input Parameters: 10868 + A - the matrix to create subdomains from 10869 - N - requested number of subdomains 10870 10871 10872 Output Parameters: 10873 + n - number of subdomains resulting on this rank 10874 - iss - IS list with indices of subdomains on this rank 10875 10876 Level: advanced 10877 10878 Notes: 10879 number of subdomains must be smaller than the communicator size 10880 @*/ 10881 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10882 { 10883 MPI_Comm comm,subcomm; 10884 PetscMPIInt size,rank,color; 10885 PetscInt rstart,rend,k; 10886 PetscErrorCode ierr; 10887 10888 PetscFunctionBegin; 10889 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10890 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10891 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10892 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); 10893 *n = 1; 10894 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10895 color = rank/k; 10896 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10897 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10898 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10899 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10900 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10901 PetscFunctionReturn(0); 10902 } 10903 10904 /*@ 10905 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10906 10907 If the interpolation and restriction operators are the same, uses MatPtAP. 10908 If they are not the same, use MatMatMatMult. 10909 10910 Once the coarse grid problem is constructed, correct for interpolation operators 10911 that are not of full rank, which can legitimately happen in the case of non-nested 10912 geometric multigrid. 10913 10914 Input Parameters: 10915 + restrct - restriction operator 10916 . dA - fine grid matrix 10917 . interpolate - interpolation operator 10918 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10919 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10920 10921 Output Parameters: 10922 . A - the Galerkin coarse matrix 10923 10924 Options Database Key: 10925 . -pc_mg_galerkin <both,pmat,mat,none> 10926 10927 Level: developer 10928 10929 .keywords: MG, multigrid, Galerkin 10930 10931 .seealso: MatPtAP(), MatMatMatMult() 10932 @*/ 10933 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10934 { 10935 PetscErrorCode ierr; 10936 IS zerorows; 10937 Vec diag; 10938 10939 PetscFunctionBegin; 10940 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10941 /* Construct the coarse grid matrix */ 10942 if (interpolate == restrct) { 10943 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10944 } else { 10945 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10946 } 10947 10948 /* If the interpolation matrix is not of full rank, A will have zero rows. 10949 This can legitimately happen in the case of non-nested geometric multigrid. 10950 In that event, we set the rows of the matrix to the rows of the identity, 10951 ignoring the equations (as the RHS will also be zero). */ 10952 10953 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10954 10955 if (zerorows != NULL) { /* if there are any zero rows */ 10956 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10957 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10958 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10959 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10960 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10961 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10962 } 10963 PetscFunctionReturn(0); 10964 } 10965 10966 /*@C 10967 MatSetOperation - Allows user to set a matrix operation for any matrix type 10968 10969 Logically Collective on Mat 10970 10971 Input Parameters: 10972 + mat - the matrix 10973 . op - the name of the operation 10974 - f - the function that provides the operation 10975 10976 Level: developer 10977 10978 Usage: 10979 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10980 $ ierr = MatCreateXXX(comm,...&A); 10981 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10982 10983 Notes: 10984 See the file include/petscmat.h for a complete list of matrix 10985 operations, which all have the form MATOP_<OPERATION>, where 10986 <OPERATION> is the name (in all capital letters) of the 10987 user interface routine (e.g., MatMult() -> MATOP_MULT). 10988 10989 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10990 sequence as the usual matrix interface routines, since they 10991 are intended to be accessed via the usual matrix interface 10992 routines, e.g., 10993 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10994 10995 In particular each function MUST return an error code of 0 on success and 10996 nonzero on failure. 10997 10998 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10999 11000 .keywords: matrix, set, operation 11001 11002 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 11003 @*/ 11004 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 11005 { 11006 PetscFunctionBegin; 11007 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11008 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 11009 mat->ops->viewnative = mat->ops->view; 11010 } 11011 (((void(**)(void))mat->ops)[op]) = f; 11012 PetscFunctionReturn(0); 11013 } 11014 11015 /*@C 11016 MatGetOperation - Gets a matrix operation for any matrix type. 11017 11018 Not Collective 11019 11020 Input Parameters: 11021 + mat - the matrix 11022 - op - the name of the operation 11023 11024 Output Parameter: 11025 . f - the function that provides the operation 11026 11027 Level: developer 11028 11029 Usage: 11030 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 11031 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 11032 11033 Notes: 11034 See the file include/petscmat.h for a complete list of matrix 11035 operations, which all have the form MATOP_<OPERATION>, where 11036 <OPERATION> is the name (in all capital letters) of the 11037 user interface routine (e.g., MatMult() -> MATOP_MULT). 11038 11039 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 11040 11041 .keywords: matrix, get, operation 11042 11043 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 11044 @*/ 11045 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 11046 { 11047 PetscFunctionBegin; 11048 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11049 *f = (((void (**)(void))mat->ops)[op]); 11050 PetscFunctionReturn(0); 11051 } 11052 11053 /*@ 11054 MatHasOperation - Determines whether the given matrix supports the particular 11055 operation. 11056 11057 Not Collective 11058 11059 Input Parameters: 11060 + mat - the matrix 11061 - op - the operation, for example, MATOP_GET_DIAGONAL 11062 11063 Output Parameter: 11064 . has - either PETSC_TRUE or PETSC_FALSE 11065 11066 Level: advanced 11067 11068 Notes: 11069 See the file include/petscmat.h for a complete list of matrix 11070 operations, which all have the form MATOP_<OPERATION>, where 11071 <OPERATION> is the name (in all capital letters) of the 11072 user-level routine. E.g., MatNorm() -> MATOP_NORM. 11073 11074 .keywords: matrix, has, operation 11075 11076 .seealso: MatCreateShell() 11077 @*/ 11078 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 11079 { 11080 PetscErrorCode ierr; 11081 11082 PetscFunctionBegin; 11083 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11084 PetscValidType(mat,1); 11085 PetscValidPointer(has,3); 11086 if (mat->ops->hasoperation) { 11087 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 11088 } else { 11089 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 11090 else { 11091 *has = PETSC_FALSE; 11092 if (op == MATOP_CREATE_SUBMATRIX) { 11093 PetscMPIInt size; 11094 11095 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 11096 if (size == 1) { 11097 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 11098 } 11099 } 11100 } 11101 } 11102 PetscFunctionReturn(0); 11103 } 11104 11105 /*@ 11106 MatHasCongruentLayouts - Determines whether the rows and columns layouts 11107 of the matrix are congruent 11108 11109 Collective on mat 11110 11111 Input Parameters: 11112 . mat - the matrix 11113 11114 Output Parameter: 11115 . cong - either PETSC_TRUE or PETSC_FALSE 11116 11117 Level: beginner 11118 11119 Notes: 11120 11121 .keywords: matrix, has 11122 11123 .seealso: MatCreate(), MatSetSizes() 11124 @*/ 11125 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 11126 { 11127 PetscErrorCode ierr; 11128 11129 PetscFunctionBegin; 11130 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11131 PetscValidType(mat,1); 11132 PetscValidPointer(cong,2); 11133 if (!mat->rmap || !mat->cmap) { 11134 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11135 PetscFunctionReturn(0); 11136 } 11137 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11138 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 11139 if (*cong) mat->congruentlayouts = 1; 11140 else mat->congruentlayouts = 0; 11141 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11142 PetscFunctionReturn(0); 11143 } 11144 11145 /*@ 11146 MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse, 11147 e.g., matrx product of MatPtAP. 11148 11149 Collective on mat 11150 11151 Input Parameters: 11152 . mat - the matrix 11153 11154 Output Parameter: 11155 . mat - the matrix with intermediate data structures released 11156 11157 Level: advanced 11158 11159 Notes: 11160 11161 .keywords: matrix 11162 11163 .seealso: MatPtAP(), MatMatMult() 11164 @*/ 11165 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat) 11166 { 11167 PetscErrorCode ierr; 11168 11169 PetscFunctionBegin; 11170 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11171 PetscValidType(mat,1); 11172 if (mat->ops->freeintermediatedatastructures) { 11173 ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr); 11174 } 11175 PetscFunctionReturn(0); 11176 } 11177