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