1 2 /* 3 This is where the abstract matrix operations are defined 4 */ 5 6 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 7 #include <petsc/private/isimpl.h> 8 #include <petsc/private/vecimpl.h> 9 10 /* Logging support */ 11 PetscClassId MAT_CLASSID; 12 PetscClassId MAT_COLORING_CLASSID; 13 PetscClassId MAT_FDCOLORING_CLASSID; 14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 15 16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch; 36 PetscLogEvent MAT_ViennaCLCopyToGPU; 37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 39 40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 41 42 /*@ 43 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations 44 45 Logically Collective on Mat 46 47 Input Parameters: 48 + x - the matrix 49 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 50 it will create one internally. 51 52 Output Parameter: 53 . x - the matrix 54 55 Example of Usage: 56 .vb 57 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 58 MatSetRandom(x,rctx); 59 PetscRandomDestroy(rctx); 60 .ve 61 62 Level: intermediate 63 64 Concepts: matrix^setting to random 65 Concepts: random^matrix 66 67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 68 @*/ 69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 70 { 71 PetscErrorCode ierr; 72 PetscRandom randObj = NULL; 73 74 PetscFunctionBegin; 75 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 76 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 77 PetscValidType(x,1); 78 79 if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 80 81 if (!rctx) { 82 MPI_Comm comm; 83 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 84 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr); 85 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr); 86 rctx = randObj; 87 } 88 89 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 90 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr); 91 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 92 93 x->assembled = PETSC_TRUE; 94 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 95 PetscFunctionReturn(0); 96 } 97 98 /*@ 99 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 100 101 Logically Collective on Mat 102 103 Input Parameters: 104 . mat - the factored matrix 105 106 Output Parameter: 107 + pivot - the pivot value computed 108 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 109 the share the matrix 110 111 Level: advanced 112 113 Notes: 114 This routine does not work for factorizations done with external packages. 115 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 116 117 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 118 119 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 120 @*/ 121 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 122 { 123 PetscFunctionBegin; 124 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 125 *pivot = mat->factorerror_zeropivot_value; 126 *row = mat->factorerror_zeropivot_row; 127 PetscFunctionReturn(0); 128 } 129 130 /*@ 131 MatFactorGetError - gets the error code from a factorization 132 133 Logically Collective on Mat 134 135 Input Parameters: 136 . mat - the factored matrix 137 138 Output Parameter: 139 . err - the error code 140 141 Level: advanced 142 143 Notes: 144 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 145 146 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 147 @*/ 148 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 149 { 150 PetscFunctionBegin; 151 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 152 *err = mat->factorerrortype; 153 PetscFunctionReturn(0); 154 } 155 156 /*@ 157 MatFactorClearError - clears the error code in a factorization 158 159 Logically Collective on Mat 160 161 Input Parameter: 162 . mat - the factored matrix 163 164 Level: developer 165 166 Notes: 167 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 168 169 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 170 @*/ 171 PetscErrorCode MatFactorClearError(Mat mat) 172 { 173 PetscFunctionBegin; 174 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 175 mat->factorerrortype = MAT_FACTOR_NOERROR; 176 mat->factorerror_zeropivot_value = 0.0; 177 mat->factorerror_zeropivot_row = 0; 178 PetscFunctionReturn(0); 179 } 180 181 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 182 { 183 PetscErrorCode ierr; 184 Vec r,l; 185 const PetscScalar *al; 186 PetscInt i,nz,gnz,N,n; 187 188 PetscFunctionBegin; 189 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 190 if (!cols) { /* nonzero rows */ 191 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 192 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 193 ierr = VecSet(l,0.0);CHKERRQ(ierr); 194 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 195 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 196 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 197 } else { /* nonzero columns */ 198 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 199 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 200 ierr = VecSet(r,0.0);CHKERRQ(ierr); 201 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 202 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 203 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 204 } 205 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 206 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 207 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 208 if (gnz != N) { 209 PetscInt *nzr; 210 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 211 if (nz) { 212 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 213 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 214 } 215 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 216 } else *nonzero = NULL; 217 if (!cols) { /* nonzero rows */ 218 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 219 } else { 220 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 221 } 222 ierr = VecDestroy(&l);CHKERRQ(ierr); 223 ierr = VecDestroy(&r);CHKERRQ(ierr); 224 PetscFunctionReturn(0); 225 } 226 227 /*@ 228 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 229 230 Input Parameter: 231 . A - the matrix 232 233 Output Parameter: 234 . keptrows - the rows that are not completely zero 235 236 Notes: 237 keptrows is set to NULL if all rows are nonzero. 238 239 Level: intermediate 240 241 @*/ 242 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 243 { 244 PetscErrorCode ierr; 245 246 PetscFunctionBegin; 247 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 248 PetscValidType(mat,1); 249 PetscValidPointer(keptrows,2); 250 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 251 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 252 if (!mat->ops->findnonzerorows) { 253 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 254 } else { 255 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 256 } 257 PetscFunctionReturn(0); 258 } 259 260 /*@ 261 MatFindZeroRows - Locate all rows that are completely zero in the matrix 262 263 Input Parameter: 264 . A - the matrix 265 266 Output Parameter: 267 . zerorows - the rows that are completely zero 268 269 Notes: 270 zerorows is set to NULL if no rows are zero. 271 272 Level: intermediate 273 274 @*/ 275 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 276 { 277 PetscErrorCode ierr; 278 IS keptrows; 279 PetscInt m, n; 280 281 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 282 PetscValidType(mat,1); 283 284 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 285 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 286 In keeping with this convention, we set zerorows to NULL if there are no zero 287 rows. */ 288 if (keptrows == NULL) { 289 *zerorows = NULL; 290 } else { 291 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 292 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 293 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 294 } 295 PetscFunctionReturn(0); 296 } 297 298 /*@ 299 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 300 301 Not Collective 302 303 Input Parameters: 304 . A - the matrix 305 306 Output Parameters: 307 . a - the diagonal part (which is a SEQUENTIAL matrix) 308 309 Notes: 310 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 311 Use caution, as the reference count on the returned matrix is not incremented and it is used as 312 part of the containing MPI Mat's normal operation. 313 314 Level: advanced 315 316 @*/ 317 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 318 { 319 PetscErrorCode ierr; 320 321 PetscFunctionBegin; 322 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 323 PetscValidType(A,1); 324 PetscValidPointer(a,3); 325 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 326 if (!A->ops->getdiagonalblock) { 327 PetscMPIInt size; 328 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 329 if (size == 1) { 330 *a = A; 331 PetscFunctionReturn(0); 332 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type"); 333 } 334 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 335 PetscFunctionReturn(0); 336 } 337 338 /*@ 339 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 340 341 Collective on Mat 342 343 Input Parameters: 344 . mat - the matrix 345 346 Output Parameter: 347 . trace - the sum of the diagonal entries 348 349 Level: advanced 350 351 @*/ 352 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 353 { 354 PetscErrorCode ierr; 355 Vec diag; 356 357 PetscFunctionBegin; 358 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 359 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 360 ierr = VecSum(diag,trace);CHKERRQ(ierr); 361 ierr = VecDestroy(&diag);CHKERRQ(ierr); 362 PetscFunctionReturn(0); 363 } 364 365 /*@ 366 MatRealPart - Zeros out the imaginary part of the matrix 367 368 Logically Collective on Mat 369 370 Input Parameters: 371 . mat - the matrix 372 373 Level: advanced 374 375 376 .seealso: MatImaginaryPart() 377 @*/ 378 PetscErrorCode MatRealPart(Mat mat) 379 { 380 PetscErrorCode ierr; 381 382 PetscFunctionBegin; 383 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 384 PetscValidType(mat,1); 385 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 386 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 387 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 388 MatCheckPreallocated(mat,1); 389 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 390 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 391 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 392 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 393 } 394 #endif 395 PetscFunctionReturn(0); 396 } 397 398 /*@C 399 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 400 401 Collective on Mat 402 403 Input Parameter: 404 . mat - the matrix 405 406 Output Parameters: 407 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 408 - ghosts - the global indices of the ghost points 409 410 Notes: 411 the nghosts and ghosts are suitable to pass into VecCreateGhost() 412 413 Level: advanced 414 415 @*/ 416 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 417 { 418 PetscErrorCode ierr; 419 420 PetscFunctionBegin; 421 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 422 PetscValidType(mat,1); 423 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 424 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 425 if (!mat->ops->getghosts) { 426 if (nghosts) *nghosts = 0; 427 if (ghosts) *ghosts = 0; 428 } else { 429 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 430 } 431 PetscFunctionReturn(0); 432 } 433 434 435 /*@ 436 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 437 438 Logically Collective on Mat 439 440 Input Parameters: 441 . mat - the matrix 442 443 Level: advanced 444 445 446 .seealso: MatRealPart() 447 @*/ 448 PetscErrorCode MatImaginaryPart(Mat mat) 449 { 450 PetscErrorCode ierr; 451 452 PetscFunctionBegin; 453 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 454 PetscValidType(mat,1); 455 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 456 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 457 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 458 MatCheckPreallocated(mat,1); 459 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 460 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 461 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 462 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 463 } 464 #endif 465 PetscFunctionReturn(0); 466 } 467 468 /*@ 469 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 470 471 Not Collective 472 473 Input Parameter: 474 . mat - the matrix 475 476 Output Parameters: 477 + missing - is any diagonal missing 478 - dd - first diagonal entry that is missing (optional) on this process 479 480 Level: advanced 481 482 483 .seealso: MatRealPart() 484 @*/ 485 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 486 { 487 PetscErrorCode ierr; 488 489 PetscFunctionBegin; 490 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 491 PetscValidType(mat,1); 492 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 493 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 494 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 495 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 496 PetscFunctionReturn(0); 497 } 498 499 /*@C 500 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 501 for each row that you get to ensure that your application does 502 not bleed memory. 503 504 Not Collective 505 506 Input Parameters: 507 + mat - the matrix 508 - row - the row to get 509 510 Output Parameters: 511 + ncols - if not NULL, the number of nonzeros in the row 512 . cols - if not NULL, the column numbers 513 - vals - if not NULL, the values 514 515 Notes: 516 This routine is provided for people who need to have direct access 517 to the structure of a matrix. We hope that we provide enough 518 high-level matrix routines that few users will need it. 519 520 MatGetRow() always returns 0-based column indices, regardless of 521 whether the internal representation is 0-based (default) or 1-based. 522 523 For better efficiency, set cols and/or vals to NULL if you do 524 not wish to extract these quantities. 525 526 The user can only examine the values extracted with MatGetRow(); 527 the values cannot be altered. To change the matrix entries, one 528 must use MatSetValues(). 529 530 You can only have one call to MatGetRow() outstanding for a particular 531 matrix at a time, per processor. MatGetRow() can only obtain rows 532 associated with the given processor, it cannot get rows from the 533 other processors; for that we suggest using MatCreateSubMatrices(), then 534 MatGetRow() on the submatrix. The row index passed to MatGetRow() 535 is in the global number of rows. 536 537 Fortran Notes: 538 The calling sequence from Fortran is 539 .vb 540 MatGetRow(matrix,row,ncols,cols,values,ierr) 541 Mat matrix (input) 542 integer row (input) 543 integer ncols (output) 544 integer cols(maxcols) (output) 545 double precision (or double complex) values(maxcols) output 546 .ve 547 where maxcols >= maximum nonzeros in any row of the matrix. 548 549 550 Caution: 551 Do not try to change the contents of the output arrays (cols and vals). 552 In some cases, this may corrupt the matrix. 553 554 Level: advanced 555 556 Concepts: matrices^row access 557 558 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 559 @*/ 560 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 561 { 562 PetscErrorCode ierr; 563 PetscInt incols; 564 565 PetscFunctionBegin; 566 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 567 PetscValidType(mat,1); 568 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 569 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 570 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 571 MatCheckPreallocated(mat,1); 572 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 573 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 574 if (ncols) *ncols = incols; 575 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 576 PetscFunctionReturn(0); 577 } 578 579 /*@ 580 MatConjugate - replaces the matrix values with their complex conjugates 581 582 Logically Collective on Mat 583 584 Input Parameters: 585 . mat - the matrix 586 587 Level: advanced 588 589 .seealso: VecConjugate() 590 @*/ 591 PetscErrorCode MatConjugate(Mat mat) 592 { 593 #if defined(PETSC_USE_COMPLEX) 594 PetscErrorCode ierr; 595 596 PetscFunctionBegin; 597 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 598 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 599 if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov"); 600 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 601 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 602 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 603 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 604 } 605 #endif 606 PetscFunctionReturn(0); 607 #else 608 return 0; 609 #endif 610 } 611 612 /*@C 613 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 614 615 Not Collective 616 617 Input Parameters: 618 + mat - the matrix 619 . row - the row to get 620 . ncols, cols - the number of nonzeros and their columns 621 - vals - if nonzero the column values 622 623 Notes: 624 This routine should be called after you have finished examining the entries. 625 626 This routine zeros out ncols, cols, and vals. This is to prevent accidental 627 us of the array after it has been restored. If you pass NULL, it will 628 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 629 630 Fortran Notes: 631 The calling sequence from Fortran is 632 .vb 633 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 634 Mat matrix (input) 635 integer row (input) 636 integer ncols (output) 637 integer cols(maxcols) (output) 638 double precision (or double complex) values(maxcols) output 639 .ve 640 Where maxcols >= maximum nonzeros in any row of the matrix. 641 642 In Fortran MatRestoreRow() MUST be called after MatGetRow() 643 before another call to MatGetRow() can be made. 644 645 Level: advanced 646 647 .seealso: MatGetRow() 648 @*/ 649 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 650 { 651 PetscErrorCode ierr; 652 653 PetscFunctionBegin; 654 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 655 if (ncols) PetscValidIntPointer(ncols,3); 656 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 657 if (!mat->ops->restorerow) PetscFunctionReturn(0); 658 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 659 if (ncols) *ncols = 0; 660 if (cols) *cols = NULL; 661 if (vals) *vals = NULL; 662 PetscFunctionReturn(0); 663 } 664 665 /*@ 666 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 667 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 668 669 Not Collective 670 671 Input Parameters: 672 + mat - the matrix 673 674 Notes: 675 The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format. 676 677 Level: advanced 678 679 Concepts: matrices^row access 680 681 .seealso: MatRestoreRowRowUpperTriangular() 682 @*/ 683 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 684 { 685 PetscErrorCode ierr; 686 687 PetscFunctionBegin; 688 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 689 PetscValidType(mat,1); 690 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 691 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 692 if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 693 MatCheckPreallocated(mat,1); 694 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 695 PetscFunctionReturn(0); 696 } 697 698 /*@ 699 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 700 701 Not Collective 702 703 Input Parameters: 704 + mat - the matrix 705 706 Notes: 707 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 708 709 710 Level: advanced 711 712 .seealso: MatGetRowUpperTriangular() 713 @*/ 714 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 715 { 716 PetscErrorCode ierr; 717 718 PetscFunctionBegin; 719 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 720 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 721 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 722 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 723 PetscFunctionReturn(0); 724 } 725 726 /*@C 727 MatSetOptionsPrefix - Sets the prefix used for searching for all 728 Mat options in the database. 729 730 Logically Collective on Mat 731 732 Input Parameter: 733 + A - the Mat context 734 - prefix - the prefix to prepend to all option names 735 736 Notes: 737 A hyphen (-) must NOT be given at the beginning of the prefix name. 738 The first character of all runtime options is AUTOMATICALLY the hyphen. 739 740 Level: advanced 741 742 .keywords: Mat, set, options, prefix, database 743 744 .seealso: MatSetFromOptions() 745 @*/ 746 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 747 { 748 PetscErrorCode ierr; 749 750 PetscFunctionBegin; 751 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 752 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 753 PetscFunctionReturn(0); 754 } 755 756 /*@C 757 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 758 Mat options in the database. 759 760 Logically Collective on Mat 761 762 Input Parameters: 763 + A - the Mat context 764 - prefix - the prefix to prepend to all option names 765 766 Notes: 767 A hyphen (-) must NOT be given at the beginning of the prefix name. 768 The first character of all runtime options is AUTOMATICALLY the hyphen. 769 770 Level: advanced 771 772 .keywords: Mat, append, options, prefix, database 773 774 .seealso: MatGetOptionsPrefix() 775 @*/ 776 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 777 { 778 PetscErrorCode ierr; 779 780 PetscFunctionBegin; 781 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 782 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 783 PetscFunctionReturn(0); 784 } 785 786 /*@C 787 MatGetOptionsPrefix - Sets the prefix used for searching for all 788 Mat options in the database. 789 790 Not Collective 791 792 Input Parameter: 793 . A - the Mat context 794 795 Output Parameter: 796 . prefix - pointer to the prefix string used 797 798 Notes: 799 On the fortran side, the user should pass in a string 'prefix' of 800 sufficient length to hold the prefix. 801 802 Level: advanced 803 804 .keywords: Mat, get, options, prefix, database 805 806 .seealso: MatAppendOptionsPrefix() 807 @*/ 808 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 809 { 810 PetscErrorCode ierr; 811 812 PetscFunctionBegin; 813 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 814 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 815 PetscFunctionReturn(0); 816 } 817 818 /*@ 819 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 820 821 Collective on Mat 822 823 Input Parameters: 824 . A - the Mat context 825 826 Notes: 827 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 828 Currently support MPIAIJ and SEQAIJ. 829 830 Level: beginner 831 832 .keywords: Mat, ResetPreallocation 833 834 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 835 @*/ 836 PetscErrorCode MatResetPreallocation(Mat A) 837 { 838 PetscErrorCode ierr; 839 840 PetscFunctionBegin; 841 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 842 PetscValidType(A,1); 843 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 844 PetscFunctionReturn(0); 845 } 846 847 848 /*@ 849 MatSetUp - Sets up the internal matrix data structures for the later use. 850 851 Collective on Mat 852 853 Input Parameters: 854 . A - the Mat context 855 856 Notes: 857 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 858 859 If a suitable preallocation routine is used, this function does not need to be called. 860 861 See the Performance chapter of the PETSc users manual for how to preallocate matrices 862 863 Level: beginner 864 865 .keywords: Mat, setup 866 867 .seealso: MatCreate(), MatDestroy() 868 @*/ 869 PetscErrorCode MatSetUp(Mat A) 870 { 871 PetscMPIInt size; 872 PetscErrorCode ierr; 873 874 PetscFunctionBegin; 875 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 876 if (!((PetscObject)A)->type_name) { 877 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 878 if (size == 1) { 879 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 880 } else { 881 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 882 } 883 } 884 if (!A->preallocated && A->ops->setup) { 885 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 886 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 887 } 888 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 889 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 890 A->preallocated = PETSC_TRUE; 891 PetscFunctionReturn(0); 892 } 893 894 #if defined(PETSC_HAVE_SAWS) 895 #include <petscviewersaws.h> 896 #endif 897 /*@C 898 MatView - Visualizes a matrix object. 899 900 Collective on Mat 901 902 Input Parameters: 903 + mat - the matrix 904 - viewer - visualization context 905 906 Notes: 907 The available visualization contexts include 908 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 909 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 910 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 911 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 912 913 The user can open alternative visualization contexts with 914 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 915 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 916 specified file; corresponding input uses MatLoad() 917 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 918 an X window display 919 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 920 Currently only the sequential dense and AIJ 921 matrix types support the Socket viewer. 922 923 The user can call PetscViewerPushFormat() to specify the output 924 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 925 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 926 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 927 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 928 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 929 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 930 format common among all matrix types 931 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 932 format (which is in many cases the same as the default) 933 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 934 size and structure (not the matrix entries) 935 . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 936 the matrix structure 937 938 Options Database Keys: 939 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 940 . -mat_view ::ascii_info_detail - Prints more detailed info 941 . -mat_view - Prints matrix in ASCII format 942 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 943 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 944 . -display <name> - Sets display name (default is host) 945 . -draw_pause <sec> - Sets number of seconds to pause after display 946 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 947 . -viewer_socket_machine <machine> - 948 . -viewer_socket_port <port> - 949 . -mat_view binary - save matrix to file in binary format 950 - -viewer_binary_filename <name> - 951 Level: beginner 952 953 Notes: 954 see the manual page for MatLoad() for the exact format of the binary file when the binary 955 viewer is used. 956 957 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 958 viewer is used. 959 960 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure. 961 And then use the following mouse functions: 962 left mouse: zoom in 963 middle mouse: zoom out 964 right mouse: continue with the simulation 965 966 Concepts: matrices^viewing 967 Concepts: matrices^plotting 968 Concepts: matrices^printing 969 970 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 971 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 972 @*/ 973 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 974 { 975 PetscErrorCode ierr; 976 PetscInt rows,cols,rbs,cbs; 977 PetscBool iascii,ibinary; 978 PetscViewerFormat format; 979 PetscMPIInt size; 980 #if defined(PETSC_HAVE_SAWS) 981 PetscBool issaws; 982 #endif 983 984 PetscFunctionBegin; 985 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 986 PetscValidType(mat,1); 987 if (!viewer) { 988 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 989 } 990 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 991 PetscCheckSameComm(mat,1,viewer,2); 992 MatCheckPreallocated(mat,1); 993 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 994 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 995 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 996 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 997 if (ibinary) { 998 PetscBool mpiio; 999 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 1000 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 1001 } 1002 1003 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1004 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1005 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1006 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 1007 } 1008 1009 #if defined(PETSC_HAVE_SAWS) 1010 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 1011 #endif 1012 if (iascii) { 1013 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1014 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 1015 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1016 MatNullSpace nullsp,transnullsp; 1017 1018 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1019 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1020 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1021 if (rbs != 1 || cbs != 1) { 1022 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 1023 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 1024 } else { 1025 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1026 } 1027 if (mat->factortype) { 1028 MatSolverType solver; 1029 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1030 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1031 } 1032 if (mat->ops->getinfo) { 1033 MatInfo info; 1034 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1035 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1036 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1037 } 1038 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1039 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1040 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1041 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1042 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1043 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1044 } 1045 #if defined(PETSC_HAVE_SAWS) 1046 } else if (issaws) { 1047 PetscMPIInt rank; 1048 1049 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1050 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1051 if (!((PetscObject)mat)->amsmem && !rank) { 1052 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1053 } 1054 #endif 1055 } 1056 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1057 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1058 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1059 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1060 } else if (mat->ops->view) { 1061 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1062 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1063 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1064 } 1065 if (iascii) { 1066 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1067 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1068 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1069 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1070 } 1071 } 1072 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1073 PetscFunctionReturn(0); 1074 } 1075 1076 #if defined(PETSC_USE_DEBUG) 1077 #include <../src/sys/totalview/tv_data_display.h> 1078 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1079 { 1080 TV_add_row("Local rows", "int", &mat->rmap->n); 1081 TV_add_row("Local columns", "int", &mat->cmap->n); 1082 TV_add_row("Global rows", "int", &mat->rmap->N); 1083 TV_add_row("Global columns", "int", &mat->cmap->N); 1084 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1085 return TV_format_OK; 1086 } 1087 #endif 1088 1089 /*@C 1090 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1091 with MatView(). The matrix format is determined from the options database. 1092 Generates a parallel MPI matrix if the communicator has more than one 1093 processor. The default matrix type is AIJ. 1094 1095 Collective on PetscViewer 1096 1097 Input Parameters: 1098 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1099 or some related function before a call to MatLoad() 1100 - viewer - binary/HDF5 file viewer 1101 1102 Options Database Keys: 1103 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1104 block size 1105 . -matload_block_size <bs> 1106 1107 Level: beginner 1108 1109 Notes: 1110 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1111 Mat before calling this routine if you wish to set it from the options database. 1112 1113 MatLoad() automatically loads into the options database any options 1114 given in the file filename.info where filename is the name of the file 1115 that was passed to the PetscViewerBinaryOpen(). The options in the info 1116 file will be ignored if you use the -viewer_binary_skip_info option. 1117 1118 If the type or size of newmat is not set before a call to MatLoad, PETSc 1119 sets the default matrix type AIJ and sets the local and global sizes. 1120 If type and/or size is already set, then the same are used. 1121 1122 In parallel, each processor can load a subset of rows (or the 1123 entire matrix). This routine is especially useful when a large 1124 matrix is stored on disk and only part of it is desired on each 1125 processor. For example, a parallel solver may access only some of 1126 the rows from each processor. The algorithm used here reads 1127 relatively small blocks of data rather than reading the entire 1128 matrix and then subsetting it. 1129 1130 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1131 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1132 or the sequence like 1133 $ PetscViewer v; 1134 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1135 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1136 $ PetscViewerSetFromOptions(v); 1137 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1138 $ PetscViewerFileSetName(v,"datafile"); 1139 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1140 $ -viewer_type {binary,hdf5} 1141 1142 See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach, 1143 and src/mat/examples/tutorials/ex10.c with the second approach. 1144 1145 Notes about the PETSc binary format: 1146 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1147 is read onto rank 0 and then shipped to its destination rank, one after another. 1148 Multiple objects, both matrices and vectors, can be stored within the same file. 1149 Their PetscObject name is ignored; they are loaded in the order of their storage. 1150 1151 Most users should not need to know the details of the binary storage 1152 format, since MatLoad() and MatView() completely hide these details. 1153 But for anyone who's interested, the standard binary matrix storage 1154 format is 1155 1156 $ int MAT_FILE_CLASSID 1157 $ int number of rows 1158 $ int number of columns 1159 $ int total number of nonzeros 1160 $ int *number nonzeros in each row 1161 $ int *column indices of all nonzeros (starting index is zero) 1162 $ PetscScalar *values of all nonzeros 1163 1164 PETSc automatically does the byte swapping for 1165 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1166 linux, Windows and the paragon; thus if you write your own binary 1167 read/write routines you have to swap the bytes; see PetscBinaryRead() 1168 and PetscBinaryWrite() to see how this may be done. 1169 1170 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1171 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1172 Each processor's chunk is loaded independently by its owning rank. 1173 Multiple objects, both matrices and vectors, can be stored within the same file. 1174 They are looked up by their PetscObject name. 1175 1176 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1177 by default the same structure and naming of the AIJ arrays and column count 1178 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1179 $ save example.mat A b -v7.3 1180 can be directly read by this routine (see Reference 1 for details). 1181 Note that depending on your MATLAB version, this format might be a default, 1182 otherwise you can set it as default in Preferences. 1183 1184 Unless -nocompression flag is used to save the file in MATLAB, 1185 PETSc must be configured with ZLIB package. 1186 1187 Current HDF5 limitations: 1188 MATLAB uses a column-major storage, so to get the correct objects in PETSc, 1189 you need to transpose your matrices and vectors before saving in MATLAB. 1190 1191 This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices. 1192 1193 MatView() is not yet implemented. 1194 1195 References: 1196 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1197 1198 .keywords: matrix, load, binary, input, HDF5 1199 1200 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), PetscViewerHDF5SetAIJNames(), PetscViewerHDF5SetAIJColumnCountAttributeName(), MatView(), VecLoad() 1201 1202 @*/ 1203 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1204 { 1205 PetscErrorCode ierr; 1206 PetscBool flg; 1207 1208 PetscFunctionBegin; 1209 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1210 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1211 1212 if (!((PetscObject)newmat)->type_name) { 1213 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1214 } 1215 1216 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 1217 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1218 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1219 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1220 1221 flg = PETSC_FALSE; 1222 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1223 if (flg) { 1224 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1225 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1226 } 1227 flg = PETSC_FALSE; 1228 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1229 if (flg) { 1230 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1231 } 1232 PetscFunctionReturn(0); 1233 } 1234 1235 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1236 { 1237 PetscErrorCode ierr; 1238 Mat_Redundant *redund = *redundant; 1239 PetscInt i; 1240 1241 PetscFunctionBegin; 1242 if (redund){ 1243 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1244 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1245 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1246 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1247 } else { 1248 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1249 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1250 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1251 for (i=0; i<redund->nrecvs; i++) { 1252 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1253 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1254 } 1255 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1256 } 1257 1258 if (redund->subcomm) { 1259 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1260 } 1261 ierr = PetscFree(redund);CHKERRQ(ierr); 1262 } 1263 PetscFunctionReturn(0); 1264 } 1265 1266 /*@ 1267 MatDestroy - Frees space taken by a matrix. 1268 1269 Collective on Mat 1270 1271 Input Parameter: 1272 . A - the matrix 1273 1274 Level: beginner 1275 1276 @*/ 1277 PetscErrorCode MatDestroy(Mat *A) 1278 { 1279 PetscErrorCode ierr; 1280 1281 PetscFunctionBegin; 1282 if (!*A) PetscFunctionReturn(0); 1283 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1284 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1285 1286 /* if memory was published with SAWs then destroy it */ 1287 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1288 if ((*A)->ops->destroy) { 1289 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1290 } 1291 1292 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1293 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1294 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1295 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1296 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1297 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1298 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1299 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1300 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1301 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1302 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1303 PetscFunctionReturn(0); 1304 } 1305 1306 /*@C 1307 MatSetValues - Inserts or adds a block of values into a matrix. 1308 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1309 MUST be called after all calls to MatSetValues() have been completed. 1310 1311 Not Collective 1312 1313 Input Parameters: 1314 + mat - the matrix 1315 . v - a logically two-dimensional array of values 1316 . m, idxm - the number of rows and their global indices 1317 . n, idxn - the number of columns and their global indices 1318 - addv - either ADD_VALUES or INSERT_VALUES, where 1319 ADD_VALUES adds values to any existing entries, and 1320 INSERT_VALUES replaces existing entries with new values 1321 1322 Notes: 1323 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1324 MatSetUp() before using this routine 1325 1326 By default the values, v, are row-oriented. See MatSetOption() for other options. 1327 1328 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1329 options cannot be mixed without intervening calls to the assembly 1330 routines. 1331 1332 MatSetValues() uses 0-based row and column numbers in Fortran 1333 as well as in C. 1334 1335 Negative indices may be passed in idxm and idxn, these rows and columns are 1336 simply ignored. This allows easily inserting element stiffness matrices 1337 with homogeneous Dirchlet boundary conditions that you don't want represented 1338 in the matrix. 1339 1340 Efficiency Alert: 1341 The routine MatSetValuesBlocked() may offer much better efficiency 1342 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1343 1344 Level: beginner 1345 1346 Developer Notes: 1347 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1348 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1349 1350 Concepts: matrices^putting entries in 1351 1352 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1353 InsertMode, INSERT_VALUES, ADD_VALUES 1354 @*/ 1355 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1356 { 1357 PetscErrorCode ierr; 1358 #if defined(PETSC_USE_DEBUG) 1359 PetscInt i,j; 1360 #endif 1361 1362 PetscFunctionBeginHot; 1363 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1364 PetscValidType(mat,1); 1365 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1366 PetscValidIntPointer(idxm,3); 1367 PetscValidIntPointer(idxn,5); 1368 PetscValidScalarPointer(v,6); 1369 MatCheckPreallocated(mat,1); 1370 if (mat->insertmode == NOT_SET_VALUES) { 1371 mat->insertmode = addv; 1372 } 1373 #if defined(PETSC_USE_DEBUG) 1374 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1375 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1376 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1377 1378 for (i=0; i<m; i++) { 1379 for (j=0; j<n; j++) { 1380 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1381 #if defined(PETSC_USE_COMPLEX) 1382 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]); 1383 #else 1384 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1385 #endif 1386 } 1387 } 1388 #endif 1389 1390 if (mat->assembled) { 1391 mat->was_assembled = PETSC_TRUE; 1392 mat->assembled = PETSC_FALSE; 1393 } 1394 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1395 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1396 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1397 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1398 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1399 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1400 } 1401 #endif 1402 PetscFunctionReturn(0); 1403 } 1404 1405 1406 /*@ 1407 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1408 values into a matrix 1409 1410 Not Collective 1411 1412 Input Parameters: 1413 + mat - the matrix 1414 . row - the (block) row to set 1415 - v - a logically two-dimensional array of values 1416 1417 Notes: 1418 By the values, v, are column-oriented (for the block version) and sorted 1419 1420 All the nonzeros in the row must be provided 1421 1422 The matrix must have previously had its column indices set 1423 1424 The row must belong to this process 1425 1426 Level: intermediate 1427 1428 Concepts: matrices^putting entries in 1429 1430 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1431 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1432 @*/ 1433 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1434 { 1435 PetscErrorCode ierr; 1436 PetscInt globalrow; 1437 1438 PetscFunctionBegin; 1439 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1440 PetscValidType(mat,1); 1441 PetscValidScalarPointer(v,2); 1442 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1443 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1444 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1445 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1446 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1447 } 1448 #endif 1449 PetscFunctionReturn(0); 1450 } 1451 1452 /*@ 1453 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1454 values into a matrix 1455 1456 Not Collective 1457 1458 Input Parameters: 1459 + mat - the matrix 1460 . row - the (block) row to set 1461 - 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 1462 1463 Notes: 1464 The values, v, are column-oriented for the block version. 1465 1466 All the nonzeros in the row must be provided 1467 1468 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1469 1470 The row must belong to this process 1471 1472 Level: advanced 1473 1474 Concepts: matrices^putting entries in 1475 1476 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1477 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1478 @*/ 1479 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1480 { 1481 PetscErrorCode ierr; 1482 1483 PetscFunctionBeginHot; 1484 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1485 PetscValidType(mat,1); 1486 MatCheckPreallocated(mat,1); 1487 PetscValidScalarPointer(v,2); 1488 #if defined(PETSC_USE_DEBUG) 1489 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1490 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1491 #endif 1492 mat->insertmode = INSERT_VALUES; 1493 1494 if (mat->assembled) { 1495 mat->was_assembled = PETSC_TRUE; 1496 mat->assembled = PETSC_FALSE; 1497 } 1498 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1499 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1500 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1501 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1502 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1503 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1504 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1505 } 1506 #endif 1507 PetscFunctionReturn(0); 1508 } 1509 1510 /*@ 1511 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1512 Using structured grid indexing 1513 1514 Not Collective 1515 1516 Input Parameters: 1517 + mat - the matrix 1518 . m - number of rows being entered 1519 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1520 . n - number of columns being entered 1521 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1522 . v - a logically two-dimensional array of values 1523 - addv - either ADD_VALUES or INSERT_VALUES, where 1524 ADD_VALUES adds values to any existing entries, and 1525 INSERT_VALUES replaces existing entries with new values 1526 1527 Notes: 1528 By default the values, v, are row-oriented. See MatSetOption() for other options. 1529 1530 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1531 options cannot be mixed without intervening calls to the assembly 1532 routines. 1533 1534 The grid coordinates are across the entire grid, not just the local portion 1535 1536 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1537 as well as in C. 1538 1539 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1540 1541 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1542 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1543 1544 The columns and rows in the stencil passed in MUST be contained within the 1545 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1546 if you create a DMDA with an overlap of one grid level and on a particular process its first 1547 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1548 first i index you can use in your column and row indices in MatSetStencil() is 5. 1549 1550 In Fortran idxm and idxn should be declared as 1551 $ MatStencil idxm(4,m),idxn(4,n) 1552 and the values inserted using 1553 $ idxm(MatStencil_i,1) = i 1554 $ idxm(MatStencil_j,1) = j 1555 $ idxm(MatStencil_k,1) = k 1556 $ idxm(MatStencil_c,1) = c 1557 etc 1558 1559 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1560 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1561 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1562 DM_BOUNDARY_PERIODIC boundary type. 1563 1564 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 1565 a single value per point) you can skip filling those indices. 1566 1567 Inspired by the structured grid interface to the HYPRE package 1568 (http://www.llnl.gov/CASC/hypre) 1569 1570 Efficiency Alert: 1571 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1572 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1573 1574 Level: beginner 1575 1576 Concepts: matrices^putting entries in 1577 1578 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1579 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1580 @*/ 1581 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1582 { 1583 PetscErrorCode ierr; 1584 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1585 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1586 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1587 1588 PetscFunctionBegin; 1589 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1590 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1591 PetscValidType(mat,1); 1592 PetscValidIntPointer(idxm,3); 1593 PetscValidIntPointer(idxn,5); 1594 PetscValidScalarPointer(v,6); 1595 1596 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1597 jdxm = buf; jdxn = buf+m; 1598 } else { 1599 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1600 jdxm = bufm; jdxn = bufn; 1601 } 1602 for (i=0; i<m; i++) { 1603 for (j=0; j<3-sdim; j++) dxm++; 1604 tmp = *dxm++ - starts[0]; 1605 for (j=0; j<dim-1; j++) { 1606 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1607 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1608 } 1609 if (mat->stencil.noc) dxm++; 1610 jdxm[i] = tmp; 1611 } 1612 for (i=0; i<n; i++) { 1613 for (j=0; j<3-sdim; j++) dxn++; 1614 tmp = *dxn++ - starts[0]; 1615 for (j=0; j<dim-1; j++) { 1616 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1617 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1618 } 1619 if (mat->stencil.noc) dxn++; 1620 jdxn[i] = tmp; 1621 } 1622 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1623 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1624 PetscFunctionReturn(0); 1625 } 1626 1627 /*@ 1628 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1629 Using structured grid indexing 1630 1631 Not Collective 1632 1633 Input Parameters: 1634 + mat - the matrix 1635 . m - number of rows being entered 1636 . idxm - grid coordinates for matrix rows being entered 1637 . n - number of columns being entered 1638 . idxn - grid coordinates for matrix columns being entered 1639 . v - a logically two-dimensional array of values 1640 - addv - either ADD_VALUES or INSERT_VALUES, where 1641 ADD_VALUES adds values to any existing entries, and 1642 INSERT_VALUES replaces existing entries with new values 1643 1644 Notes: 1645 By default the values, v, are row-oriented and unsorted. 1646 See MatSetOption() for other options. 1647 1648 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1649 options cannot be mixed without intervening calls to the assembly 1650 routines. 1651 1652 The grid coordinates are across the entire grid, not just the local portion 1653 1654 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1655 as well as in C. 1656 1657 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1658 1659 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1660 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1661 1662 The columns and rows in the stencil passed in MUST be contained within the 1663 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1664 if you create a DMDA with an overlap of one grid level and on a particular process its first 1665 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1666 first i index you can use in your column and row indices in MatSetStencil() is 5. 1667 1668 In Fortran idxm and idxn should be declared as 1669 $ MatStencil idxm(4,m),idxn(4,n) 1670 and the values inserted using 1671 $ idxm(MatStencil_i,1) = i 1672 $ idxm(MatStencil_j,1) = j 1673 $ idxm(MatStencil_k,1) = k 1674 etc 1675 1676 Negative indices may be passed in idxm and idxn, these rows and columns are 1677 simply ignored. This allows easily inserting element stiffness matrices 1678 with homogeneous Dirchlet boundary conditions that you don't want represented 1679 in the matrix. 1680 1681 Inspired by the structured grid interface to the HYPRE package 1682 (http://www.llnl.gov/CASC/hypre) 1683 1684 Level: beginner 1685 1686 Concepts: matrices^putting entries in 1687 1688 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1689 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1690 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1691 @*/ 1692 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1693 { 1694 PetscErrorCode ierr; 1695 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1696 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1697 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1698 1699 PetscFunctionBegin; 1700 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1701 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1702 PetscValidType(mat,1); 1703 PetscValidIntPointer(idxm,3); 1704 PetscValidIntPointer(idxn,5); 1705 PetscValidScalarPointer(v,6); 1706 1707 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1708 jdxm = buf; jdxn = buf+m; 1709 } else { 1710 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1711 jdxm = bufm; jdxn = bufn; 1712 } 1713 for (i=0; i<m; i++) { 1714 for (j=0; j<3-sdim; j++) dxm++; 1715 tmp = *dxm++ - starts[0]; 1716 for (j=0; j<sdim-1; j++) { 1717 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1718 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1719 } 1720 dxm++; 1721 jdxm[i] = tmp; 1722 } 1723 for (i=0; i<n; i++) { 1724 for (j=0; j<3-sdim; j++) dxn++; 1725 tmp = *dxn++ - starts[0]; 1726 for (j=0; j<sdim-1; j++) { 1727 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1728 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1729 } 1730 dxn++; 1731 jdxn[i] = tmp; 1732 } 1733 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1734 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1735 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1736 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1737 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1738 } 1739 #endif 1740 PetscFunctionReturn(0); 1741 } 1742 1743 /*@ 1744 MatSetStencil - Sets the grid information for setting values into a matrix via 1745 MatSetValuesStencil() 1746 1747 Not Collective 1748 1749 Input Parameters: 1750 + mat - the matrix 1751 . dim - dimension of the grid 1, 2, or 3 1752 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1753 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1754 - dof - number of degrees of freedom per node 1755 1756 1757 Inspired by the structured grid interface to the HYPRE package 1758 (www.llnl.gov/CASC/hyper) 1759 1760 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1761 user. 1762 1763 Level: beginner 1764 1765 Concepts: matrices^putting entries in 1766 1767 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1768 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1769 @*/ 1770 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1771 { 1772 PetscInt i; 1773 1774 PetscFunctionBegin; 1775 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1776 PetscValidIntPointer(dims,3); 1777 PetscValidIntPointer(starts,4); 1778 1779 mat->stencil.dim = dim + (dof > 1); 1780 for (i=0; i<dim; i++) { 1781 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1782 mat->stencil.starts[i] = starts[dim-i-1]; 1783 } 1784 mat->stencil.dims[dim] = dof; 1785 mat->stencil.starts[dim] = 0; 1786 mat->stencil.noc = (PetscBool)(dof == 1); 1787 PetscFunctionReturn(0); 1788 } 1789 1790 /*@C 1791 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1792 1793 Not Collective 1794 1795 Input Parameters: 1796 + mat - the matrix 1797 . v - a logically two-dimensional array of values 1798 . m, idxm - the number of block rows and their global block indices 1799 . n, idxn - the number of block columns and their global block indices 1800 - addv - either ADD_VALUES or INSERT_VALUES, where 1801 ADD_VALUES adds values to any existing entries, and 1802 INSERT_VALUES replaces existing entries with new values 1803 1804 Notes: 1805 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1806 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1807 1808 The m and n count the NUMBER of blocks in the row direction and column direction, 1809 NOT the total number of rows/columns; for example, if the block size is 2 and 1810 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1811 The values in idxm would be 1 2; that is the first index for each block divided by 1812 the block size. 1813 1814 Note that you must call MatSetBlockSize() when constructing this matrix (before 1815 preallocating it). 1816 1817 By default the values, v, are row-oriented, so the layout of 1818 v is the same as for MatSetValues(). See MatSetOption() for other options. 1819 1820 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1821 options cannot be mixed without intervening calls to the assembly 1822 routines. 1823 1824 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1825 as well as in C. 1826 1827 Negative indices may be passed in idxm and idxn, these rows and columns are 1828 simply ignored. This allows easily inserting element stiffness matrices 1829 with homogeneous Dirchlet boundary conditions that you don't want represented 1830 in the matrix. 1831 1832 Each time an entry is set within a sparse matrix via MatSetValues(), 1833 internal searching must be done to determine where to place the 1834 data in the matrix storage space. By instead inserting blocks of 1835 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1836 reduced. 1837 1838 Example: 1839 $ Suppose m=n=2 and block size(bs) = 2 The array is 1840 $ 1841 $ 1 2 | 3 4 1842 $ 5 6 | 7 8 1843 $ - - - | - - - 1844 $ 9 10 | 11 12 1845 $ 13 14 | 15 16 1846 $ 1847 $ v[] should be passed in like 1848 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1849 $ 1850 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1851 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1852 1853 Level: intermediate 1854 1855 Concepts: matrices^putting entries in blocked 1856 1857 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1858 @*/ 1859 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1860 { 1861 PetscErrorCode ierr; 1862 1863 PetscFunctionBeginHot; 1864 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1865 PetscValidType(mat,1); 1866 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1867 PetscValidIntPointer(idxm,3); 1868 PetscValidIntPointer(idxn,5); 1869 PetscValidScalarPointer(v,6); 1870 MatCheckPreallocated(mat,1); 1871 if (mat->insertmode == NOT_SET_VALUES) { 1872 mat->insertmode = addv; 1873 } 1874 #if defined(PETSC_USE_DEBUG) 1875 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1876 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1877 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1878 #endif 1879 1880 if (mat->assembled) { 1881 mat->was_assembled = PETSC_TRUE; 1882 mat->assembled = PETSC_FALSE; 1883 } 1884 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1885 if (mat->ops->setvaluesblocked) { 1886 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1887 } else { 1888 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1889 PetscInt i,j,bs,cbs; 1890 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1891 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1892 iidxm = buf; iidxn = buf + m*bs; 1893 } else { 1894 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1895 iidxm = bufr; iidxn = bufc; 1896 } 1897 for (i=0; i<m; i++) { 1898 for (j=0; j<bs; j++) { 1899 iidxm[i*bs+j] = bs*idxm[i] + j; 1900 } 1901 } 1902 for (i=0; i<n; i++) { 1903 for (j=0; j<cbs; j++) { 1904 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1905 } 1906 } 1907 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1908 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1909 } 1910 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1911 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1912 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1913 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1914 } 1915 #endif 1916 PetscFunctionReturn(0); 1917 } 1918 1919 /*@ 1920 MatGetValues - Gets a block of values from a matrix. 1921 1922 Not Collective; currently only returns a local block 1923 1924 Input Parameters: 1925 + mat - the matrix 1926 . v - a logically two-dimensional array for storing the values 1927 . m, idxm - the number of rows and their global indices 1928 - n, idxn - the number of columns and their global indices 1929 1930 Notes: 1931 The user must allocate space (m*n PetscScalars) for the values, v. 1932 The values, v, are then returned in a row-oriented format, 1933 analogous to that used by default in MatSetValues(). 1934 1935 MatGetValues() uses 0-based row and column numbers in 1936 Fortran as well as in C. 1937 1938 MatGetValues() requires that the matrix has been assembled 1939 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1940 MatSetValues() and MatGetValues() CANNOT be made in succession 1941 without intermediate matrix assembly. 1942 1943 Negative row or column indices will be ignored and those locations in v[] will be 1944 left unchanged. 1945 1946 Level: advanced 1947 1948 Concepts: matrices^accessing values 1949 1950 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1951 @*/ 1952 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1953 { 1954 PetscErrorCode ierr; 1955 1956 PetscFunctionBegin; 1957 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1958 PetscValidType(mat,1); 1959 if (!m || !n) PetscFunctionReturn(0); 1960 PetscValidIntPointer(idxm,3); 1961 PetscValidIntPointer(idxn,5); 1962 PetscValidScalarPointer(v,6); 1963 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1964 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1965 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1966 MatCheckPreallocated(mat,1); 1967 1968 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1969 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1970 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1971 PetscFunctionReturn(0); 1972 } 1973 1974 /*@ 1975 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1976 the same size. Currently, this can only be called once and creates the given matrix. 1977 1978 Not Collective 1979 1980 Input Parameters: 1981 + mat - the matrix 1982 . nb - the number of blocks 1983 . bs - the number of rows (and columns) in each block 1984 . rows - a concatenation of the rows for each block 1985 - v - a concatenation of logically two-dimensional arrays of values 1986 1987 Notes: 1988 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1989 1990 Level: advanced 1991 1992 Concepts: matrices^putting entries in 1993 1994 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1995 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1996 @*/ 1997 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 1998 { 1999 PetscErrorCode ierr; 2000 2001 PetscFunctionBegin; 2002 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2003 PetscValidType(mat,1); 2004 PetscValidScalarPointer(rows,4); 2005 PetscValidScalarPointer(v,5); 2006 #if defined(PETSC_USE_DEBUG) 2007 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2008 #endif 2009 2010 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 2011 if (mat->ops->setvaluesbatch) { 2012 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 2013 } else { 2014 PetscInt b; 2015 for (b = 0; b < nb; ++b) { 2016 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 2017 } 2018 } 2019 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 2020 PetscFunctionReturn(0); 2021 } 2022 2023 /*@ 2024 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2025 the routine MatSetValuesLocal() to allow users to insert matrix entries 2026 using a local (per-processor) numbering. 2027 2028 Not Collective 2029 2030 Input Parameters: 2031 + x - the matrix 2032 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2033 - cmapping - column mapping 2034 2035 Level: intermediate 2036 2037 Concepts: matrices^local to global mapping 2038 Concepts: local to global mapping^for matrices 2039 2040 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 2041 @*/ 2042 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2043 { 2044 PetscErrorCode ierr; 2045 2046 PetscFunctionBegin; 2047 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2048 PetscValidType(x,1); 2049 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2050 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2051 2052 if (x->ops->setlocaltoglobalmapping) { 2053 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 2054 } else { 2055 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 2056 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 2057 } 2058 PetscFunctionReturn(0); 2059 } 2060 2061 2062 /*@ 2063 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2064 2065 Not Collective 2066 2067 Input Parameters: 2068 . A - the matrix 2069 2070 Output Parameters: 2071 + rmapping - row mapping 2072 - cmapping - column mapping 2073 2074 Level: advanced 2075 2076 Concepts: matrices^local to global mapping 2077 Concepts: local to global mapping^for matrices 2078 2079 .seealso: MatSetValuesLocal() 2080 @*/ 2081 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2082 { 2083 PetscFunctionBegin; 2084 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2085 PetscValidType(A,1); 2086 if (rmapping) PetscValidPointer(rmapping,2); 2087 if (cmapping) PetscValidPointer(cmapping,3); 2088 if (rmapping) *rmapping = A->rmap->mapping; 2089 if (cmapping) *cmapping = A->cmap->mapping; 2090 PetscFunctionReturn(0); 2091 } 2092 2093 /*@ 2094 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2095 2096 Not Collective 2097 2098 Input Parameters: 2099 . A - the matrix 2100 2101 Output Parameters: 2102 + rmap - row layout 2103 - cmap - column layout 2104 2105 Level: advanced 2106 2107 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2108 @*/ 2109 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2110 { 2111 PetscFunctionBegin; 2112 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2113 PetscValidType(A,1); 2114 if (rmap) PetscValidPointer(rmap,2); 2115 if (cmap) PetscValidPointer(cmap,3); 2116 if (rmap) *rmap = A->rmap; 2117 if (cmap) *cmap = A->cmap; 2118 PetscFunctionReturn(0); 2119 } 2120 2121 /*@C 2122 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2123 using a local ordering of the nodes. 2124 2125 Not Collective 2126 2127 Input Parameters: 2128 + mat - the matrix 2129 . nrow, irow - number of rows and their local indices 2130 . ncol, icol - number of columns and their local indices 2131 . y - a logically two-dimensional array of values 2132 - addv - either INSERT_VALUES or ADD_VALUES, where 2133 ADD_VALUES adds values to any existing entries, and 2134 INSERT_VALUES replaces existing entries with new values 2135 2136 Notes: 2137 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2138 MatSetUp() before using this routine 2139 2140 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2141 2142 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2143 options cannot be mixed without intervening calls to the assembly 2144 routines. 2145 2146 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2147 MUST be called after all calls to MatSetValuesLocal() have been completed. 2148 2149 Level: intermediate 2150 2151 Concepts: matrices^putting entries in with local numbering 2152 2153 Developer Notes: 2154 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2155 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2156 2157 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2158 MatSetValueLocal() 2159 @*/ 2160 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2161 { 2162 PetscErrorCode ierr; 2163 2164 PetscFunctionBeginHot; 2165 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2166 PetscValidType(mat,1); 2167 MatCheckPreallocated(mat,1); 2168 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2169 PetscValidIntPointer(irow,3); 2170 PetscValidIntPointer(icol,5); 2171 PetscValidScalarPointer(y,6); 2172 if (mat->insertmode == NOT_SET_VALUES) { 2173 mat->insertmode = addv; 2174 } 2175 #if defined(PETSC_USE_DEBUG) 2176 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2177 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2178 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2179 #endif 2180 2181 if (mat->assembled) { 2182 mat->was_assembled = PETSC_TRUE; 2183 mat->assembled = PETSC_FALSE; 2184 } 2185 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2186 if (mat->ops->setvalueslocal) { 2187 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2188 } else { 2189 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2190 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2191 irowm = buf; icolm = buf+nrow; 2192 } else { 2193 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2194 irowm = bufr; icolm = bufc; 2195 } 2196 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2197 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2198 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2199 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2200 } 2201 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2202 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2203 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2204 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2205 } 2206 #endif 2207 PetscFunctionReturn(0); 2208 } 2209 2210 /*@C 2211 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2212 using a local ordering of the nodes a block at a time. 2213 2214 Not Collective 2215 2216 Input Parameters: 2217 + x - the matrix 2218 . nrow, irow - number of rows and their local indices 2219 . ncol, icol - number of columns and their local indices 2220 . y - a logically two-dimensional array of values 2221 - addv - either INSERT_VALUES or ADD_VALUES, where 2222 ADD_VALUES adds values to any existing entries, and 2223 INSERT_VALUES replaces existing entries with new values 2224 2225 Notes: 2226 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2227 MatSetUp() before using this routine 2228 2229 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2230 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2231 2232 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2233 options cannot be mixed without intervening calls to the assembly 2234 routines. 2235 2236 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2237 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2238 2239 Level: intermediate 2240 2241 Developer Notes: 2242 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2243 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2244 2245 Concepts: matrices^putting blocked values in with local numbering 2246 2247 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2248 MatSetValuesLocal(), MatSetValuesBlocked() 2249 @*/ 2250 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2251 { 2252 PetscErrorCode ierr; 2253 2254 PetscFunctionBeginHot; 2255 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2256 PetscValidType(mat,1); 2257 MatCheckPreallocated(mat,1); 2258 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2259 PetscValidIntPointer(irow,3); 2260 PetscValidIntPointer(icol,5); 2261 PetscValidScalarPointer(y,6); 2262 if (mat->insertmode == NOT_SET_VALUES) { 2263 mat->insertmode = addv; 2264 } 2265 #if defined(PETSC_USE_DEBUG) 2266 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2267 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2268 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); 2269 #endif 2270 2271 if (mat->assembled) { 2272 mat->was_assembled = PETSC_TRUE; 2273 mat->assembled = PETSC_FALSE; 2274 } 2275 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2276 if (mat->ops->setvaluesblockedlocal) { 2277 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2278 } else { 2279 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2280 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2281 irowm = buf; icolm = buf + nrow; 2282 } else { 2283 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2284 irowm = bufr; icolm = bufc; 2285 } 2286 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2287 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2288 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2289 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2290 } 2291 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2292 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2293 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2294 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2295 } 2296 #endif 2297 PetscFunctionReturn(0); 2298 } 2299 2300 /*@ 2301 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2302 2303 Collective on Mat and Vec 2304 2305 Input Parameters: 2306 + mat - the matrix 2307 - x - the vector to be multiplied 2308 2309 Output Parameters: 2310 . y - the result 2311 2312 Notes: 2313 The vectors x and y cannot be the same. I.e., one cannot 2314 call MatMult(A,y,y). 2315 2316 Level: developer 2317 2318 Concepts: matrix-vector product 2319 2320 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2321 @*/ 2322 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2323 { 2324 PetscErrorCode ierr; 2325 2326 PetscFunctionBegin; 2327 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2328 PetscValidType(mat,1); 2329 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2330 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2331 2332 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2333 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2334 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2335 MatCheckPreallocated(mat,1); 2336 2337 if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2338 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2339 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2340 PetscFunctionReturn(0); 2341 } 2342 2343 /* --------------------------------------------------------*/ 2344 /*@ 2345 MatMult - Computes the matrix-vector product, y = Ax. 2346 2347 Neighbor-wise Collective on Mat and Vec 2348 2349 Input Parameters: 2350 + mat - the matrix 2351 - x - the vector to be multiplied 2352 2353 Output Parameters: 2354 . y - the result 2355 2356 Notes: 2357 The vectors x and y cannot be the same. I.e., one cannot 2358 call MatMult(A,y,y). 2359 2360 Level: beginner 2361 2362 Concepts: matrix-vector product 2363 2364 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2365 @*/ 2366 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2367 { 2368 PetscErrorCode ierr; 2369 2370 PetscFunctionBegin; 2371 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2372 PetscValidType(mat,1); 2373 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2374 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2375 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2376 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2377 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2378 #if !defined(PETSC_HAVE_CONSTRAINTS) 2379 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); 2380 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); 2381 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); 2382 #endif 2383 VecLocked(y,3); 2384 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2385 MatCheckPreallocated(mat,1); 2386 2387 ierr = VecLockPush(x);CHKERRQ(ierr); 2388 if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2389 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2390 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2391 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2392 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2393 ierr = VecLockPop(x);CHKERRQ(ierr); 2394 PetscFunctionReturn(0); 2395 } 2396 2397 /*@ 2398 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2399 2400 Neighbor-wise Collective on Mat and Vec 2401 2402 Input Parameters: 2403 + mat - the matrix 2404 - x - the vector to be multiplied 2405 2406 Output Parameters: 2407 . y - the result 2408 2409 Notes: 2410 The vectors x and y cannot be the same. I.e., one cannot 2411 call MatMultTranspose(A,y,y). 2412 2413 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2414 use MatMultHermitianTranspose() 2415 2416 Level: beginner 2417 2418 Concepts: matrix vector product^transpose 2419 2420 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2421 @*/ 2422 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2423 { 2424 PetscErrorCode ierr; 2425 2426 PetscFunctionBegin; 2427 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2428 PetscValidType(mat,1); 2429 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2430 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2431 2432 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2433 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2434 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2435 #if !defined(PETSC_HAVE_CONSTRAINTS) 2436 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); 2437 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); 2438 #endif 2439 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2440 MatCheckPreallocated(mat,1); 2441 2442 if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined"); 2443 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2444 ierr = VecLockPush(x);CHKERRQ(ierr); 2445 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2446 ierr = VecLockPop(x);CHKERRQ(ierr); 2447 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2448 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2449 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2450 PetscFunctionReturn(0); 2451 } 2452 2453 /*@ 2454 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2455 2456 Neighbor-wise Collective on Mat and Vec 2457 2458 Input Parameters: 2459 + mat - the matrix 2460 - x - the vector to be multilplied 2461 2462 Output Parameters: 2463 . y - the result 2464 2465 Notes: 2466 The vectors x and y cannot be the same. I.e., one cannot 2467 call MatMultHermitianTranspose(A,y,y). 2468 2469 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2470 2471 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2472 2473 Level: beginner 2474 2475 Concepts: matrix vector product^transpose 2476 2477 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2478 @*/ 2479 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2480 { 2481 PetscErrorCode ierr; 2482 Vec w; 2483 2484 PetscFunctionBegin; 2485 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2486 PetscValidType(mat,1); 2487 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2488 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2489 2490 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2491 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2492 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2493 #if !defined(PETSC_HAVE_CONSTRAINTS) 2494 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); 2495 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); 2496 #endif 2497 MatCheckPreallocated(mat,1); 2498 2499 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2500 if (mat->ops->multhermitiantranspose) { 2501 ierr = VecLockPush(x);CHKERRQ(ierr); 2502 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2503 ierr = VecLockPop(x);CHKERRQ(ierr); 2504 } else { 2505 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2506 ierr = VecCopy(x,w);CHKERRQ(ierr); 2507 ierr = VecConjugate(w);CHKERRQ(ierr); 2508 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2509 ierr = VecDestroy(&w);CHKERRQ(ierr); 2510 ierr = VecConjugate(y);CHKERRQ(ierr); 2511 } 2512 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2513 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2514 PetscFunctionReturn(0); 2515 } 2516 2517 /*@ 2518 MatMultAdd - Computes v3 = v2 + A * v1. 2519 2520 Neighbor-wise Collective on Mat and Vec 2521 2522 Input Parameters: 2523 + mat - the matrix 2524 - v1, v2 - the vectors 2525 2526 Output Parameters: 2527 . v3 - the result 2528 2529 Notes: 2530 The vectors v1 and v3 cannot be the same. I.e., one cannot 2531 call MatMultAdd(A,v1,v2,v1). 2532 2533 Level: beginner 2534 2535 Concepts: matrix vector product^addition 2536 2537 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2538 @*/ 2539 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2540 { 2541 PetscErrorCode ierr; 2542 2543 PetscFunctionBegin; 2544 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2545 PetscValidType(mat,1); 2546 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2547 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2548 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2549 2550 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2551 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2552 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); 2553 /* 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); 2554 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); */ 2555 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); 2556 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); 2557 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2558 MatCheckPreallocated(mat,1); 2559 2560 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2561 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2562 ierr = VecLockPush(v1);CHKERRQ(ierr); 2563 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2564 ierr = VecLockPop(v1);CHKERRQ(ierr); 2565 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2566 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2567 PetscFunctionReturn(0); 2568 } 2569 2570 /*@ 2571 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2572 2573 Neighbor-wise Collective on Mat and Vec 2574 2575 Input Parameters: 2576 + mat - the matrix 2577 - v1, v2 - the vectors 2578 2579 Output Parameters: 2580 . v3 - the result 2581 2582 Notes: 2583 The vectors v1 and v3 cannot be the same. I.e., one cannot 2584 call MatMultTransposeAdd(A,v1,v2,v1). 2585 2586 Level: beginner 2587 2588 Concepts: matrix vector product^transpose and addition 2589 2590 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2591 @*/ 2592 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2593 { 2594 PetscErrorCode ierr; 2595 2596 PetscFunctionBegin; 2597 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2598 PetscValidType(mat,1); 2599 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2600 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2601 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2602 2603 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2604 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2605 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2606 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2607 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); 2608 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); 2609 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); 2610 MatCheckPreallocated(mat,1); 2611 2612 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2613 ierr = VecLockPush(v1);CHKERRQ(ierr); 2614 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2615 ierr = VecLockPop(v1);CHKERRQ(ierr); 2616 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2617 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2618 PetscFunctionReturn(0); 2619 } 2620 2621 /*@ 2622 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2623 2624 Neighbor-wise Collective on Mat and Vec 2625 2626 Input Parameters: 2627 + mat - the matrix 2628 - v1, v2 - the vectors 2629 2630 Output Parameters: 2631 . v3 - the result 2632 2633 Notes: 2634 The vectors v1 and v3 cannot be the same. I.e., one cannot 2635 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2636 2637 Level: beginner 2638 2639 Concepts: matrix vector product^transpose and addition 2640 2641 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2642 @*/ 2643 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2644 { 2645 PetscErrorCode ierr; 2646 2647 PetscFunctionBegin; 2648 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2649 PetscValidType(mat,1); 2650 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2651 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2652 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2653 2654 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2655 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2656 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2657 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); 2658 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); 2659 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); 2660 MatCheckPreallocated(mat,1); 2661 2662 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2663 ierr = VecLockPush(v1);CHKERRQ(ierr); 2664 if (mat->ops->multhermitiantransposeadd) { 2665 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2666 } else { 2667 Vec w,z; 2668 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2669 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2670 ierr = VecConjugate(w);CHKERRQ(ierr); 2671 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2672 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2673 ierr = VecDestroy(&w);CHKERRQ(ierr); 2674 ierr = VecConjugate(z);CHKERRQ(ierr); 2675 if (v2 != v3) { 2676 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2677 } else { 2678 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2679 } 2680 ierr = VecDestroy(&z);CHKERRQ(ierr); 2681 } 2682 ierr = VecLockPop(v1);CHKERRQ(ierr); 2683 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2684 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2685 PetscFunctionReturn(0); 2686 } 2687 2688 /*@ 2689 MatMultConstrained - The inner multiplication routine for a 2690 constrained matrix P^T A P. 2691 2692 Neighbor-wise Collective on Mat and Vec 2693 2694 Input Parameters: 2695 + mat - the matrix 2696 - x - the vector to be multilplied 2697 2698 Output Parameters: 2699 . y - the result 2700 2701 Notes: 2702 The vectors x and y cannot be the same. I.e., one cannot 2703 call MatMult(A,y,y). 2704 2705 Level: beginner 2706 2707 .keywords: matrix, multiply, matrix-vector product, constraint 2708 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2709 @*/ 2710 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2711 { 2712 PetscErrorCode ierr; 2713 2714 PetscFunctionBegin; 2715 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2716 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2717 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2718 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2719 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2720 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2721 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); 2722 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); 2723 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); 2724 2725 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2726 ierr = VecLockPush(x);CHKERRQ(ierr); 2727 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2728 ierr = VecLockPop(x);CHKERRQ(ierr); 2729 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2730 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2731 PetscFunctionReturn(0); 2732 } 2733 2734 /*@ 2735 MatMultTransposeConstrained - The inner multiplication routine for a 2736 constrained matrix P^T A^T P. 2737 2738 Neighbor-wise Collective on Mat and Vec 2739 2740 Input Parameters: 2741 + mat - the matrix 2742 - x - the vector to be multilplied 2743 2744 Output Parameters: 2745 . y - the result 2746 2747 Notes: 2748 The vectors x and y cannot be the same. I.e., one cannot 2749 call MatMult(A,y,y). 2750 2751 Level: beginner 2752 2753 .keywords: matrix, multiply, matrix-vector product, constraint 2754 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2755 @*/ 2756 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2757 { 2758 PetscErrorCode ierr; 2759 2760 PetscFunctionBegin; 2761 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2762 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2763 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2764 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2765 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2766 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2767 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); 2768 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); 2769 2770 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2771 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2772 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2773 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2774 PetscFunctionReturn(0); 2775 } 2776 2777 /*@C 2778 MatGetFactorType - gets the type of factorization it is 2779 2780 Not Collective 2781 2782 Input Parameters: 2783 . mat - the matrix 2784 2785 Output Parameters: 2786 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2787 2788 Level: intermediate 2789 2790 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType() 2791 @*/ 2792 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2793 { 2794 PetscFunctionBegin; 2795 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2796 PetscValidType(mat,1); 2797 PetscValidPointer(t,2); 2798 *t = mat->factortype; 2799 PetscFunctionReturn(0); 2800 } 2801 2802 /*@C 2803 MatSetFactorType - sets the type of factorization it is 2804 2805 Logically Collective on Mat 2806 2807 Input Parameters: 2808 + mat - the matrix 2809 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2810 2811 Level: intermediate 2812 2813 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2814 @*/ 2815 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2816 { 2817 PetscFunctionBegin; 2818 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2819 PetscValidType(mat,1); 2820 mat->factortype = t; 2821 PetscFunctionReturn(0); 2822 } 2823 2824 /* ------------------------------------------------------------*/ 2825 /*@C 2826 MatGetInfo - Returns information about matrix storage (number of 2827 nonzeros, memory, etc.). 2828 2829 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2830 2831 Input Parameters: 2832 . mat - the matrix 2833 2834 Output Parameters: 2835 + flag - flag indicating the type of parameters to be returned 2836 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2837 MAT_GLOBAL_SUM - sum over all processors) 2838 - info - matrix information context 2839 2840 Notes: 2841 The MatInfo context contains a variety of matrix data, including 2842 number of nonzeros allocated and used, number of mallocs during 2843 matrix assembly, etc. Additional information for factored matrices 2844 is provided (such as the fill ratio, number of mallocs during 2845 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2846 when using the runtime options 2847 $ -info -mat_view ::ascii_info 2848 2849 Example for C/C++ Users: 2850 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2851 data within the MatInfo context. For example, 2852 .vb 2853 MatInfo info; 2854 Mat A; 2855 double mal, nz_a, nz_u; 2856 2857 MatGetInfo(A,MAT_LOCAL,&info); 2858 mal = info.mallocs; 2859 nz_a = info.nz_allocated; 2860 .ve 2861 2862 Example for Fortran Users: 2863 Fortran users should declare info as a double precision 2864 array of dimension MAT_INFO_SIZE, and then extract the parameters 2865 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2866 a complete list of parameter names. 2867 .vb 2868 double precision info(MAT_INFO_SIZE) 2869 double precision mal, nz_a 2870 Mat A 2871 integer ierr 2872 2873 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2874 mal = info(MAT_INFO_MALLOCS) 2875 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2876 .ve 2877 2878 Level: intermediate 2879 2880 Concepts: matrices^getting information on 2881 2882 Developer Note: fortran interface is not autogenerated as the f90 2883 interface defintion cannot be generated correctly [due to MatInfo] 2884 2885 .seealso: MatStashGetInfo() 2886 2887 @*/ 2888 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2889 { 2890 PetscErrorCode ierr; 2891 2892 PetscFunctionBegin; 2893 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2894 PetscValidType(mat,1); 2895 PetscValidPointer(info,3); 2896 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2897 MatCheckPreallocated(mat,1); 2898 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2899 PetscFunctionReturn(0); 2900 } 2901 2902 /* 2903 This is used by external packages where it is not easy to get the info from the actual 2904 matrix factorization. 2905 */ 2906 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2907 { 2908 PetscErrorCode ierr; 2909 2910 PetscFunctionBegin; 2911 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2912 PetscFunctionReturn(0); 2913 } 2914 2915 /* ----------------------------------------------------------*/ 2916 2917 /*@C 2918 MatLUFactor - Performs in-place LU factorization of matrix. 2919 2920 Collective on Mat 2921 2922 Input Parameters: 2923 + mat - the matrix 2924 . row - row permutation 2925 . col - column permutation 2926 - info - options for factorization, includes 2927 $ fill - expected fill as ratio of original fill. 2928 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2929 $ Run with the option -info to determine an optimal value to use 2930 2931 Notes: 2932 Most users should employ the simplified KSP interface for linear solvers 2933 instead of working directly with matrix algebra routines such as this. 2934 See, e.g., KSPCreate(). 2935 2936 This changes the state of the matrix to a factored matrix; it cannot be used 2937 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2938 2939 Level: developer 2940 2941 Concepts: matrices^LU factorization 2942 2943 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2944 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2945 2946 Developer Note: fortran interface is not autogenerated as the f90 2947 interface defintion cannot be generated correctly [due to MatFactorInfo] 2948 2949 @*/ 2950 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2951 { 2952 PetscErrorCode ierr; 2953 MatFactorInfo tinfo; 2954 2955 PetscFunctionBegin; 2956 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2957 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2958 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2959 if (info) PetscValidPointer(info,4); 2960 PetscValidType(mat,1); 2961 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2962 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2963 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2964 MatCheckPreallocated(mat,1); 2965 if (!info) { 2966 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2967 info = &tinfo; 2968 } 2969 2970 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2971 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2972 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2973 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2974 PetscFunctionReturn(0); 2975 } 2976 2977 /*@C 2978 MatILUFactor - Performs in-place ILU factorization of matrix. 2979 2980 Collective on Mat 2981 2982 Input Parameters: 2983 + mat - the matrix 2984 . row - row permutation 2985 . col - column permutation 2986 - info - structure containing 2987 $ levels - number of levels of fill. 2988 $ expected fill - as ratio of original fill. 2989 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2990 missing diagonal entries) 2991 2992 Notes: 2993 Probably really in-place only when level of fill is zero, otherwise allocates 2994 new space to store factored matrix and deletes previous memory. 2995 2996 Most users should employ the simplified KSP interface for linear solvers 2997 instead of working directly with matrix algebra routines such as this. 2998 See, e.g., KSPCreate(). 2999 3000 Level: developer 3001 3002 Concepts: matrices^ILU factorization 3003 3004 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 3005 3006 Developer Note: fortran interface is not autogenerated as the f90 3007 interface defintion cannot be generated correctly [due to MatFactorInfo] 3008 3009 @*/ 3010 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3011 { 3012 PetscErrorCode ierr; 3013 3014 PetscFunctionBegin; 3015 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3016 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3017 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3018 PetscValidPointer(info,4); 3019 PetscValidType(mat,1); 3020 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3021 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3022 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3023 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3024 MatCheckPreallocated(mat,1); 3025 3026 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 3027 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 3028 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 3029 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3030 PetscFunctionReturn(0); 3031 } 3032 3033 /*@C 3034 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3035 Call this routine before calling MatLUFactorNumeric(). 3036 3037 Collective on Mat 3038 3039 Input Parameters: 3040 + fact - the factor matrix obtained with MatGetFactor() 3041 . mat - the matrix 3042 . row, col - row and column permutations 3043 - info - options for factorization, includes 3044 $ fill - expected fill as ratio of original fill. 3045 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3046 $ Run with the option -info to determine an optimal value to use 3047 3048 3049 Notes: 3050 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3051 3052 Most users should employ the simplified KSP interface for linear solvers 3053 instead of working directly with matrix algebra routines such as this. 3054 See, e.g., KSPCreate(). 3055 3056 Level: developer 3057 3058 Concepts: matrices^LU symbolic factorization 3059 3060 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 3061 3062 Developer Note: fortran interface is not autogenerated as the f90 3063 interface defintion cannot be generated correctly [due to MatFactorInfo] 3064 3065 @*/ 3066 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3067 { 3068 PetscErrorCode ierr; 3069 3070 PetscFunctionBegin; 3071 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3072 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3073 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3074 if (info) PetscValidPointer(info,4); 3075 PetscValidType(mat,1); 3076 PetscValidPointer(fact,5); 3077 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3078 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3079 if (!(fact)->ops->lufactorsymbolic) { 3080 MatSolverType spackage; 3081 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3082 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 3083 } 3084 MatCheckPreallocated(mat,2); 3085 3086 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3087 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3088 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3089 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3090 PetscFunctionReturn(0); 3091 } 3092 3093 /*@C 3094 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3095 Call this routine after first calling MatLUFactorSymbolic(). 3096 3097 Collective on Mat 3098 3099 Input Parameters: 3100 + fact - the factor matrix obtained with MatGetFactor() 3101 . mat - the matrix 3102 - info - options for factorization 3103 3104 Notes: 3105 See MatLUFactor() for in-place factorization. See 3106 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3107 3108 Most users should employ the simplified KSP interface for linear solvers 3109 instead of working directly with matrix algebra routines such as this. 3110 See, e.g., KSPCreate(). 3111 3112 Level: developer 3113 3114 Concepts: matrices^LU numeric factorization 3115 3116 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3117 3118 Developer Note: fortran interface is not autogenerated as the f90 3119 interface defintion cannot be generated correctly [due to MatFactorInfo] 3120 3121 @*/ 3122 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3123 { 3124 PetscErrorCode ierr; 3125 3126 PetscFunctionBegin; 3127 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3128 PetscValidType(mat,1); 3129 PetscValidPointer(fact,2); 3130 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3131 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3132 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); 3133 3134 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3135 MatCheckPreallocated(mat,2); 3136 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3137 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3138 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3139 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3140 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3141 PetscFunctionReturn(0); 3142 } 3143 3144 /*@C 3145 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3146 symmetric matrix. 3147 3148 Collective on Mat 3149 3150 Input Parameters: 3151 + mat - the matrix 3152 . perm - row and column permutations 3153 - f - expected fill as ratio of original fill 3154 3155 Notes: 3156 See MatLUFactor() for the nonsymmetric case. See also 3157 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3158 3159 Most users should employ the simplified KSP interface for linear solvers 3160 instead of working directly with matrix algebra routines such as this. 3161 See, e.g., KSPCreate(). 3162 3163 Level: developer 3164 3165 Concepts: matrices^Cholesky factorization 3166 3167 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3168 MatGetOrdering() 3169 3170 Developer Note: fortran interface is not autogenerated as the f90 3171 interface defintion cannot be generated correctly [due to MatFactorInfo] 3172 3173 @*/ 3174 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3175 { 3176 PetscErrorCode ierr; 3177 3178 PetscFunctionBegin; 3179 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3180 PetscValidType(mat,1); 3181 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3182 if (info) PetscValidPointer(info,3); 3183 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3184 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3185 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3186 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); 3187 MatCheckPreallocated(mat,1); 3188 3189 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3190 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3191 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3192 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3193 PetscFunctionReturn(0); 3194 } 3195 3196 /*@C 3197 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3198 of a symmetric matrix. 3199 3200 Collective on Mat 3201 3202 Input Parameters: 3203 + fact - the factor matrix obtained with MatGetFactor() 3204 . mat - the matrix 3205 . perm - row and column permutations 3206 - info - options for factorization, includes 3207 $ fill - expected fill as ratio of original fill. 3208 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3209 $ Run with the option -info to determine an optimal value to use 3210 3211 Notes: 3212 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3213 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3214 3215 Most users should employ the simplified KSP interface for linear solvers 3216 instead of working directly with matrix algebra routines such as this. 3217 See, e.g., KSPCreate(). 3218 3219 Level: developer 3220 3221 Concepts: matrices^Cholesky symbolic factorization 3222 3223 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3224 MatGetOrdering() 3225 3226 Developer Note: fortran interface is not autogenerated as the f90 3227 interface defintion cannot be generated correctly [due to MatFactorInfo] 3228 3229 @*/ 3230 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3231 { 3232 PetscErrorCode ierr; 3233 3234 PetscFunctionBegin; 3235 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3236 PetscValidType(mat,1); 3237 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3238 if (info) PetscValidPointer(info,3); 3239 PetscValidPointer(fact,4); 3240 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3241 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3242 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3243 if (!(fact)->ops->choleskyfactorsymbolic) { 3244 MatSolverType spackage; 3245 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3246 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3247 } 3248 MatCheckPreallocated(mat,2); 3249 3250 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3251 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3252 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3253 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3254 PetscFunctionReturn(0); 3255 } 3256 3257 /*@C 3258 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3259 of a symmetric matrix. Call this routine after first calling 3260 MatCholeskyFactorSymbolic(). 3261 3262 Collective on Mat 3263 3264 Input Parameters: 3265 + fact - the factor matrix obtained with MatGetFactor() 3266 . mat - the initial matrix 3267 . info - options for factorization 3268 - fact - the symbolic factor of mat 3269 3270 3271 Notes: 3272 Most users should employ the simplified KSP interface for linear solvers 3273 instead of working directly with matrix algebra routines such as this. 3274 See, e.g., KSPCreate(). 3275 3276 Level: developer 3277 3278 Concepts: matrices^Cholesky numeric factorization 3279 3280 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3281 3282 Developer Note: fortran interface is not autogenerated as the f90 3283 interface defintion cannot be generated correctly [due to MatFactorInfo] 3284 3285 @*/ 3286 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3287 { 3288 PetscErrorCode ierr; 3289 3290 PetscFunctionBegin; 3291 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3292 PetscValidType(mat,1); 3293 PetscValidPointer(fact,2); 3294 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3295 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3296 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3297 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); 3298 MatCheckPreallocated(mat,2); 3299 3300 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3301 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3302 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3303 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3304 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3305 PetscFunctionReturn(0); 3306 } 3307 3308 /* ----------------------------------------------------------------*/ 3309 /*@ 3310 MatSolve - Solves A x = b, given a factored matrix. 3311 3312 Neighbor-wise Collective on Mat and Vec 3313 3314 Input Parameters: 3315 + mat - the factored matrix 3316 - b - the right-hand-side vector 3317 3318 Output Parameter: 3319 . x - the result vector 3320 3321 Notes: 3322 The vectors b and x cannot be the same. I.e., one cannot 3323 call MatSolve(A,x,x). 3324 3325 Notes: 3326 Most users should employ the simplified KSP interface for linear solvers 3327 instead of working directly with matrix algebra routines such as this. 3328 See, e.g., KSPCreate(). 3329 3330 Level: developer 3331 3332 Concepts: matrices^triangular solves 3333 3334 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3335 @*/ 3336 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3337 { 3338 PetscErrorCode ierr; 3339 3340 PetscFunctionBegin; 3341 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3342 PetscValidType(mat,1); 3343 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3344 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3345 PetscCheckSameComm(mat,1,b,2); 3346 PetscCheckSameComm(mat,1,x,3); 3347 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3348 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); 3349 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); 3350 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); 3351 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3352 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3353 MatCheckPreallocated(mat,1); 3354 3355 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3356 if (mat->factorerrortype) { 3357 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3358 ierr = VecSetInf(x);CHKERRQ(ierr); 3359 } else { 3360 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3361 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3362 } 3363 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3364 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3365 PetscFunctionReturn(0); 3366 } 3367 3368 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans) 3369 { 3370 PetscErrorCode ierr; 3371 Vec b,x; 3372 PetscInt m,N,i; 3373 PetscScalar *bb,*xx; 3374 PetscBool flg; 3375 3376 PetscFunctionBegin; 3377 ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3378 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 3379 ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3380 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); 3381 3382 ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr); 3383 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3384 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3385 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3386 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3387 for (i=0; i<N; i++) { 3388 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3389 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3390 if (trans) { 3391 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3392 } else { 3393 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3394 } 3395 ierr = VecResetArray(x);CHKERRQ(ierr); 3396 ierr = VecResetArray(b);CHKERRQ(ierr); 3397 } 3398 ierr = VecDestroy(&b);CHKERRQ(ierr); 3399 ierr = VecDestroy(&x);CHKERRQ(ierr); 3400 ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr); 3401 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3402 PetscFunctionReturn(0); 3403 } 3404 3405 /*@ 3406 MatMatSolve - Solves A X = B, given a factored matrix. 3407 3408 Neighbor-wise Collective on Mat 3409 3410 Input Parameters: 3411 + A - the factored matrix 3412 - B - the right-hand-side matrix (dense matrix) 3413 3414 Output Parameter: 3415 . X - the result matrix (dense matrix) 3416 3417 Notes: 3418 The matrices b and x cannot be the same. I.e., one cannot 3419 call MatMatSolve(A,x,x). 3420 3421 Notes: 3422 Most users should usually employ the simplified KSP interface for linear solvers 3423 instead of working directly with matrix algebra routines such as this. 3424 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3425 at a time. 3426 3427 When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 3428 it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides. 3429 3430 Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B. 3431 3432 Level: developer 3433 3434 Concepts: matrices^triangular solves 3435 3436 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3437 @*/ 3438 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3439 { 3440 PetscErrorCode ierr; 3441 3442 PetscFunctionBegin; 3443 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3444 PetscValidType(A,1); 3445 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3446 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3447 PetscCheckSameComm(A,1,B,2); 3448 PetscCheckSameComm(A,1,X,3); 3449 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3450 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); 3451 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); 3452 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"); 3453 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3454 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3455 MatCheckPreallocated(A,1); 3456 3457 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3458 if (!A->ops->matsolve) { 3459 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3460 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3461 } else { 3462 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3463 } 3464 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3465 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3466 PetscFunctionReturn(0); 3467 } 3468 3469 /*@ 3470 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3471 3472 Neighbor-wise Collective on Mat 3473 3474 Input Parameters: 3475 + A - the factored matrix 3476 - B - the right-hand-side matrix (dense matrix) 3477 3478 Output Parameter: 3479 . X - the result matrix (dense matrix) 3480 3481 Notes: 3482 The matrices B and X cannot be the same. I.e., one cannot 3483 call MatMatSolveTranspose(A,X,X). 3484 3485 Notes: 3486 Most users should usually employ the simplified KSP interface for linear solvers 3487 instead of working directly with matrix algebra routines such as this. 3488 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3489 at a time. 3490 3491 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3492 3493 Level: developer 3494 3495 Concepts: matrices^triangular solves 3496 3497 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3498 @*/ 3499 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3500 { 3501 PetscErrorCode ierr; 3502 3503 PetscFunctionBegin; 3504 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3505 PetscValidType(A,1); 3506 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3507 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3508 PetscCheckSameComm(A,1,B,2); 3509 PetscCheckSameComm(A,1,X,3); 3510 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3511 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); 3512 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); 3513 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); 3514 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"); 3515 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3516 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3517 MatCheckPreallocated(A,1); 3518 3519 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3520 if (!A->ops->matsolvetranspose) { 3521 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3522 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3523 } else { 3524 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3525 } 3526 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3527 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3528 PetscFunctionReturn(0); 3529 } 3530 3531 /*@ 3532 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3533 3534 Neighbor-wise Collective on Mat 3535 3536 Input Parameters: 3537 + A - the factored matrix 3538 - Bt - the transpose of right-hand-side matrix 3539 3540 Output Parameter: 3541 . X - the result matrix (dense matrix) 3542 3543 Notes: 3544 Most users should usually employ the simplified KSP interface for linear solvers 3545 instead of working directly with matrix algebra routines such as this. 3546 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3547 at a time. 3548 3549 For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve(). 3550 3551 Level: developer 3552 3553 Concepts: matrices^triangular solves 3554 3555 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3556 @*/ 3557 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3558 { 3559 PetscErrorCode ierr; 3560 3561 PetscFunctionBegin; 3562 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3563 PetscValidType(A,1); 3564 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3565 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3566 PetscCheckSameComm(A,1,Bt,2); 3567 PetscCheckSameComm(A,1,X,3); 3568 3569 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3570 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); 3571 if (A->rmap->N != Bt->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %D %D",A->rmap->N,Bt->cmap->N); 3572 if (X->cmap->N < Bt->rmap->N) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix"); 3573 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3574 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3575 MatCheckPreallocated(A,1); 3576 3577 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3578 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3579 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3580 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3581 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3582 PetscFunctionReturn(0); 3583 } 3584 3585 /*@ 3586 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3587 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3588 3589 Neighbor-wise Collective on Mat and Vec 3590 3591 Input Parameters: 3592 + mat - the factored matrix 3593 - b - the right-hand-side vector 3594 3595 Output Parameter: 3596 . x - the result vector 3597 3598 Notes: 3599 MatSolve() should be used for most applications, as it performs 3600 a forward solve followed by a backward solve. 3601 3602 The vectors b and x cannot be the same, i.e., one cannot 3603 call MatForwardSolve(A,x,x). 3604 3605 For matrix in seqsbaij format with block size larger than 1, 3606 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3607 MatForwardSolve() solves U^T*D y = b, and 3608 MatBackwardSolve() solves U x = y. 3609 Thus they do not provide a symmetric preconditioner. 3610 3611 Most users should employ the simplified KSP interface for linear solvers 3612 instead of working directly with matrix algebra routines such as this. 3613 See, e.g., KSPCreate(). 3614 3615 Level: developer 3616 3617 Concepts: matrices^forward solves 3618 3619 .seealso: MatSolve(), MatBackwardSolve() 3620 @*/ 3621 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3622 { 3623 PetscErrorCode ierr; 3624 3625 PetscFunctionBegin; 3626 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3627 PetscValidType(mat,1); 3628 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3629 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3630 PetscCheckSameComm(mat,1,b,2); 3631 PetscCheckSameComm(mat,1,x,3); 3632 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3633 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); 3634 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); 3635 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); 3636 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3637 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3638 MatCheckPreallocated(mat,1); 3639 3640 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3641 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3642 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3643 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3644 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3645 PetscFunctionReturn(0); 3646 } 3647 3648 /*@ 3649 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3650 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3651 3652 Neighbor-wise Collective on Mat and Vec 3653 3654 Input Parameters: 3655 + mat - the factored matrix 3656 - b - the right-hand-side vector 3657 3658 Output Parameter: 3659 . x - the result vector 3660 3661 Notes: 3662 MatSolve() should be used for most applications, as it performs 3663 a forward solve followed by a backward solve. 3664 3665 The vectors b and x cannot be the same. I.e., one cannot 3666 call MatBackwardSolve(A,x,x). 3667 3668 For matrix in seqsbaij format with block size larger than 1, 3669 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3670 MatForwardSolve() solves U^T*D y = b, and 3671 MatBackwardSolve() solves U x = y. 3672 Thus they do not provide a symmetric preconditioner. 3673 3674 Most users should employ the simplified KSP interface for linear solvers 3675 instead of working directly with matrix algebra routines such as this. 3676 See, e.g., KSPCreate(). 3677 3678 Level: developer 3679 3680 Concepts: matrices^backward solves 3681 3682 .seealso: MatSolve(), MatForwardSolve() 3683 @*/ 3684 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3685 { 3686 PetscErrorCode ierr; 3687 3688 PetscFunctionBegin; 3689 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3690 PetscValidType(mat,1); 3691 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3692 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3693 PetscCheckSameComm(mat,1,b,2); 3694 PetscCheckSameComm(mat,1,x,3); 3695 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3696 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); 3697 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); 3698 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); 3699 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3700 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3701 MatCheckPreallocated(mat,1); 3702 3703 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3704 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3705 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3706 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3707 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3708 PetscFunctionReturn(0); 3709 } 3710 3711 /*@ 3712 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3713 3714 Neighbor-wise Collective on Mat and Vec 3715 3716 Input Parameters: 3717 + mat - the factored matrix 3718 . b - the right-hand-side vector 3719 - y - the vector to be added to 3720 3721 Output Parameter: 3722 . x - the result vector 3723 3724 Notes: 3725 The vectors b and x cannot be the same. I.e., one cannot 3726 call MatSolveAdd(A,x,y,x). 3727 3728 Most users should employ the simplified KSP interface for linear solvers 3729 instead of working directly with matrix algebra routines such as this. 3730 See, e.g., KSPCreate(). 3731 3732 Level: developer 3733 3734 Concepts: matrices^triangular solves 3735 3736 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3737 @*/ 3738 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3739 { 3740 PetscScalar one = 1.0; 3741 Vec tmp; 3742 PetscErrorCode ierr; 3743 3744 PetscFunctionBegin; 3745 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3746 PetscValidType(mat,1); 3747 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3748 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3749 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3750 PetscCheckSameComm(mat,1,b,2); 3751 PetscCheckSameComm(mat,1,y,2); 3752 PetscCheckSameComm(mat,1,x,3); 3753 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3754 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); 3755 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); 3756 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); 3757 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); 3758 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); 3759 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3760 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3761 MatCheckPreallocated(mat,1); 3762 3763 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3764 if (mat->ops->solveadd) { 3765 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3766 } else { 3767 /* do the solve then the add manually */ 3768 if (x != y) { 3769 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3770 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3771 } else { 3772 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3773 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3774 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3775 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3776 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3777 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3778 } 3779 } 3780 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3781 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3782 PetscFunctionReturn(0); 3783 } 3784 3785 /*@ 3786 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3787 3788 Neighbor-wise Collective on Mat and Vec 3789 3790 Input Parameters: 3791 + mat - the factored matrix 3792 - b - the right-hand-side vector 3793 3794 Output Parameter: 3795 . x - the result vector 3796 3797 Notes: 3798 The vectors b and x cannot be the same. I.e., one cannot 3799 call MatSolveTranspose(A,x,x). 3800 3801 Most users should employ the simplified KSP interface for linear solvers 3802 instead of working directly with matrix algebra routines such as this. 3803 See, e.g., KSPCreate(). 3804 3805 Level: developer 3806 3807 Concepts: matrices^triangular solves 3808 3809 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3810 @*/ 3811 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3812 { 3813 PetscErrorCode ierr; 3814 3815 PetscFunctionBegin; 3816 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3817 PetscValidType(mat,1); 3818 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3819 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3820 PetscCheckSameComm(mat,1,b,2); 3821 PetscCheckSameComm(mat,1,x,3); 3822 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3823 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); 3824 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); 3825 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3826 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3827 MatCheckPreallocated(mat,1); 3828 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3829 if (mat->factorerrortype) { 3830 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3831 ierr = VecSetInf(x);CHKERRQ(ierr); 3832 } else { 3833 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3834 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3835 } 3836 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3837 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3838 PetscFunctionReturn(0); 3839 } 3840 3841 /*@ 3842 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3843 factored matrix. 3844 3845 Neighbor-wise Collective on Mat and Vec 3846 3847 Input Parameters: 3848 + mat - the factored matrix 3849 . b - the right-hand-side vector 3850 - y - the vector to be added to 3851 3852 Output Parameter: 3853 . x - the result vector 3854 3855 Notes: 3856 The vectors b and x cannot be the same. I.e., one cannot 3857 call MatSolveTransposeAdd(A,x,y,x). 3858 3859 Most users should employ the simplified KSP interface for linear solvers 3860 instead of working directly with matrix algebra routines such as this. 3861 See, e.g., KSPCreate(). 3862 3863 Level: developer 3864 3865 Concepts: matrices^triangular solves 3866 3867 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3868 @*/ 3869 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3870 { 3871 PetscScalar one = 1.0; 3872 PetscErrorCode ierr; 3873 Vec tmp; 3874 3875 PetscFunctionBegin; 3876 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3877 PetscValidType(mat,1); 3878 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3879 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3880 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3881 PetscCheckSameComm(mat,1,b,2); 3882 PetscCheckSameComm(mat,1,y,3); 3883 PetscCheckSameComm(mat,1,x,4); 3884 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3885 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); 3886 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); 3887 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); 3888 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); 3889 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3890 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3891 MatCheckPreallocated(mat,1); 3892 3893 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3894 if (mat->ops->solvetransposeadd) { 3895 if (mat->factorerrortype) { 3896 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3897 ierr = VecSetInf(x);CHKERRQ(ierr); 3898 } else { 3899 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3900 } 3901 } else { 3902 /* do the solve then the add manually */ 3903 if (x != y) { 3904 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3905 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3906 } else { 3907 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3908 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3909 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3910 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3911 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3912 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3913 } 3914 } 3915 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3916 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3917 PetscFunctionReturn(0); 3918 } 3919 /* ----------------------------------------------------------------*/ 3920 3921 /*@ 3922 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3923 3924 Neighbor-wise Collective on Mat and Vec 3925 3926 Input Parameters: 3927 + mat - the matrix 3928 . b - the right hand side 3929 . omega - the relaxation factor 3930 . flag - flag indicating the type of SOR (see below) 3931 . shift - diagonal shift 3932 . its - the number of iterations 3933 - lits - the number of local iterations 3934 3935 Output Parameters: 3936 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3937 3938 SOR Flags: 3939 . SOR_FORWARD_SWEEP - forward SOR 3940 . SOR_BACKWARD_SWEEP - backward SOR 3941 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3942 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3943 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3944 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3945 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3946 upper/lower triangular part of matrix to 3947 vector (with omega) 3948 . SOR_ZERO_INITIAL_GUESS - zero initial guess 3949 3950 Notes: 3951 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3952 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3953 on each processor. 3954 3955 Application programmers will not generally use MatSOR() directly, 3956 but instead will employ the KSP/PC interface. 3957 3958 Notes: 3959 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3960 3961 Notes for Advanced Users: 3962 The flags are implemented as bitwise inclusive or operations. 3963 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3964 to specify a zero initial guess for SSOR. 3965 3966 Most users should employ the simplified KSP interface for linear solvers 3967 instead of working directly with matrix algebra routines such as this. 3968 See, e.g., KSPCreate(). 3969 3970 Vectors x and b CANNOT be the same 3971 3972 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3973 3974 Level: developer 3975 3976 Concepts: matrices^relaxation 3977 Concepts: matrices^SOR 3978 Concepts: matrices^Gauss-Seidel 3979 3980 @*/ 3981 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3982 { 3983 PetscErrorCode ierr; 3984 3985 PetscFunctionBegin; 3986 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3987 PetscValidType(mat,1); 3988 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3989 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3990 PetscCheckSameComm(mat,1,b,2); 3991 PetscCheckSameComm(mat,1,x,8); 3992 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3993 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3994 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3995 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); 3996 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); 3997 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); 3998 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 3999 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 4000 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4001 4002 MatCheckPreallocated(mat,1); 4003 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 4004 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 4005 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 4006 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 4007 PetscFunctionReturn(0); 4008 } 4009 4010 /* 4011 Default matrix copy routine. 4012 */ 4013 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4014 { 4015 PetscErrorCode ierr; 4016 PetscInt i,rstart = 0,rend = 0,nz; 4017 const PetscInt *cwork; 4018 const PetscScalar *vwork; 4019 4020 PetscFunctionBegin; 4021 if (B->assembled) { 4022 ierr = MatZeroEntries(B);CHKERRQ(ierr); 4023 } 4024 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 4025 for (i=rstart; i<rend; i++) { 4026 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 4027 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 4028 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 4029 } 4030 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4031 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4032 PetscFunctionReturn(0); 4033 } 4034 4035 /*@ 4036 MatCopy - Copys a matrix to another matrix. 4037 4038 Collective on Mat 4039 4040 Input Parameters: 4041 + A - the matrix 4042 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4043 4044 Output Parameter: 4045 . B - where the copy is put 4046 4047 Notes: 4048 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 4049 same nonzero pattern or the routine will crash. 4050 4051 MatCopy() copies the matrix entries of a matrix to another existing 4052 matrix (after first zeroing the second matrix). A related routine is 4053 MatConvert(), which first creates a new matrix and then copies the data. 4054 4055 Level: intermediate 4056 4057 Concepts: matrices^copying 4058 4059 .seealso: MatConvert(), MatDuplicate() 4060 4061 @*/ 4062 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4063 { 4064 PetscErrorCode ierr; 4065 PetscInt i; 4066 4067 PetscFunctionBegin; 4068 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4069 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4070 PetscValidType(A,1); 4071 PetscValidType(B,2); 4072 PetscCheckSameComm(A,1,B,2); 4073 MatCheckPreallocated(B,2); 4074 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4075 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4076 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); 4077 MatCheckPreallocated(A,1); 4078 if (A == B) PetscFunctionReturn(0); 4079 4080 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4081 if (A->ops->copy) { 4082 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 4083 } else { /* generic conversion */ 4084 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 4085 } 4086 4087 B->stencil.dim = A->stencil.dim; 4088 B->stencil.noc = A->stencil.noc; 4089 for (i=0; i<=A->stencil.dim; i++) { 4090 B->stencil.dims[i] = A->stencil.dims[i]; 4091 B->stencil.starts[i] = A->stencil.starts[i]; 4092 } 4093 4094 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4095 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4096 PetscFunctionReturn(0); 4097 } 4098 4099 /*@C 4100 MatConvert - Converts a matrix to another matrix, either of the same 4101 or different type. 4102 4103 Collective on Mat 4104 4105 Input Parameters: 4106 + mat - the matrix 4107 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4108 same type as the original matrix. 4109 - reuse - denotes if the destination matrix is to be created or reused. 4110 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 4111 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). 4112 4113 Output Parameter: 4114 . M - pointer to place new matrix 4115 4116 Notes: 4117 MatConvert() first creates a new matrix and then copies the data from 4118 the first matrix. A related routine is MatCopy(), which copies the matrix 4119 entries of one matrix to another already existing matrix context. 4120 4121 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4122 the MPI communicator of the generated matrix is always the same as the communicator 4123 of the input matrix. 4124 4125 Level: intermediate 4126 4127 Concepts: matrices^converting between storage formats 4128 4129 .seealso: MatCopy(), MatDuplicate() 4130 @*/ 4131 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4132 { 4133 PetscErrorCode ierr; 4134 PetscBool sametype,issame,flg; 4135 char convname[256],mtype[256]; 4136 Mat B; 4137 4138 PetscFunctionBegin; 4139 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4140 PetscValidType(mat,1); 4141 PetscValidPointer(M,3); 4142 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4143 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4144 MatCheckPreallocated(mat,1); 4145 4146 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4147 if (flg) { 4148 newtype = mtype; 4149 } 4150 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4151 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4152 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4153 if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX"); 4154 4155 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0); 4156 4157 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4158 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4159 } else { 4160 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4161 const char *prefix[3] = {"seq","mpi",""}; 4162 PetscInt i; 4163 /* 4164 Order of precedence: 4165 1) See if a specialized converter is known to the current matrix. 4166 2) See if a specialized converter is known to the desired matrix class. 4167 3) See if a good general converter is registered for the desired class 4168 (as of 6/27/03 only MATMPIADJ falls into this category). 4169 4) See if a good general converter is known for the current matrix. 4170 5) Use a really basic converter. 4171 */ 4172 4173 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4174 for (i=0; i<3; i++) { 4175 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4176 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4177 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4178 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4179 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4180 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4181 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4182 if (conv) goto foundconv; 4183 } 4184 4185 /* 2) See if a specialized converter is known to the desired matrix class. */ 4186 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4187 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4188 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4189 for (i=0; i<3; i++) { 4190 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4191 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4192 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4193 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4194 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4195 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4196 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4197 if (conv) { 4198 ierr = MatDestroy(&B);CHKERRQ(ierr); 4199 goto foundconv; 4200 } 4201 } 4202 4203 /* 3) See if a good general converter is registered for the desired class */ 4204 conv = B->ops->convertfrom; 4205 ierr = MatDestroy(&B);CHKERRQ(ierr); 4206 if (conv) goto foundconv; 4207 4208 /* 4) See if a good general converter is known for the current matrix */ 4209 if (mat->ops->convert) { 4210 conv = mat->ops->convert; 4211 } 4212 if (conv) goto foundconv; 4213 4214 /* 5) Use a really basic converter. */ 4215 conv = MatConvert_Basic; 4216 4217 foundconv: 4218 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4219 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4220 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4221 /* the block sizes must be same if the mappings are copied over */ 4222 (*M)->rmap->bs = mat->rmap->bs; 4223 (*M)->cmap->bs = mat->cmap->bs; 4224 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4225 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4226 (*M)->rmap->mapping = mat->rmap->mapping; 4227 (*M)->cmap->mapping = mat->cmap->mapping; 4228 } 4229 (*M)->stencil.dim = mat->stencil.dim; 4230 (*M)->stencil.noc = mat->stencil.noc; 4231 for (i=0; i<=mat->stencil.dim; i++) { 4232 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4233 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4234 } 4235 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4236 } 4237 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4238 4239 /* Copy Mat options */ 4240 if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);} 4241 if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);} 4242 PetscFunctionReturn(0); 4243 } 4244 4245 /*@C 4246 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4247 4248 Not Collective 4249 4250 Input Parameter: 4251 . mat - the matrix, must be a factored matrix 4252 4253 Output Parameter: 4254 . type - the string name of the package (do not free this string) 4255 4256 Notes: 4257 In Fortran you pass in a empty string and the package name will be copied into it. 4258 (Make sure the string is long enough) 4259 4260 Level: intermediate 4261 4262 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4263 @*/ 4264 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4265 { 4266 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4267 4268 PetscFunctionBegin; 4269 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4270 PetscValidType(mat,1); 4271 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4272 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4273 if (!conv) { 4274 *type = MATSOLVERPETSC; 4275 } else { 4276 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4277 } 4278 PetscFunctionReturn(0); 4279 } 4280 4281 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4282 struct _MatSolverTypeForSpecifcType { 4283 MatType mtype; 4284 PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*); 4285 MatSolverTypeForSpecifcType next; 4286 }; 4287 4288 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4289 struct _MatSolverTypeHolder { 4290 char *name; 4291 MatSolverTypeForSpecifcType handlers; 4292 MatSolverTypeHolder next; 4293 }; 4294 4295 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4296 4297 /*@C 4298 MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type 4299 4300 Input Parameters: 4301 + package - name of the package, for example petsc or superlu 4302 . mtype - the matrix type that works with this package 4303 . ftype - the type of factorization supported by the package 4304 - getfactor - routine that will create the factored matrix ready to be used 4305 4306 Level: intermediate 4307 4308 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4309 @*/ 4310 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*)) 4311 { 4312 PetscErrorCode ierr; 4313 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4314 PetscBool flg; 4315 MatSolverTypeForSpecifcType inext,iprev = NULL; 4316 4317 PetscFunctionBegin; 4318 ierr = MatInitializePackage();CHKERRQ(ierr); 4319 if (!next) { 4320 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4321 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4322 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4323 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4324 MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor; 4325 PetscFunctionReturn(0); 4326 } 4327 while (next) { 4328 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4329 if (flg) { 4330 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4331 inext = next->handlers; 4332 while (inext) { 4333 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4334 if (flg) { 4335 inext->getfactor[(int)ftype-1] = getfactor; 4336 PetscFunctionReturn(0); 4337 } 4338 iprev = inext; 4339 inext = inext->next; 4340 } 4341 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4342 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4343 iprev->next->getfactor[(int)ftype-1] = getfactor; 4344 PetscFunctionReturn(0); 4345 } 4346 prev = next; 4347 next = next->next; 4348 } 4349 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4350 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4351 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4352 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4353 prev->next->handlers->getfactor[(int)ftype-1] = getfactor; 4354 PetscFunctionReturn(0); 4355 } 4356 4357 /*@C 4358 MatSolvePackageGet - Get's the function that creates the factor matrix if it exist 4359 4360 Input Parameters: 4361 + package - name of the package, for example petsc or superlu 4362 . ftype - the type of factorization supported by the package 4363 - mtype - the matrix type that works with this package 4364 4365 Output Parameters: 4366 + foundpackage - PETSC_TRUE if the package was registered 4367 . foundmtype - PETSC_TRUE if the package supports the requested mtype 4368 - getfactor - routine that will create the factored matrix ready to be used or NULL if not found 4369 4370 Level: intermediate 4371 4372 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4373 @*/ 4374 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*)) 4375 { 4376 PetscErrorCode ierr; 4377 MatSolverTypeHolder next = MatSolverTypeHolders; 4378 PetscBool flg; 4379 MatSolverTypeForSpecifcType inext; 4380 4381 PetscFunctionBegin; 4382 if (foundpackage) *foundpackage = PETSC_FALSE; 4383 if (foundmtype) *foundmtype = PETSC_FALSE; 4384 if (getfactor) *getfactor = NULL; 4385 4386 if (package) { 4387 while (next) { 4388 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4389 if (flg) { 4390 if (foundpackage) *foundpackage = PETSC_TRUE; 4391 inext = next->handlers; 4392 while (inext) { 4393 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4394 if (flg) { 4395 if (foundmtype) *foundmtype = PETSC_TRUE; 4396 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4397 PetscFunctionReturn(0); 4398 } 4399 inext = inext->next; 4400 } 4401 } 4402 next = next->next; 4403 } 4404 } else { 4405 while (next) { 4406 inext = next->handlers; 4407 while (inext) { 4408 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4409 if (flg && inext->getfactor[(int)ftype-1]) { 4410 if (foundpackage) *foundpackage = PETSC_TRUE; 4411 if (foundmtype) *foundmtype = PETSC_TRUE; 4412 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4413 PetscFunctionReturn(0); 4414 } 4415 inext = inext->next; 4416 } 4417 next = next->next; 4418 } 4419 } 4420 PetscFunctionReturn(0); 4421 } 4422 4423 PetscErrorCode MatSolverTypeDestroy(void) 4424 { 4425 PetscErrorCode ierr; 4426 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4427 MatSolverTypeForSpecifcType inext,iprev; 4428 4429 PetscFunctionBegin; 4430 while (next) { 4431 ierr = PetscFree(next->name);CHKERRQ(ierr); 4432 inext = next->handlers; 4433 while (inext) { 4434 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4435 iprev = inext; 4436 inext = inext->next; 4437 ierr = PetscFree(iprev);CHKERRQ(ierr); 4438 } 4439 prev = next; 4440 next = next->next; 4441 ierr = PetscFree(prev);CHKERRQ(ierr); 4442 } 4443 MatSolverTypeHolders = NULL; 4444 PetscFunctionReturn(0); 4445 } 4446 4447 /*@C 4448 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4449 4450 Collective on Mat 4451 4452 Input Parameters: 4453 + mat - the matrix 4454 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4455 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4456 4457 Output Parameters: 4458 . f - the factor matrix used with MatXXFactorSymbolic() calls 4459 4460 Notes: 4461 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4462 such as pastix, superlu, mumps etc. 4463 4464 PETSc must have been ./configure to use the external solver, using the option --download-package 4465 4466 Level: intermediate 4467 4468 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4469 @*/ 4470 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4471 { 4472 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4473 PetscBool foundpackage,foundmtype; 4474 4475 PetscFunctionBegin; 4476 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4477 PetscValidType(mat,1); 4478 4479 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4480 MatCheckPreallocated(mat,1); 4481 4482 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr); 4483 if (!foundpackage) { 4484 if (type) { 4485 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4486 } else { 4487 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>"); 4488 } 4489 } 4490 4491 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4492 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); 4493 4494 #if defined(PETSC_USE_COMPLEX) 4495 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"); 4496 #endif 4497 4498 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4499 PetscFunctionReturn(0); 4500 } 4501 4502 /*@C 4503 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4504 4505 Not Collective 4506 4507 Input Parameters: 4508 + mat - the matrix 4509 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4510 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4511 4512 Output Parameter: 4513 . flg - PETSC_TRUE if the factorization is available 4514 4515 Notes: 4516 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4517 such as pastix, superlu, mumps etc. 4518 4519 PETSc must have been ./configure to use the external solver, using the option --download-package 4520 4521 Level: intermediate 4522 4523 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4524 @*/ 4525 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4526 { 4527 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4528 4529 PetscFunctionBegin; 4530 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4531 PetscValidType(mat,1); 4532 4533 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4534 MatCheckPreallocated(mat,1); 4535 4536 *flg = PETSC_FALSE; 4537 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4538 if (gconv) { 4539 *flg = PETSC_TRUE; 4540 } 4541 PetscFunctionReturn(0); 4542 } 4543 4544 #include <petscdmtypes.h> 4545 4546 /*@ 4547 MatDuplicate - Duplicates a matrix including the non-zero structure. 4548 4549 Collective on Mat 4550 4551 Input Parameters: 4552 + mat - the matrix 4553 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4554 See the manual page for MatDuplicateOption for an explanation of these options. 4555 4556 Output Parameter: 4557 . M - pointer to place new matrix 4558 4559 Level: intermediate 4560 4561 Concepts: matrices^duplicating 4562 4563 Notes: 4564 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4565 4566 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4567 @*/ 4568 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4569 { 4570 PetscErrorCode ierr; 4571 Mat B; 4572 PetscInt i; 4573 DM dm; 4574 void (*viewf)(void); 4575 4576 PetscFunctionBegin; 4577 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4578 PetscValidType(mat,1); 4579 PetscValidPointer(M,3); 4580 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4581 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4582 MatCheckPreallocated(mat,1); 4583 4584 *M = 0; 4585 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4586 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4587 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4588 B = *M; 4589 4590 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4591 if (viewf) { 4592 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4593 } 4594 4595 B->stencil.dim = mat->stencil.dim; 4596 B->stencil.noc = mat->stencil.noc; 4597 for (i=0; i<=mat->stencil.dim; i++) { 4598 B->stencil.dims[i] = mat->stencil.dims[i]; 4599 B->stencil.starts[i] = mat->stencil.starts[i]; 4600 } 4601 4602 B->nooffproczerorows = mat->nooffproczerorows; 4603 B->nooffprocentries = mat->nooffprocentries; 4604 4605 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4606 if (dm) { 4607 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4608 } 4609 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4610 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4611 PetscFunctionReturn(0); 4612 } 4613 4614 /*@ 4615 MatGetDiagonal - Gets the diagonal of a matrix. 4616 4617 Logically Collective on Mat and Vec 4618 4619 Input Parameters: 4620 + mat - the matrix 4621 - v - the vector for storing the diagonal 4622 4623 Output Parameter: 4624 . v - the diagonal of the matrix 4625 4626 Level: intermediate 4627 4628 Note: 4629 Currently only correct in parallel for square matrices. 4630 4631 Concepts: matrices^accessing diagonals 4632 4633 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4634 @*/ 4635 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4636 { 4637 PetscErrorCode ierr; 4638 4639 PetscFunctionBegin; 4640 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4641 PetscValidType(mat,1); 4642 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4643 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4644 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4645 MatCheckPreallocated(mat,1); 4646 4647 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4648 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4649 PetscFunctionReturn(0); 4650 } 4651 4652 /*@C 4653 MatGetRowMin - Gets the minimum value (of the real part) of each 4654 row of the matrix 4655 4656 Logically Collective on Mat and Vec 4657 4658 Input Parameters: 4659 . mat - the matrix 4660 4661 Output Parameter: 4662 + v - the vector for storing the maximums 4663 - idx - the indices of the column found for each row (optional) 4664 4665 Level: intermediate 4666 4667 Notes: 4668 The result of this call are the same as if one converted the matrix to dense format 4669 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4670 4671 This code is only implemented for a couple of matrix formats. 4672 4673 Concepts: matrices^getting row maximums 4674 4675 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4676 MatGetRowMax() 4677 @*/ 4678 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4679 { 4680 PetscErrorCode ierr; 4681 4682 PetscFunctionBegin; 4683 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4684 PetscValidType(mat,1); 4685 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4686 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4687 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4688 MatCheckPreallocated(mat,1); 4689 4690 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4691 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4692 PetscFunctionReturn(0); 4693 } 4694 4695 /*@C 4696 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4697 row of the matrix 4698 4699 Logically Collective on Mat and Vec 4700 4701 Input Parameters: 4702 . mat - the matrix 4703 4704 Output Parameter: 4705 + v - the vector for storing the minimums 4706 - idx - the indices of the column found for each row (or NULL if not needed) 4707 4708 Level: intermediate 4709 4710 Notes: 4711 if a row is completely empty or has only 0.0 values then the idx[] value for that 4712 row is 0 (the first column). 4713 4714 This code is only implemented for a couple of matrix formats. 4715 4716 Concepts: matrices^getting row maximums 4717 4718 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4719 @*/ 4720 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4721 { 4722 PetscErrorCode ierr; 4723 4724 PetscFunctionBegin; 4725 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4726 PetscValidType(mat,1); 4727 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4728 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4729 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4730 MatCheckPreallocated(mat,1); 4731 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4732 4733 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4734 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4735 PetscFunctionReturn(0); 4736 } 4737 4738 /*@C 4739 MatGetRowMax - Gets the maximum value (of the real part) of each 4740 row of the matrix 4741 4742 Logically Collective on Mat and Vec 4743 4744 Input Parameters: 4745 . mat - the matrix 4746 4747 Output Parameter: 4748 + v - the vector for storing the maximums 4749 - idx - the indices of the column found for each row (optional) 4750 4751 Level: intermediate 4752 4753 Notes: 4754 The result of this call are the same as if one converted the matrix to dense format 4755 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4756 4757 This code is only implemented for a couple of matrix formats. 4758 4759 Concepts: matrices^getting row maximums 4760 4761 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4762 @*/ 4763 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4764 { 4765 PetscErrorCode ierr; 4766 4767 PetscFunctionBegin; 4768 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4769 PetscValidType(mat,1); 4770 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4771 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4772 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4773 MatCheckPreallocated(mat,1); 4774 4775 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4776 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4777 PetscFunctionReturn(0); 4778 } 4779 4780 /*@C 4781 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4782 row of the matrix 4783 4784 Logically Collective on Mat and Vec 4785 4786 Input Parameters: 4787 . mat - the matrix 4788 4789 Output Parameter: 4790 + v - the vector for storing the maximums 4791 - idx - the indices of the column found for each row (or NULL if not needed) 4792 4793 Level: intermediate 4794 4795 Notes: 4796 if a row is completely empty or has only 0.0 values then the idx[] value for that 4797 row is 0 (the first column). 4798 4799 This code is only implemented for a couple of matrix formats. 4800 4801 Concepts: matrices^getting row maximums 4802 4803 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4804 @*/ 4805 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4806 { 4807 PetscErrorCode ierr; 4808 4809 PetscFunctionBegin; 4810 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4811 PetscValidType(mat,1); 4812 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4813 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4814 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4815 MatCheckPreallocated(mat,1); 4816 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4817 4818 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4819 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4820 PetscFunctionReturn(0); 4821 } 4822 4823 /*@ 4824 MatGetRowSum - Gets the sum of each row of the matrix 4825 4826 Logically or Neighborhood Collective on Mat and Vec 4827 4828 Input Parameters: 4829 . mat - the matrix 4830 4831 Output Parameter: 4832 . v - the vector for storing the sum of rows 4833 4834 Level: intermediate 4835 4836 Notes: 4837 This code is slow since it is not currently specialized for different formats 4838 4839 Concepts: matrices^getting row sums 4840 4841 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4842 @*/ 4843 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4844 { 4845 Vec ones; 4846 PetscErrorCode ierr; 4847 4848 PetscFunctionBegin; 4849 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4850 PetscValidType(mat,1); 4851 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4852 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4853 MatCheckPreallocated(mat,1); 4854 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4855 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4856 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4857 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4858 PetscFunctionReturn(0); 4859 } 4860 4861 /*@ 4862 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4863 4864 Collective on Mat 4865 4866 Input Parameter: 4867 + mat - the matrix to transpose 4868 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4869 4870 Output Parameters: 4871 . B - the transpose 4872 4873 Notes: 4874 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4875 4876 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4877 4878 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4879 4880 Level: intermediate 4881 4882 Concepts: matrices^transposing 4883 4884 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4885 @*/ 4886 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4887 { 4888 PetscErrorCode ierr; 4889 4890 PetscFunctionBegin; 4891 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4892 PetscValidType(mat,1); 4893 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4894 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4895 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4896 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4897 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4898 MatCheckPreallocated(mat,1); 4899 4900 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4901 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4902 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4903 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4904 PetscFunctionReturn(0); 4905 } 4906 4907 /*@ 4908 MatIsTranspose - Test whether a matrix is another one's transpose, 4909 or its own, in which case it tests symmetry. 4910 4911 Collective on Mat 4912 4913 Input Parameter: 4914 + A - the matrix to test 4915 - B - the matrix to test against, this can equal the first parameter 4916 4917 Output Parameters: 4918 . flg - the result 4919 4920 Notes: 4921 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4922 has a running time of the order of the number of nonzeros; the parallel 4923 test involves parallel copies of the block-offdiagonal parts of the matrix. 4924 4925 Level: intermediate 4926 4927 Concepts: matrices^transposing, matrix^symmetry 4928 4929 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4930 @*/ 4931 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4932 { 4933 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4934 4935 PetscFunctionBegin; 4936 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4937 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4938 PetscValidPointer(flg,3); 4939 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4940 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4941 *flg = PETSC_FALSE; 4942 if (f && g) { 4943 if (f == g) { 4944 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4945 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4946 } else { 4947 MatType mattype; 4948 if (!f) { 4949 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4950 } else { 4951 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4952 } 4953 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4954 } 4955 PetscFunctionReturn(0); 4956 } 4957 4958 /*@ 4959 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4960 4961 Collective on Mat 4962 4963 Input Parameter: 4964 + mat - the matrix to transpose and complex conjugate 4965 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 4966 4967 Output Parameters: 4968 . B - the Hermitian 4969 4970 Level: intermediate 4971 4972 Concepts: matrices^transposing, complex conjugatex 4973 4974 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4975 @*/ 4976 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 4977 { 4978 PetscErrorCode ierr; 4979 4980 PetscFunctionBegin; 4981 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 4982 #if defined(PETSC_USE_COMPLEX) 4983 ierr = MatConjugate(*B);CHKERRQ(ierr); 4984 #endif 4985 PetscFunctionReturn(0); 4986 } 4987 4988 /*@ 4989 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 4990 4991 Collective on Mat 4992 4993 Input Parameter: 4994 + A - the matrix to test 4995 - B - the matrix to test against, this can equal the first parameter 4996 4997 Output Parameters: 4998 . flg - the result 4999 5000 Notes: 5001 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5002 has a running time of the order of the number of nonzeros; the parallel 5003 test involves parallel copies of the block-offdiagonal parts of the matrix. 5004 5005 Level: intermediate 5006 5007 Concepts: matrices^transposing, matrix^symmetry 5008 5009 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 5010 @*/ 5011 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5012 { 5013 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5014 5015 PetscFunctionBegin; 5016 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5017 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5018 PetscValidPointer(flg,3); 5019 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 5020 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 5021 if (f && g) { 5022 if (f==g) { 5023 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 5024 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5025 } 5026 PetscFunctionReturn(0); 5027 } 5028 5029 /*@ 5030 MatPermute - Creates a new matrix with rows and columns permuted from the 5031 original. 5032 5033 Collective on Mat 5034 5035 Input Parameters: 5036 + mat - the matrix to permute 5037 . row - row permutation, each processor supplies only the permutation for its rows 5038 - col - column permutation, each processor supplies only the permutation for its columns 5039 5040 Output Parameters: 5041 . B - the permuted matrix 5042 5043 Level: advanced 5044 5045 Note: 5046 The index sets map from row/col of permuted matrix to row/col of original matrix. 5047 The index sets should be on the same communicator as Mat and have the same local sizes. 5048 5049 Concepts: matrices^permuting 5050 5051 .seealso: MatGetOrdering(), ISAllGather() 5052 5053 @*/ 5054 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5055 { 5056 PetscErrorCode ierr; 5057 5058 PetscFunctionBegin; 5059 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5060 PetscValidType(mat,1); 5061 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5062 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5063 PetscValidPointer(B,4); 5064 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5065 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5066 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5067 MatCheckPreallocated(mat,1); 5068 5069 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 5070 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 5071 PetscFunctionReturn(0); 5072 } 5073 5074 /*@ 5075 MatEqual - Compares two matrices. 5076 5077 Collective on Mat 5078 5079 Input Parameters: 5080 + A - the first matrix 5081 - B - the second matrix 5082 5083 Output Parameter: 5084 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5085 5086 Level: intermediate 5087 5088 Concepts: matrices^equality between 5089 @*/ 5090 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5091 { 5092 PetscErrorCode ierr; 5093 5094 PetscFunctionBegin; 5095 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5096 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5097 PetscValidType(A,1); 5098 PetscValidType(B,2); 5099 PetscValidIntPointer(flg,3); 5100 PetscCheckSameComm(A,1,B,2); 5101 MatCheckPreallocated(B,2); 5102 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5103 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5104 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); 5105 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5106 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5107 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); 5108 MatCheckPreallocated(A,1); 5109 5110 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5111 PetscFunctionReturn(0); 5112 } 5113 5114 /*@ 5115 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5116 matrices that are stored as vectors. Either of the two scaling 5117 matrices can be NULL. 5118 5119 Collective on Mat 5120 5121 Input Parameters: 5122 + mat - the matrix to be scaled 5123 . l - the left scaling vector (or NULL) 5124 - r - the right scaling vector (or NULL) 5125 5126 Notes: 5127 MatDiagonalScale() computes A = LAR, where 5128 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5129 The L scales the rows of the matrix, the R scales the columns of the matrix. 5130 5131 Level: intermediate 5132 5133 Concepts: matrices^diagonal scaling 5134 Concepts: diagonal scaling of matrices 5135 5136 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5137 @*/ 5138 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5139 { 5140 PetscErrorCode ierr; 5141 5142 PetscFunctionBegin; 5143 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5144 PetscValidType(mat,1); 5145 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5146 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5147 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5148 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5149 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5150 MatCheckPreallocated(mat,1); 5151 5152 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5153 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5154 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5155 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5156 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5157 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5158 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5159 } 5160 #endif 5161 PetscFunctionReturn(0); 5162 } 5163 5164 /*@ 5165 MatScale - Scales all elements of a matrix by a given number. 5166 5167 Logically Collective on Mat 5168 5169 Input Parameters: 5170 + mat - the matrix to be scaled 5171 - a - the scaling value 5172 5173 Output Parameter: 5174 . mat - the scaled matrix 5175 5176 Level: intermediate 5177 5178 Concepts: matrices^scaling all entries 5179 5180 .seealso: MatDiagonalScale() 5181 @*/ 5182 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5183 { 5184 PetscErrorCode ierr; 5185 5186 PetscFunctionBegin; 5187 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5188 PetscValidType(mat,1); 5189 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5190 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5191 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5192 PetscValidLogicalCollectiveScalar(mat,a,2); 5193 MatCheckPreallocated(mat,1); 5194 5195 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5196 if (a != (PetscScalar)1.0) { 5197 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5198 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5199 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5200 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5201 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5202 } 5203 #endif 5204 } 5205 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5206 PetscFunctionReturn(0); 5207 } 5208 5209 static PetscErrorCode MatNorm_Basic(Mat A,NormType type,PetscReal *nrm) 5210 { 5211 PetscErrorCode ierr; 5212 5213 PetscFunctionBegin; 5214 if (type == NORM_1 || type == NORM_INFINITY) { 5215 Vec l,r; 5216 5217 ierr = MatCreateVecs(A,&r,&l);CHKERRQ(ierr); 5218 if (type == NORM_INFINITY) { 5219 ierr = VecSet(r,1.);CHKERRQ(ierr); 5220 ierr = MatMult(A,r,l);CHKERRQ(ierr); 5221 ierr = VecNorm(l,NORM_INFINITY,nrm);CHKERRQ(ierr); 5222 } else { 5223 ierr = VecSet(l,1.);CHKERRQ(ierr); 5224 ierr = MatMultTranspose(A,l,r);CHKERRQ(ierr); 5225 ierr = VecNorm(r,NORM_INFINITY,nrm);CHKERRQ(ierr); 5226 } 5227 ierr = VecDestroy(&l);CHKERRQ(ierr); 5228 ierr = VecDestroy(&r);CHKERRQ(ierr); 5229 } else SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix class %s, norm type %d",((PetscObject)A)->type_name,type); 5230 PetscFunctionReturn(0); 5231 } 5232 5233 /*@ 5234 MatNorm - Calculates various norms of a matrix. 5235 5236 Collective on Mat 5237 5238 Input Parameters: 5239 + mat - the matrix 5240 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5241 5242 Output Parameters: 5243 . nrm - the resulting norm 5244 5245 Level: intermediate 5246 5247 Concepts: matrices^norm 5248 Concepts: norm^of matrix 5249 @*/ 5250 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5251 { 5252 PetscErrorCode ierr; 5253 5254 PetscFunctionBegin; 5255 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5256 PetscValidType(mat,1); 5257 PetscValidLogicalCollectiveEnum(mat,type,2); 5258 PetscValidScalarPointer(nrm,3); 5259 5260 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5261 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5262 MatCheckPreallocated(mat,1); 5263 5264 if (!mat->ops->norm) { 5265 ierr = MatNorm_Basic(mat,type,nrm);CHKERRQ(ierr); 5266 } else { 5267 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5268 } 5269 PetscFunctionReturn(0); 5270 } 5271 5272 /* 5273 This variable is used to prevent counting of MatAssemblyBegin() that 5274 are called from within a MatAssemblyEnd(). 5275 */ 5276 static PetscInt MatAssemblyEnd_InUse = 0; 5277 /*@ 5278 MatAssemblyBegin - Begins assembling the matrix. This routine should 5279 be called after completing all calls to MatSetValues(). 5280 5281 Collective on Mat 5282 5283 Input Parameters: 5284 + mat - the matrix 5285 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5286 5287 Notes: 5288 MatSetValues() generally caches the values. The matrix is ready to 5289 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5290 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5291 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5292 using the matrix. 5293 5294 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5295 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 5296 a global collective operation requring all processes that share the matrix. 5297 5298 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5299 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5300 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5301 5302 Level: beginner 5303 5304 Concepts: matrices^assembling 5305 5306 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5307 @*/ 5308 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5309 { 5310 PetscErrorCode ierr; 5311 5312 PetscFunctionBegin; 5313 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5314 PetscValidType(mat,1); 5315 MatCheckPreallocated(mat,1); 5316 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5317 if (mat->assembled) { 5318 mat->was_assembled = PETSC_TRUE; 5319 mat->assembled = PETSC_FALSE; 5320 } 5321 if (!MatAssemblyEnd_InUse) { 5322 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5323 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5324 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5325 } else if (mat->ops->assemblybegin) { 5326 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5327 } 5328 PetscFunctionReturn(0); 5329 } 5330 5331 /*@ 5332 MatAssembled - Indicates if a matrix has been assembled and is ready for 5333 use; for example, in matrix-vector product. 5334 5335 Not Collective 5336 5337 Input Parameter: 5338 . mat - the matrix 5339 5340 Output Parameter: 5341 . assembled - PETSC_TRUE or PETSC_FALSE 5342 5343 Level: advanced 5344 5345 Concepts: matrices^assembled? 5346 5347 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5348 @*/ 5349 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5350 { 5351 PetscFunctionBegin; 5352 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5353 PetscValidType(mat,1); 5354 PetscValidPointer(assembled,2); 5355 *assembled = mat->assembled; 5356 PetscFunctionReturn(0); 5357 } 5358 5359 /*@ 5360 MatAssemblyEnd - Completes assembling the matrix. This routine should 5361 be called after MatAssemblyBegin(). 5362 5363 Collective on Mat 5364 5365 Input Parameters: 5366 + mat - the matrix 5367 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5368 5369 Options Database Keys: 5370 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5371 . -mat_view ::ascii_info_detail - Prints more detailed info 5372 . -mat_view - Prints matrix in ASCII format 5373 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5374 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5375 . -display <name> - Sets display name (default is host) 5376 . -draw_pause <sec> - Sets number of seconds to pause after display 5377 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5378 . -viewer_socket_machine <machine> - Machine to use for socket 5379 . -viewer_socket_port <port> - Port number to use for socket 5380 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5381 5382 Notes: 5383 MatSetValues() generally caches the values. The matrix is ready to 5384 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5385 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5386 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5387 using the matrix. 5388 5389 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5390 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5391 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5392 5393 Level: beginner 5394 5395 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5396 @*/ 5397 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5398 { 5399 PetscErrorCode ierr; 5400 static PetscInt inassm = 0; 5401 PetscBool flg = PETSC_FALSE; 5402 5403 PetscFunctionBegin; 5404 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5405 PetscValidType(mat,1); 5406 5407 inassm++; 5408 MatAssemblyEnd_InUse++; 5409 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5410 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5411 if (mat->ops->assemblyend) { 5412 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5413 } 5414 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5415 } else if (mat->ops->assemblyend) { 5416 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5417 } 5418 5419 /* Flush assembly is not a true assembly */ 5420 if (type != MAT_FLUSH_ASSEMBLY) { 5421 mat->assembled = PETSC_TRUE; mat->num_ass++; 5422 } 5423 mat->insertmode = NOT_SET_VALUES; 5424 MatAssemblyEnd_InUse--; 5425 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5426 if (!mat->symmetric_eternal) { 5427 mat->symmetric_set = PETSC_FALSE; 5428 mat->hermitian_set = PETSC_FALSE; 5429 mat->structurally_symmetric_set = PETSC_FALSE; 5430 } 5431 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5432 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5433 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5434 } 5435 #endif 5436 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5437 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5438 5439 if (mat->checksymmetryonassembly) { 5440 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5441 if (flg) { 5442 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5443 } else { 5444 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5445 } 5446 } 5447 if (mat->nullsp && mat->checknullspaceonassembly) { 5448 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5449 } 5450 } 5451 inassm--; 5452 PetscFunctionReturn(0); 5453 } 5454 5455 /*@ 5456 MatSetOption - Sets a parameter option for a matrix. Some options 5457 may be specific to certain storage formats. Some options 5458 determine how values will be inserted (or added). Sorted, 5459 row-oriented input will generally assemble the fastest. The default 5460 is row-oriented. 5461 5462 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5463 5464 Input Parameters: 5465 + mat - the matrix 5466 . option - the option, one of those listed below (and possibly others), 5467 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5468 5469 Options Describing Matrix Structure: 5470 + MAT_SPD - symmetric positive definite 5471 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5472 . MAT_HERMITIAN - transpose is the complex conjugation 5473 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5474 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5475 you set to be kept with all future use of the matrix 5476 including after MatAssemblyBegin/End() which could 5477 potentially change the symmetry structure, i.e. you 5478 KNOW the matrix will ALWAYS have the property you set. 5479 5480 5481 Options For Use with MatSetValues(): 5482 Insert a logically dense subblock, which can be 5483 . MAT_ROW_ORIENTED - row-oriented (default) 5484 5485 Note these options reflect the data you pass in with MatSetValues(); it has 5486 nothing to do with how the data is stored internally in the matrix 5487 data structure. 5488 5489 When (re)assembling a matrix, we can restrict the input for 5490 efficiency/debugging purposes. These options include: 5491 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5492 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5493 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5494 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5495 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5496 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5497 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5498 performance for very large process counts. 5499 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5500 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5501 functions, instead sending only neighbor messages. 5502 5503 Notes: 5504 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5505 5506 Some options are relevant only for particular matrix types and 5507 are thus ignored by others. Other options are not supported by 5508 certain matrix types and will generate an error message if set. 5509 5510 If using a Fortran 77 module to compute a matrix, one may need to 5511 use the column-oriented option (or convert to the row-oriented 5512 format). 5513 5514 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5515 that would generate a new entry in the nonzero structure is instead 5516 ignored. Thus, if memory has not alredy been allocated for this particular 5517 data, then the insertion is ignored. For dense matrices, in which 5518 the entire array is allocated, no entries are ever ignored. 5519 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5520 5521 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5522 that would generate a new entry in the nonzero structure instead produces 5523 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 5524 5525 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5526 that would generate a new entry that has not been preallocated will 5527 instead produce an error. (Currently supported for AIJ and BAIJ formats 5528 only.) This is a useful flag when debugging matrix memory preallocation. 5529 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5530 5531 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5532 other processors should be dropped, rather than stashed. 5533 This is useful if you know that the "owning" processor is also 5534 always generating the correct matrix entries, so that PETSc need 5535 not transfer duplicate entries generated on another processor. 5536 5537 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5538 searches during matrix assembly. When this flag is set, the hash table 5539 is created during the first Matrix Assembly. This hash table is 5540 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5541 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5542 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5543 supported by MATMPIBAIJ format only. 5544 5545 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5546 are kept in the nonzero structure 5547 5548 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5549 a zero location in the matrix 5550 5551 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5552 5553 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5554 zero row routines and thus improves performance for very large process counts. 5555 5556 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5557 part of the matrix (since they should match the upper triangular part). 5558 5559 Notes: 5560 Can only be called after MatSetSizes() and MatSetType() have been set. 5561 5562 Level: intermediate 5563 5564 Concepts: matrices^setting options 5565 5566 .seealso: MatOption, Mat 5567 5568 @*/ 5569 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5570 { 5571 PetscErrorCode ierr; 5572 5573 PetscFunctionBegin; 5574 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5575 PetscValidType(mat,1); 5576 if (op > 0) { 5577 PetscValidLogicalCollectiveEnum(mat,op,2); 5578 PetscValidLogicalCollectiveBool(mat,flg,3); 5579 } 5580 5581 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); 5582 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()"); 5583 5584 switch (op) { 5585 case MAT_NO_OFF_PROC_ENTRIES: 5586 mat->nooffprocentries = flg; 5587 PetscFunctionReturn(0); 5588 break; 5589 case MAT_SUBSET_OFF_PROC_ENTRIES: 5590 mat->subsetoffprocentries = flg; 5591 PetscFunctionReturn(0); 5592 case MAT_NO_OFF_PROC_ZERO_ROWS: 5593 mat->nooffproczerorows = flg; 5594 PetscFunctionReturn(0); 5595 break; 5596 case MAT_SPD: 5597 mat->spd_set = PETSC_TRUE; 5598 mat->spd = flg; 5599 if (flg) { 5600 mat->symmetric = PETSC_TRUE; 5601 mat->structurally_symmetric = PETSC_TRUE; 5602 mat->symmetric_set = PETSC_TRUE; 5603 mat->structurally_symmetric_set = PETSC_TRUE; 5604 } 5605 break; 5606 case MAT_SYMMETRIC: 5607 mat->symmetric = flg; 5608 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5609 mat->symmetric_set = PETSC_TRUE; 5610 mat->structurally_symmetric_set = flg; 5611 #if !defined(PETSC_USE_COMPLEX) 5612 mat->hermitian = flg; 5613 mat->hermitian_set = PETSC_TRUE; 5614 #endif 5615 break; 5616 case MAT_HERMITIAN: 5617 mat->hermitian = flg; 5618 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5619 mat->hermitian_set = PETSC_TRUE; 5620 mat->structurally_symmetric_set = flg; 5621 #if !defined(PETSC_USE_COMPLEX) 5622 mat->symmetric = flg; 5623 mat->symmetric_set = PETSC_TRUE; 5624 #endif 5625 break; 5626 case MAT_STRUCTURALLY_SYMMETRIC: 5627 mat->structurally_symmetric = flg; 5628 mat->structurally_symmetric_set = PETSC_TRUE; 5629 break; 5630 case MAT_SYMMETRY_ETERNAL: 5631 mat->symmetric_eternal = flg; 5632 break; 5633 case MAT_STRUCTURE_ONLY: 5634 mat->structure_only = flg; 5635 break; 5636 default: 5637 break; 5638 } 5639 if (mat->ops->setoption) { 5640 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5641 } 5642 PetscFunctionReturn(0); 5643 } 5644 5645 /*@ 5646 MatGetOption - Gets a parameter option that has been set for a matrix. 5647 5648 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5649 5650 Input Parameters: 5651 + mat - the matrix 5652 - option - the option, this only responds to certain options, check the code for which ones 5653 5654 Output Parameter: 5655 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5656 5657 Notes: 5658 Can only be called after MatSetSizes() and MatSetType() have been set. 5659 5660 Level: intermediate 5661 5662 Concepts: matrices^setting options 5663 5664 .seealso: MatOption, MatSetOption() 5665 5666 @*/ 5667 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5668 { 5669 PetscFunctionBegin; 5670 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5671 PetscValidType(mat,1); 5672 5673 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); 5674 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()"); 5675 5676 switch (op) { 5677 case MAT_NO_OFF_PROC_ENTRIES: 5678 *flg = mat->nooffprocentries; 5679 break; 5680 case MAT_NO_OFF_PROC_ZERO_ROWS: 5681 *flg = mat->nooffproczerorows; 5682 break; 5683 case MAT_SYMMETRIC: 5684 *flg = mat->symmetric; 5685 break; 5686 case MAT_HERMITIAN: 5687 *flg = mat->hermitian; 5688 break; 5689 case MAT_STRUCTURALLY_SYMMETRIC: 5690 *flg = mat->structurally_symmetric; 5691 break; 5692 case MAT_SYMMETRY_ETERNAL: 5693 *flg = mat->symmetric_eternal; 5694 break; 5695 case MAT_SPD: 5696 *flg = mat->spd; 5697 break; 5698 default: 5699 break; 5700 } 5701 PetscFunctionReturn(0); 5702 } 5703 5704 /*@ 5705 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5706 this routine retains the old nonzero structure. 5707 5708 Logically Collective on Mat 5709 5710 Input Parameters: 5711 . mat - the matrix 5712 5713 Level: intermediate 5714 5715 Notes: 5716 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. 5717 See the Performance chapter of the users manual for information on preallocating matrices. 5718 5719 Concepts: matrices^zeroing 5720 5721 .seealso: MatZeroRows() 5722 @*/ 5723 PetscErrorCode MatZeroEntries(Mat mat) 5724 { 5725 PetscErrorCode ierr; 5726 5727 PetscFunctionBegin; 5728 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5729 PetscValidType(mat,1); 5730 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5731 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"); 5732 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5733 MatCheckPreallocated(mat,1); 5734 5735 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5736 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5737 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5738 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5739 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5740 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5741 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5742 } 5743 #endif 5744 PetscFunctionReturn(0); 5745 } 5746 5747 /*@ 5748 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5749 of a set of rows and columns of a matrix. 5750 5751 Collective on Mat 5752 5753 Input Parameters: 5754 + mat - the matrix 5755 . numRows - the number of rows to remove 5756 . rows - the global row indices 5757 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5758 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5759 - b - optional vector of right hand side, that will be adjusted by provided solution 5760 5761 Notes: 5762 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5763 5764 The user can set a value in the diagonal entry (or for the AIJ and 5765 row formats can optionally remove the main diagonal entry from the 5766 nonzero structure as well, by passing 0.0 as the final argument). 5767 5768 For the parallel case, all processes that share the matrix (i.e., 5769 those in the communicator used for matrix creation) MUST call this 5770 routine, regardless of whether any rows being zeroed are owned by 5771 them. 5772 5773 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5774 list only rows local to itself). 5775 5776 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5777 5778 Level: intermediate 5779 5780 Concepts: matrices^zeroing rows 5781 5782 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5783 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5784 @*/ 5785 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5786 { 5787 PetscErrorCode ierr; 5788 5789 PetscFunctionBegin; 5790 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5791 PetscValidType(mat,1); 5792 if (numRows) PetscValidIntPointer(rows,3); 5793 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5794 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5795 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5796 MatCheckPreallocated(mat,1); 5797 5798 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5799 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5800 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5801 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5802 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5803 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5804 } 5805 #endif 5806 PetscFunctionReturn(0); 5807 } 5808 5809 /*@ 5810 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5811 of a set of rows and columns of a matrix. 5812 5813 Collective on Mat 5814 5815 Input Parameters: 5816 + mat - the matrix 5817 . is - the rows to zero 5818 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5819 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5820 - b - optional vector of right hand side, that will be adjusted by provided solution 5821 5822 Notes: 5823 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5824 5825 The user can set a value in the diagonal entry (or for the AIJ and 5826 row formats can optionally remove the main diagonal entry from the 5827 nonzero structure as well, by passing 0.0 as the final argument). 5828 5829 For the parallel case, all processes that share the matrix (i.e., 5830 those in the communicator used for matrix creation) MUST call this 5831 routine, regardless of whether any rows being zeroed are owned by 5832 them. 5833 5834 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5835 list only rows local to itself). 5836 5837 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5838 5839 Level: intermediate 5840 5841 Concepts: matrices^zeroing rows 5842 5843 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5844 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5845 @*/ 5846 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5847 { 5848 PetscErrorCode ierr; 5849 PetscInt numRows; 5850 const PetscInt *rows; 5851 5852 PetscFunctionBegin; 5853 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5854 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5855 PetscValidType(mat,1); 5856 PetscValidType(is,2); 5857 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5858 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5859 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5860 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5861 PetscFunctionReturn(0); 5862 } 5863 5864 /*@ 5865 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5866 of a set of rows of a matrix. 5867 5868 Collective on Mat 5869 5870 Input Parameters: 5871 + mat - the matrix 5872 . numRows - the number of rows to remove 5873 . rows - the global row indices 5874 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5875 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5876 - b - optional vector of right hand side, that will be adjusted by provided solution 5877 5878 Notes: 5879 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5880 but does not release memory. For the dense and block diagonal 5881 formats this does not alter the nonzero structure. 5882 5883 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5884 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5885 merely zeroed. 5886 5887 The user can set a value in the diagonal entry (or for the AIJ and 5888 row formats can optionally remove the main diagonal entry from the 5889 nonzero structure as well, by passing 0.0 as the final argument). 5890 5891 For the parallel case, all processes that share the matrix (i.e., 5892 those in the communicator used for matrix creation) MUST call this 5893 routine, regardless of whether any rows being zeroed are owned by 5894 them. 5895 5896 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5897 list only rows local to itself). 5898 5899 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5900 owns that are to be zeroed. This saves a global synchronization in the implementation. 5901 5902 Level: intermediate 5903 5904 Concepts: matrices^zeroing rows 5905 5906 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5907 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5908 @*/ 5909 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5910 { 5911 PetscErrorCode ierr; 5912 5913 PetscFunctionBegin; 5914 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5915 PetscValidType(mat,1); 5916 if (numRows) PetscValidIntPointer(rows,3); 5917 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5918 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5919 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5920 MatCheckPreallocated(mat,1); 5921 5922 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5923 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5924 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5925 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5926 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5927 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5928 } 5929 #endif 5930 PetscFunctionReturn(0); 5931 } 5932 5933 /*@ 5934 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5935 of a set of rows of a matrix. 5936 5937 Collective on Mat 5938 5939 Input Parameters: 5940 + mat - the matrix 5941 . is - index set of rows to remove 5942 . diag - value put in all diagonals of eliminated rows 5943 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5944 - b - optional vector of right hand side, that will be adjusted by provided solution 5945 5946 Notes: 5947 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5948 but does not release memory. For the dense and block diagonal 5949 formats this does not alter the nonzero structure. 5950 5951 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5952 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5953 merely zeroed. 5954 5955 The user can set a value in the diagonal entry (or for the AIJ and 5956 row formats can optionally remove the main diagonal entry from the 5957 nonzero structure as well, by passing 0.0 as the final argument). 5958 5959 For the parallel case, all processes that share the matrix (i.e., 5960 those in the communicator used for matrix creation) MUST call this 5961 routine, regardless of whether any rows being zeroed are owned by 5962 them. 5963 5964 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5965 list only rows local to itself). 5966 5967 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5968 owns that are to be zeroed. This saves a global synchronization in the implementation. 5969 5970 Level: intermediate 5971 5972 Concepts: matrices^zeroing rows 5973 5974 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5975 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5976 @*/ 5977 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5978 { 5979 PetscInt numRows; 5980 const PetscInt *rows; 5981 PetscErrorCode ierr; 5982 5983 PetscFunctionBegin; 5984 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5985 PetscValidType(mat,1); 5986 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5987 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5988 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5989 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5990 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5991 PetscFunctionReturn(0); 5992 } 5993 5994 /*@ 5995 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5996 of a set of rows of a matrix. These rows must be local to the process. 5997 5998 Collective on Mat 5999 6000 Input Parameters: 6001 + mat - the matrix 6002 . numRows - the number of rows to remove 6003 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6004 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6005 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6006 - b - optional vector of right hand side, that will be adjusted by provided solution 6007 6008 Notes: 6009 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6010 but does not release memory. For the dense and block diagonal 6011 formats this does not alter the nonzero structure. 6012 6013 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6014 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6015 merely zeroed. 6016 6017 The user can set a value in the diagonal entry (or for the AIJ and 6018 row formats can optionally remove the main diagonal entry from the 6019 nonzero structure as well, by passing 0.0 as the final argument). 6020 6021 For the parallel case, all processes that share the matrix (i.e., 6022 those in the communicator used for matrix creation) MUST call this 6023 routine, regardless of whether any rows being zeroed are owned by 6024 them. 6025 6026 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6027 list only rows local to itself). 6028 6029 The grid coordinates are across the entire grid, not just the local portion 6030 6031 In Fortran idxm and idxn should be declared as 6032 $ MatStencil idxm(4,m) 6033 and the values inserted using 6034 $ idxm(MatStencil_i,1) = i 6035 $ idxm(MatStencil_j,1) = j 6036 $ idxm(MatStencil_k,1) = k 6037 $ idxm(MatStencil_c,1) = c 6038 etc 6039 6040 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6041 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6042 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6043 DM_BOUNDARY_PERIODIC boundary type. 6044 6045 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 6046 a single value per point) you can skip filling those indices. 6047 6048 Level: intermediate 6049 6050 Concepts: matrices^zeroing rows 6051 6052 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6053 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6054 @*/ 6055 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6056 { 6057 PetscInt dim = mat->stencil.dim; 6058 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6059 PetscInt *dims = mat->stencil.dims+1; 6060 PetscInt *starts = mat->stencil.starts; 6061 PetscInt *dxm = (PetscInt*) rows; 6062 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6063 PetscErrorCode ierr; 6064 6065 PetscFunctionBegin; 6066 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6067 PetscValidType(mat,1); 6068 if (numRows) PetscValidIntPointer(rows,3); 6069 6070 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6071 for (i = 0; i < numRows; ++i) { 6072 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6073 for (j = 0; j < 3-sdim; ++j) dxm++; 6074 /* Local index in X dir */ 6075 tmp = *dxm++ - starts[0]; 6076 /* Loop over remaining dimensions */ 6077 for (j = 0; j < dim-1; ++j) { 6078 /* If nonlocal, set index to be negative */ 6079 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6080 /* Update local index */ 6081 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6082 } 6083 /* Skip component slot if necessary */ 6084 if (mat->stencil.noc) dxm++; 6085 /* Local row number */ 6086 if (tmp >= 0) { 6087 jdxm[numNewRows++] = tmp; 6088 } 6089 } 6090 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6091 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6092 PetscFunctionReturn(0); 6093 } 6094 6095 /*@ 6096 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6097 of a set of rows and columns of a matrix. 6098 6099 Collective on Mat 6100 6101 Input Parameters: 6102 + mat - the matrix 6103 . numRows - the number of rows/columns to remove 6104 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6105 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6106 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6107 - b - optional vector of right hand side, that will be adjusted by provided solution 6108 6109 Notes: 6110 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6111 but does not release memory. For the dense and block diagonal 6112 formats this does not alter the nonzero structure. 6113 6114 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6115 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6116 merely zeroed. 6117 6118 The user can set a value in the diagonal entry (or for the AIJ and 6119 row formats can optionally remove the main diagonal entry from the 6120 nonzero structure as well, by passing 0.0 as the final argument). 6121 6122 For the parallel case, all processes that share the matrix (i.e., 6123 those in the communicator used for matrix creation) MUST call this 6124 routine, regardless of whether any rows being zeroed are owned by 6125 them. 6126 6127 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6128 list only rows local to itself, but the row/column numbers are given in local numbering). 6129 6130 The grid coordinates are across the entire grid, not just the local portion 6131 6132 In Fortran idxm and idxn should be declared as 6133 $ MatStencil idxm(4,m) 6134 and the values inserted using 6135 $ idxm(MatStencil_i,1) = i 6136 $ idxm(MatStencil_j,1) = j 6137 $ idxm(MatStencil_k,1) = k 6138 $ idxm(MatStencil_c,1) = c 6139 etc 6140 6141 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6142 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6143 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6144 DM_BOUNDARY_PERIODIC boundary type. 6145 6146 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 6147 a single value per point) you can skip filling those indices. 6148 6149 Level: intermediate 6150 6151 Concepts: matrices^zeroing rows 6152 6153 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6154 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6155 @*/ 6156 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6157 { 6158 PetscInt dim = mat->stencil.dim; 6159 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6160 PetscInt *dims = mat->stencil.dims+1; 6161 PetscInt *starts = mat->stencil.starts; 6162 PetscInt *dxm = (PetscInt*) rows; 6163 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6164 PetscErrorCode ierr; 6165 6166 PetscFunctionBegin; 6167 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6168 PetscValidType(mat,1); 6169 if (numRows) PetscValidIntPointer(rows,3); 6170 6171 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6172 for (i = 0; i < numRows; ++i) { 6173 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6174 for (j = 0; j < 3-sdim; ++j) dxm++; 6175 /* Local index in X dir */ 6176 tmp = *dxm++ - starts[0]; 6177 /* Loop over remaining dimensions */ 6178 for (j = 0; j < dim-1; ++j) { 6179 /* If nonlocal, set index to be negative */ 6180 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6181 /* Update local index */ 6182 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6183 } 6184 /* Skip component slot if necessary */ 6185 if (mat->stencil.noc) dxm++; 6186 /* Local row number */ 6187 if (tmp >= 0) { 6188 jdxm[numNewRows++] = tmp; 6189 } 6190 } 6191 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6192 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6193 PetscFunctionReturn(0); 6194 } 6195 6196 /*@C 6197 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6198 of a set of rows of a matrix; using local numbering of rows. 6199 6200 Collective on Mat 6201 6202 Input Parameters: 6203 + mat - the matrix 6204 . numRows - the number of rows to remove 6205 . rows - the global row indices 6206 . diag - value put in all diagonals of eliminated rows 6207 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6208 - b - optional vector of right hand side, that will be adjusted by provided solution 6209 6210 Notes: 6211 Before calling MatZeroRowsLocal(), the user must first set the 6212 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6213 6214 For the AIJ matrix formats this removes the old nonzero structure, 6215 but does not release memory. For the dense and block diagonal 6216 formats this does not alter the nonzero structure. 6217 6218 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6219 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6220 merely zeroed. 6221 6222 The user can set a value in the diagonal entry (or for the AIJ and 6223 row formats can optionally remove the main diagonal entry from the 6224 nonzero structure as well, by passing 0.0 as the final argument). 6225 6226 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6227 owns that are to be zeroed. This saves a global synchronization in the implementation. 6228 6229 Level: intermediate 6230 6231 Concepts: matrices^zeroing 6232 6233 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6234 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6235 @*/ 6236 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6237 { 6238 PetscErrorCode ierr; 6239 6240 PetscFunctionBegin; 6241 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6242 PetscValidType(mat,1); 6243 if (numRows) PetscValidIntPointer(rows,3); 6244 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6245 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6246 MatCheckPreallocated(mat,1); 6247 6248 if (mat->ops->zerorowslocal) { 6249 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6250 } else { 6251 IS is, newis; 6252 const PetscInt *newRows; 6253 6254 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6255 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6256 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6257 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6258 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6259 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6260 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6261 ierr = ISDestroy(&is);CHKERRQ(ierr); 6262 } 6263 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6264 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6265 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6266 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6267 } 6268 #endif 6269 PetscFunctionReturn(0); 6270 } 6271 6272 /*@ 6273 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6274 of a set of rows of a matrix; using local numbering of rows. 6275 6276 Collective on Mat 6277 6278 Input Parameters: 6279 + mat - the matrix 6280 . is - index set of rows to remove 6281 . diag - value put in all diagonals of eliminated rows 6282 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6283 - b - optional vector of right hand side, that will be adjusted by provided solution 6284 6285 Notes: 6286 Before calling MatZeroRowsLocalIS(), the user must first set the 6287 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6288 6289 For the AIJ matrix formats this removes the old nonzero structure, 6290 but does not release memory. For the dense and block diagonal 6291 formats this does not alter the nonzero structure. 6292 6293 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6294 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6295 merely zeroed. 6296 6297 The user can set a value in the diagonal entry (or for the AIJ and 6298 row formats can optionally remove the main diagonal entry from the 6299 nonzero structure as well, by passing 0.0 as the final argument). 6300 6301 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6302 owns that are to be zeroed. This saves a global synchronization in the implementation. 6303 6304 Level: intermediate 6305 6306 Concepts: matrices^zeroing 6307 6308 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6309 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6310 @*/ 6311 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6312 { 6313 PetscErrorCode ierr; 6314 PetscInt numRows; 6315 const PetscInt *rows; 6316 6317 PetscFunctionBegin; 6318 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6319 PetscValidType(mat,1); 6320 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6321 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6322 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6323 MatCheckPreallocated(mat,1); 6324 6325 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6326 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6327 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6328 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6329 PetscFunctionReturn(0); 6330 } 6331 6332 /*@ 6333 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6334 of a set of rows and columns of a matrix; using local numbering of rows. 6335 6336 Collective on Mat 6337 6338 Input Parameters: 6339 + mat - the matrix 6340 . numRows - the number of rows to remove 6341 . rows - the global row indices 6342 . diag - value put in all diagonals of eliminated rows 6343 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6344 - b - optional vector of right hand side, that will be adjusted by provided solution 6345 6346 Notes: 6347 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6348 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6349 6350 The user can set a value in the diagonal entry (or for the AIJ and 6351 row formats can optionally remove the main diagonal entry from the 6352 nonzero structure as well, by passing 0.0 as the final argument). 6353 6354 Level: intermediate 6355 6356 Concepts: matrices^zeroing 6357 6358 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6359 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6360 @*/ 6361 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6362 { 6363 PetscErrorCode ierr; 6364 IS is, newis; 6365 const PetscInt *newRows; 6366 6367 PetscFunctionBegin; 6368 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6369 PetscValidType(mat,1); 6370 if (numRows) PetscValidIntPointer(rows,3); 6371 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6372 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6373 MatCheckPreallocated(mat,1); 6374 6375 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6376 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6377 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6378 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6379 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6380 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6381 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6382 ierr = ISDestroy(&is);CHKERRQ(ierr); 6383 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6384 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6385 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6386 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6387 } 6388 #endif 6389 PetscFunctionReturn(0); 6390 } 6391 6392 /*@ 6393 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6394 of a set of rows and columns of a matrix; using local numbering of rows. 6395 6396 Collective on Mat 6397 6398 Input Parameters: 6399 + mat - the matrix 6400 . is - index set of rows to remove 6401 . diag - value put in all diagonals of eliminated rows 6402 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6403 - b - optional vector of right hand side, that will be adjusted by provided solution 6404 6405 Notes: 6406 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6407 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6408 6409 The user can set a value in the diagonal entry (or for the AIJ and 6410 row formats can optionally remove the main diagonal entry from the 6411 nonzero structure as well, by passing 0.0 as the final argument). 6412 6413 Level: intermediate 6414 6415 Concepts: matrices^zeroing 6416 6417 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6418 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6419 @*/ 6420 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6421 { 6422 PetscErrorCode ierr; 6423 PetscInt numRows; 6424 const PetscInt *rows; 6425 6426 PetscFunctionBegin; 6427 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6428 PetscValidType(mat,1); 6429 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6430 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6431 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6432 MatCheckPreallocated(mat,1); 6433 6434 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6435 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6436 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6437 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6438 PetscFunctionReturn(0); 6439 } 6440 6441 /*@C 6442 MatGetSize - Returns the numbers of rows and columns in a matrix. 6443 6444 Not Collective 6445 6446 Input Parameter: 6447 . mat - the matrix 6448 6449 Output Parameters: 6450 + m - the number of global rows 6451 - n - the number of global columns 6452 6453 Note: both output parameters can be NULL on input. 6454 6455 Level: beginner 6456 6457 Concepts: matrices^size 6458 6459 .seealso: MatGetLocalSize() 6460 @*/ 6461 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6462 { 6463 PetscFunctionBegin; 6464 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6465 if (m) *m = mat->rmap->N; 6466 if (n) *n = mat->cmap->N; 6467 PetscFunctionReturn(0); 6468 } 6469 6470 /*@C 6471 MatGetLocalSize - Returns the number of rows and columns in a matrix 6472 stored locally. This information may be implementation dependent, so 6473 use with care. 6474 6475 Not Collective 6476 6477 Input Parameters: 6478 . mat - the matrix 6479 6480 Output Parameters: 6481 + m - the number of local rows 6482 - n - the number of local columns 6483 6484 Note: both output parameters can be NULL on input. 6485 6486 Level: beginner 6487 6488 Concepts: matrices^local size 6489 6490 .seealso: MatGetSize() 6491 @*/ 6492 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6493 { 6494 PetscFunctionBegin; 6495 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6496 if (m) PetscValidIntPointer(m,2); 6497 if (n) PetscValidIntPointer(n,3); 6498 if (m) *m = mat->rmap->n; 6499 if (n) *n = mat->cmap->n; 6500 PetscFunctionReturn(0); 6501 } 6502 6503 /*@C 6504 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6505 this processor. (The columns of the "diagonal block") 6506 6507 Not Collective, unless matrix has not been allocated, then collective on Mat 6508 6509 Input Parameters: 6510 . mat - the matrix 6511 6512 Output Parameters: 6513 + m - the global index of the first local column 6514 - n - one more than the global index of the last local column 6515 6516 Notes: 6517 both output parameters can be NULL on input. 6518 6519 Level: developer 6520 6521 Concepts: matrices^column ownership 6522 6523 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6524 6525 @*/ 6526 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6527 { 6528 PetscFunctionBegin; 6529 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6530 PetscValidType(mat,1); 6531 if (m) PetscValidIntPointer(m,2); 6532 if (n) PetscValidIntPointer(n,3); 6533 MatCheckPreallocated(mat,1); 6534 if (m) *m = mat->cmap->rstart; 6535 if (n) *n = mat->cmap->rend; 6536 PetscFunctionReturn(0); 6537 } 6538 6539 /*@C 6540 MatGetOwnershipRange - Returns the range of matrix rows owned by 6541 this processor, assuming that the matrix is laid out with the first 6542 n1 rows on the first processor, the next n2 rows on the second, etc. 6543 For certain parallel layouts this range may not be well defined. 6544 6545 Not Collective 6546 6547 Input Parameters: 6548 . mat - the matrix 6549 6550 Output Parameters: 6551 + m - the global index of the first local row 6552 - n - one more than the global index of the last local row 6553 6554 Note: Both output parameters can be NULL on input. 6555 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6556 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6557 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6558 6559 Level: beginner 6560 6561 Concepts: matrices^row ownership 6562 6563 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6564 6565 @*/ 6566 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6567 { 6568 PetscFunctionBegin; 6569 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6570 PetscValidType(mat,1); 6571 if (m) PetscValidIntPointer(m,2); 6572 if (n) PetscValidIntPointer(n,3); 6573 MatCheckPreallocated(mat,1); 6574 if (m) *m = mat->rmap->rstart; 6575 if (n) *n = mat->rmap->rend; 6576 PetscFunctionReturn(0); 6577 } 6578 6579 /*@C 6580 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6581 each process 6582 6583 Not Collective, unless matrix has not been allocated, then collective on Mat 6584 6585 Input Parameters: 6586 . mat - the matrix 6587 6588 Output Parameters: 6589 . ranges - start of each processors portion plus one more than the total length at the end 6590 6591 Level: beginner 6592 6593 Concepts: matrices^row ownership 6594 6595 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6596 6597 @*/ 6598 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6599 { 6600 PetscErrorCode ierr; 6601 6602 PetscFunctionBegin; 6603 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6604 PetscValidType(mat,1); 6605 MatCheckPreallocated(mat,1); 6606 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6607 PetscFunctionReturn(0); 6608 } 6609 6610 /*@C 6611 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6612 this processor. (The columns of the "diagonal blocks" for each process) 6613 6614 Not Collective, unless matrix has not been allocated, then collective on Mat 6615 6616 Input Parameters: 6617 . mat - the matrix 6618 6619 Output Parameters: 6620 . ranges - start of each processors portion plus one more then the total length at the end 6621 6622 Level: beginner 6623 6624 Concepts: matrices^column ownership 6625 6626 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6627 6628 @*/ 6629 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6630 { 6631 PetscErrorCode ierr; 6632 6633 PetscFunctionBegin; 6634 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6635 PetscValidType(mat,1); 6636 MatCheckPreallocated(mat,1); 6637 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6638 PetscFunctionReturn(0); 6639 } 6640 6641 /*@C 6642 MatGetOwnershipIS - Get row and column ownership as index sets 6643 6644 Not Collective 6645 6646 Input Arguments: 6647 . A - matrix of type Elemental 6648 6649 Output Arguments: 6650 + rows - rows in which this process owns elements 6651 . cols - columns in which this process owns elements 6652 6653 Level: intermediate 6654 6655 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6656 @*/ 6657 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6658 { 6659 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6660 6661 PetscFunctionBegin; 6662 MatCheckPreallocated(A,1); 6663 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6664 if (f) { 6665 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6666 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6667 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6668 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6669 } 6670 PetscFunctionReturn(0); 6671 } 6672 6673 /*@C 6674 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6675 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6676 to complete the factorization. 6677 6678 Collective on Mat 6679 6680 Input Parameters: 6681 + mat - the matrix 6682 . row - row permutation 6683 . column - column permutation 6684 - info - structure containing 6685 $ levels - number of levels of fill. 6686 $ expected fill - as ratio of original fill. 6687 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6688 missing diagonal entries) 6689 6690 Output Parameters: 6691 . fact - new matrix that has been symbolically factored 6692 6693 Notes: 6694 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6695 6696 Most users should employ the simplified KSP interface for linear solvers 6697 instead of working directly with matrix algebra routines such as this. 6698 See, e.g., KSPCreate(). 6699 6700 Level: developer 6701 6702 Concepts: matrices^symbolic LU factorization 6703 Concepts: matrices^factorization 6704 Concepts: LU^symbolic factorization 6705 6706 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6707 MatGetOrdering(), MatFactorInfo 6708 6709 Developer Note: fortran interface is not autogenerated as the f90 6710 interface defintion cannot be generated correctly [due to MatFactorInfo] 6711 6712 @*/ 6713 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6714 { 6715 PetscErrorCode ierr; 6716 6717 PetscFunctionBegin; 6718 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6719 PetscValidType(mat,1); 6720 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6721 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6722 PetscValidPointer(info,4); 6723 PetscValidPointer(fact,5); 6724 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6725 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6726 if (!(fact)->ops->ilufactorsymbolic) { 6727 MatSolverType spackage; 6728 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6729 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6730 } 6731 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6732 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6733 MatCheckPreallocated(mat,2); 6734 6735 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6736 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6737 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6738 PetscFunctionReturn(0); 6739 } 6740 6741 /*@C 6742 MatICCFactorSymbolic - Performs symbolic incomplete 6743 Cholesky factorization for a symmetric matrix. Use 6744 MatCholeskyFactorNumeric() to complete the factorization. 6745 6746 Collective on Mat 6747 6748 Input Parameters: 6749 + mat - the matrix 6750 . perm - row and column permutation 6751 - info - structure containing 6752 $ levels - number of levels of fill. 6753 $ expected fill - as ratio of original fill. 6754 6755 Output Parameter: 6756 . fact - the factored matrix 6757 6758 Notes: 6759 Most users should employ the KSP interface for linear solvers 6760 instead of working directly with matrix algebra routines such as this. 6761 See, e.g., KSPCreate(). 6762 6763 Level: developer 6764 6765 Concepts: matrices^symbolic incomplete Cholesky factorization 6766 Concepts: matrices^factorization 6767 Concepts: Cholsky^symbolic factorization 6768 6769 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6770 6771 Developer Note: fortran interface is not autogenerated as the f90 6772 interface defintion cannot be generated correctly [due to MatFactorInfo] 6773 6774 @*/ 6775 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6776 { 6777 PetscErrorCode ierr; 6778 6779 PetscFunctionBegin; 6780 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6781 PetscValidType(mat,1); 6782 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6783 PetscValidPointer(info,3); 6784 PetscValidPointer(fact,4); 6785 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6786 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6787 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6788 if (!(fact)->ops->iccfactorsymbolic) { 6789 MatSolverType spackage; 6790 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6791 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6792 } 6793 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6794 MatCheckPreallocated(mat,2); 6795 6796 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6797 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6798 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6799 PetscFunctionReturn(0); 6800 } 6801 6802 /*@C 6803 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6804 points to an array of valid matrices, they may be reused to store the new 6805 submatrices. 6806 6807 Collective on Mat 6808 6809 Input Parameters: 6810 + mat - the matrix 6811 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6812 . irow, icol - index sets of rows and columns to extract 6813 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6814 6815 Output Parameter: 6816 . submat - the array of submatrices 6817 6818 Notes: 6819 MatCreateSubMatrices() can extract ONLY sequential submatrices 6820 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6821 to extract a parallel submatrix. 6822 6823 Some matrix types place restrictions on the row and column 6824 indices, such as that they be sorted or that they be equal to each other. 6825 6826 The index sets may not have duplicate entries. 6827 6828 When extracting submatrices from a parallel matrix, each processor can 6829 form a different submatrix by setting the rows and columns of its 6830 individual index sets according to the local submatrix desired. 6831 6832 When finished using the submatrices, the user should destroy 6833 them with MatDestroySubMatrices(). 6834 6835 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6836 original matrix has not changed from that last call to MatCreateSubMatrices(). 6837 6838 This routine creates the matrices in submat; you should NOT create them before 6839 calling it. It also allocates the array of matrix pointers submat. 6840 6841 For BAIJ matrices the index sets must respect the block structure, that is if they 6842 request one row/column in a block, they must request all rows/columns that are in 6843 that block. For example, if the block size is 2 you cannot request just row 0 and 6844 column 0. 6845 6846 Fortran Note: 6847 The Fortran interface is slightly different from that given below; it 6848 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6849 6850 Level: advanced 6851 6852 Concepts: matrices^accessing submatrices 6853 Concepts: submatrices 6854 6855 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6856 @*/ 6857 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6858 { 6859 PetscErrorCode ierr; 6860 PetscInt i; 6861 PetscBool eq; 6862 6863 PetscFunctionBegin; 6864 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6865 PetscValidType(mat,1); 6866 if (n) { 6867 PetscValidPointer(irow,3); 6868 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6869 PetscValidPointer(icol,4); 6870 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6871 } 6872 PetscValidPointer(submat,6); 6873 if (n && scall == MAT_REUSE_MATRIX) { 6874 PetscValidPointer(*submat,6); 6875 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6876 } 6877 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6878 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6879 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6880 MatCheckPreallocated(mat,1); 6881 6882 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6883 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6884 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6885 for (i=0; i<n; i++) { 6886 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6887 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6888 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6889 if (eq) { 6890 if (mat->symmetric) { 6891 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6892 } else if (mat->hermitian) { 6893 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6894 } else if (mat->structurally_symmetric) { 6895 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6896 } 6897 } 6898 } 6899 } 6900 PetscFunctionReturn(0); 6901 } 6902 6903 /*@C 6904 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6905 6906 Collective on Mat 6907 6908 Input Parameters: 6909 + mat - the matrix 6910 . n - the number of submatrixes to be extracted 6911 . irow, icol - index sets of rows and columns to extract 6912 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6913 6914 Output Parameter: 6915 . submat - the array of submatrices 6916 6917 Level: advanced 6918 6919 Concepts: matrices^accessing submatrices 6920 Concepts: submatrices 6921 6922 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6923 @*/ 6924 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6925 { 6926 PetscErrorCode ierr; 6927 PetscInt i; 6928 PetscBool eq; 6929 6930 PetscFunctionBegin; 6931 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6932 PetscValidType(mat,1); 6933 if (n) { 6934 PetscValidPointer(irow,3); 6935 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6936 PetscValidPointer(icol,4); 6937 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6938 } 6939 PetscValidPointer(submat,6); 6940 if (n && scall == MAT_REUSE_MATRIX) { 6941 PetscValidPointer(*submat,6); 6942 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6943 } 6944 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6945 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6946 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6947 MatCheckPreallocated(mat,1); 6948 6949 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6950 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6951 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6952 for (i=0; i<n; i++) { 6953 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6954 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6955 if (eq) { 6956 if (mat->symmetric) { 6957 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6958 } else if (mat->hermitian) { 6959 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6960 } else if (mat->structurally_symmetric) { 6961 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6962 } 6963 } 6964 } 6965 } 6966 PetscFunctionReturn(0); 6967 } 6968 6969 /*@C 6970 MatDestroyMatrices - Destroys an array of matrices. 6971 6972 Collective on Mat 6973 6974 Input Parameters: 6975 + n - the number of local matrices 6976 - mat - the matrices (note that this is a pointer to the array of matrices) 6977 6978 Level: advanced 6979 6980 Notes: 6981 Frees not only the matrices, but also the array that contains the matrices 6982 In Fortran will not free the array. 6983 6984 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6985 @*/ 6986 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6987 { 6988 PetscErrorCode ierr; 6989 PetscInt i; 6990 6991 PetscFunctionBegin; 6992 if (!*mat) PetscFunctionReturn(0); 6993 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6994 PetscValidPointer(mat,2); 6995 6996 for (i=0; i<n; i++) { 6997 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6998 } 6999 7000 /* memory is allocated even if n = 0 */ 7001 ierr = PetscFree(*mat);CHKERRQ(ierr); 7002 PetscFunctionReturn(0); 7003 } 7004 7005 /*@C 7006 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7007 7008 Collective on Mat 7009 7010 Input Parameters: 7011 + n - the number of local matrices 7012 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7013 sequence of MatCreateSubMatrices()) 7014 7015 Level: advanced 7016 7017 Notes: 7018 Frees not only the matrices, but also the array that contains the matrices 7019 In Fortran will not free the array. 7020 7021 .seealso: MatCreateSubMatrices() 7022 @*/ 7023 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7024 { 7025 PetscErrorCode ierr; 7026 Mat mat0; 7027 7028 PetscFunctionBegin; 7029 if (!*mat) PetscFunctionReturn(0); 7030 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7031 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 7032 PetscValidPointer(mat,2); 7033 7034 mat0 = (*mat)[0]; 7035 if (mat0 && mat0->ops->destroysubmatrices) { 7036 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 7037 } else { 7038 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 7039 } 7040 PetscFunctionReturn(0); 7041 } 7042 7043 /*@C 7044 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 7045 7046 Collective on Mat 7047 7048 Input Parameters: 7049 . mat - the matrix 7050 7051 Output Parameter: 7052 . matstruct - the sequential matrix with the nonzero structure of mat 7053 7054 Level: intermediate 7055 7056 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 7057 @*/ 7058 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7059 { 7060 PetscErrorCode ierr; 7061 7062 PetscFunctionBegin; 7063 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7064 PetscValidPointer(matstruct,2); 7065 7066 PetscValidType(mat,1); 7067 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7068 MatCheckPreallocated(mat,1); 7069 7070 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 7071 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7072 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 7073 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7074 PetscFunctionReturn(0); 7075 } 7076 7077 /*@C 7078 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7079 7080 Collective on Mat 7081 7082 Input Parameters: 7083 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7084 sequence of MatGetSequentialNonzeroStructure()) 7085 7086 Level: advanced 7087 7088 Notes: 7089 Frees not only the matrices, but also the array that contains the matrices 7090 7091 .seealso: MatGetSeqNonzeroStructure() 7092 @*/ 7093 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7094 { 7095 PetscErrorCode ierr; 7096 7097 PetscFunctionBegin; 7098 PetscValidPointer(mat,1); 7099 ierr = MatDestroy(mat);CHKERRQ(ierr); 7100 PetscFunctionReturn(0); 7101 } 7102 7103 /*@ 7104 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7105 replaces the index sets by larger ones that represent submatrices with 7106 additional overlap. 7107 7108 Collective on Mat 7109 7110 Input Parameters: 7111 + mat - the matrix 7112 . n - the number of index sets 7113 . is - the array of index sets (these index sets will changed during the call) 7114 - ov - the additional overlap requested 7115 7116 Options Database: 7117 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7118 7119 Level: developer 7120 7121 Concepts: overlap 7122 Concepts: ASM^computing overlap 7123 7124 .seealso: MatCreateSubMatrices() 7125 @*/ 7126 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7127 { 7128 PetscErrorCode ierr; 7129 7130 PetscFunctionBegin; 7131 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7132 PetscValidType(mat,1); 7133 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7134 if (n) { 7135 PetscValidPointer(is,3); 7136 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7137 } 7138 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7139 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7140 MatCheckPreallocated(mat,1); 7141 7142 if (!ov) PetscFunctionReturn(0); 7143 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7144 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7145 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 7146 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7147 PetscFunctionReturn(0); 7148 } 7149 7150 7151 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7152 7153 /*@ 7154 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7155 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7156 additional overlap. 7157 7158 Collective on Mat 7159 7160 Input Parameters: 7161 + mat - the matrix 7162 . n - the number of index sets 7163 . is - the array of index sets (these index sets will changed during the call) 7164 - ov - the additional overlap requested 7165 7166 Options Database: 7167 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7168 7169 Level: developer 7170 7171 Concepts: overlap 7172 Concepts: ASM^computing overlap 7173 7174 .seealso: MatCreateSubMatrices() 7175 @*/ 7176 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7177 { 7178 PetscInt i; 7179 PetscErrorCode ierr; 7180 7181 PetscFunctionBegin; 7182 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7183 PetscValidType(mat,1); 7184 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7185 if (n) { 7186 PetscValidPointer(is,3); 7187 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7188 } 7189 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7190 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7191 MatCheckPreallocated(mat,1); 7192 if (!ov) PetscFunctionReturn(0); 7193 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7194 for(i=0; i<n; i++){ 7195 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7196 } 7197 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7198 PetscFunctionReturn(0); 7199 } 7200 7201 7202 7203 7204 /*@ 7205 MatGetBlockSize - Returns the matrix block size. 7206 7207 Not Collective 7208 7209 Input Parameter: 7210 . mat - the matrix 7211 7212 Output Parameter: 7213 . bs - block size 7214 7215 Notes: 7216 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7217 7218 If the block size has not been set yet this routine returns 1. 7219 7220 Level: intermediate 7221 7222 Concepts: matrices^block size 7223 7224 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7225 @*/ 7226 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7227 { 7228 PetscFunctionBegin; 7229 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7230 PetscValidIntPointer(bs,2); 7231 *bs = PetscAbs(mat->rmap->bs); 7232 PetscFunctionReturn(0); 7233 } 7234 7235 /*@ 7236 MatGetBlockSizes - Returns the matrix block row and column sizes. 7237 7238 Not Collective 7239 7240 Input Parameter: 7241 . mat - the matrix 7242 7243 Output Parameter: 7244 . rbs - row block size 7245 . cbs - column block size 7246 7247 Notes: 7248 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7249 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7250 7251 If a block size has not been set yet this routine returns 1. 7252 7253 Level: intermediate 7254 7255 Concepts: matrices^block size 7256 7257 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7258 @*/ 7259 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7260 { 7261 PetscFunctionBegin; 7262 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7263 if (rbs) PetscValidIntPointer(rbs,2); 7264 if (cbs) PetscValidIntPointer(cbs,3); 7265 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7266 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7267 PetscFunctionReturn(0); 7268 } 7269 7270 /*@ 7271 MatSetBlockSize - Sets the matrix block size. 7272 7273 Logically Collective on Mat 7274 7275 Input Parameters: 7276 + mat - the matrix 7277 - bs - block size 7278 7279 Notes: 7280 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7281 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7282 7283 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7284 is compatible with the matrix local sizes. 7285 7286 Level: intermediate 7287 7288 Concepts: matrices^block size 7289 7290 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7291 @*/ 7292 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7293 { 7294 PetscErrorCode ierr; 7295 7296 PetscFunctionBegin; 7297 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7298 PetscValidLogicalCollectiveInt(mat,bs,2); 7299 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7300 PetscFunctionReturn(0); 7301 } 7302 7303 /*@ 7304 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7305 7306 Logically Collective on Mat 7307 7308 Input Parameters: 7309 + mat - the matrix 7310 . nblocks - the number of blocks on this process 7311 - bsizes - the block sizes 7312 7313 Notes: 7314 Currently used by PCVPBJACOBI for SeqAIJ matrices 7315 7316 Level: intermediate 7317 7318 Concepts: matrices^block size 7319 7320 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7321 @*/ 7322 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7323 { 7324 PetscErrorCode ierr; 7325 PetscInt i,ncnt = 0, nlocal; 7326 7327 PetscFunctionBegin; 7328 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7329 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7330 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7331 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7332 if (ncnt != nlocal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %D does not equal local size of matrix %D",ncnt,nlocal); 7333 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7334 mat->nblocks = nblocks; 7335 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7336 ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr); 7337 PetscFunctionReturn(0); 7338 } 7339 7340 /*@C 7341 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7342 7343 Logically Collective on Mat 7344 7345 Input Parameters: 7346 . mat - the matrix 7347 7348 Output Parameters: 7349 + nblocks - the number of blocks on this process 7350 - bsizes - the block sizes 7351 7352 Notes: Currently not supported from Fortran 7353 7354 Level: intermediate 7355 7356 Concepts: matrices^block size 7357 7358 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7359 @*/ 7360 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7361 { 7362 PetscFunctionBegin; 7363 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7364 *nblocks = mat->nblocks; 7365 *bsizes = mat->bsizes; 7366 PetscFunctionReturn(0); 7367 } 7368 7369 /*@ 7370 MatSetBlockSizes - Sets the matrix block row and column sizes. 7371 7372 Logically Collective on Mat 7373 7374 Input Parameters: 7375 + mat - the matrix 7376 - rbs - row block size 7377 - cbs - column block size 7378 7379 Notes: 7380 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7381 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7382 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7383 7384 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7385 are compatible with the matrix local sizes. 7386 7387 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7388 7389 Level: intermediate 7390 7391 Concepts: matrices^block size 7392 7393 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7394 @*/ 7395 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7396 { 7397 PetscErrorCode ierr; 7398 7399 PetscFunctionBegin; 7400 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7401 PetscValidLogicalCollectiveInt(mat,rbs,2); 7402 PetscValidLogicalCollectiveInt(mat,cbs,3); 7403 if (mat->ops->setblocksizes) { 7404 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7405 } 7406 if (mat->rmap->refcnt) { 7407 ISLocalToGlobalMapping l2g = NULL; 7408 PetscLayout nmap = NULL; 7409 7410 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7411 if (mat->rmap->mapping) { 7412 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7413 } 7414 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7415 mat->rmap = nmap; 7416 mat->rmap->mapping = l2g; 7417 } 7418 if (mat->cmap->refcnt) { 7419 ISLocalToGlobalMapping l2g = NULL; 7420 PetscLayout nmap = NULL; 7421 7422 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7423 if (mat->cmap->mapping) { 7424 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7425 } 7426 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7427 mat->cmap = nmap; 7428 mat->cmap->mapping = l2g; 7429 } 7430 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7431 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7432 PetscFunctionReturn(0); 7433 } 7434 7435 /*@ 7436 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7437 7438 Logically Collective on Mat 7439 7440 Input Parameters: 7441 + mat - the matrix 7442 . fromRow - matrix from which to copy row block size 7443 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7444 7445 Level: developer 7446 7447 Concepts: matrices^block size 7448 7449 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7450 @*/ 7451 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7452 { 7453 PetscErrorCode ierr; 7454 7455 PetscFunctionBegin; 7456 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7457 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7458 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7459 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7460 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7461 PetscFunctionReturn(0); 7462 } 7463 7464 /*@ 7465 MatResidual - Default routine to calculate the residual. 7466 7467 Collective on Mat and Vec 7468 7469 Input Parameters: 7470 + mat - the matrix 7471 . b - the right-hand-side 7472 - x - the approximate solution 7473 7474 Output Parameter: 7475 . r - location to store the residual 7476 7477 Level: developer 7478 7479 .keywords: MG, default, multigrid, residual 7480 7481 .seealso: PCMGSetResidual() 7482 @*/ 7483 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7484 { 7485 PetscErrorCode ierr; 7486 7487 PetscFunctionBegin; 7488 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7489 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7490 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7491 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7492 PetscValidType(mat,1); 7493 MatCheckPreallocated(mat,1); 7494 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7495 if (!mat->ops->residual) { 7496 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7497 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7498 } else { 7499 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7500 } 7501 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7502 PetscFunctionReturn(0); 7503 } 7504 7505 /*@C 7506 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7507 7508 Collective on Mat 7509 7510 Input Parameters: 7511 + mat - the matrix 7512 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7513 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7514 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7515 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7516 always used. 7517 7518 Output Parameters: 7519 + n - number of rows in the (possibly compressed) matrix 7520 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7521 . ja - the column indices 7522 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7523 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7524 7525 Level: developer 7526 7527 Notes: 7528 You CANNOT change any of the ia[] or ja[] values. 7529 7530 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7531 7532 Fortran Notes: 7533 In Fortran use 7534 $ 7535 $ PetscInt ia(1), ja(1) 7536 $ PetscOffset iia, jja 7537 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7538 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7539 7540 or 7541 $ 7542 $ PetscInt, pointer :: ia(:),ja(:) 7543 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7544 $ ! Access the ith and jth entries via ia(i) and ja(j) 7545 7546 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7547 @*/ 7548 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7549 { 7550 PetscErrorCode ierr; 7551 7552 PetscFunctionBegin; 7553 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7554 PetscValidType(mat,1); 7555 PetscValidIntPointer(n,5); 7556 if (ia) PetscValidIntPointer(ia,6); 7557 if (ja) PetscValidIntPointer(ja,7); 7558 PetscValidIntPointer(done,8); 7559 MatCheckPreallocated(mat,1); 7560 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7561 else { 7562 *done = PETSC_TRUE; 7563 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7564 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7565 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7566 } 7567 PetscFunctionReturn(0); 7568 } 7569 7570 /*@C 7571 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7572 7573 Collective on Mat 7574 7575 Input Parameters: 7576 + mat - the matrix 7577 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7578 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7579 symmetrized 7580 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7581 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7582 always used. 7583 . n - number of columns in the (possibly compressed) matrix 7584 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7585 - ja - the row indices 7586 7587 Output Parameters: 7588 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7589 7590 Level: developer 7591 7592 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7593 @*/ 7594 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7595 { 7596 PetscErrorCode ierr; 7597 7598 PetscFunctionBegin; 7599 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7600 PetscValidType(mat,1); 7601 PetscValidIntPointer(n,4); 7602 if (ia) PetscValidIntPointer(ia,5); 7603 if (ja) PetscValidIntPointer(ja,6); 7604 PetscValidIntPointer(done,7); 7605 MatCheckPreallocated(mat,1); 7606 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7607 else { 7608 *done = PETSC_TRUE; 7609 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7610 } 7611 PetscFunctionReturn(0); 7612 } 7613 7614 /*@C 7615 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7616 MatGetRowIJ(). 7617 7618 Collective on Mat 7619 7620 Input Parameters: 7621 + mat - the matrix 7622 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7623 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7624 symmetrized 7625 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7626 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7627 always used. 7628 . n - size of (possibly compressed) matrix 7629 . ia - the row pointers 7630 - ja - the column indices 7631 7632 Output Parameters: 7633 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7634 7635 Note: 7636 This routine zeros out n, ia, and ja. This is to prevent accidental 7637 us of the array after it has been restored. If you pass NULL, it will 7638 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7639 7640 Level: developer 7641 7642 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7643 @*/ 7644 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7645 { 7646 PetscErrorCode ierr; 7647 7648 PetscFunctionBegin; 7649 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7650 PetscValidType(mat,1); 7651 if (ia) PetscValidIntPointer(ia,6); 7652 if (ja) PetscValidIntPointer(ja,7); 7653 PetscValidIntPointer(done,8); 7654 MatCheckPreallocated(mat,1); 7655 7656 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7657 else { 7658 *done = PETSC_TRUE; 7659 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7660 if (n) *n = 0; 7661 if (ia) *ia = NULL; 7662 if (ja) *ja = NULL; 7663 } 7664 PetscFunctionReturn(0); 7665 } 7666 7667 /*@C 7668 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7669 MatGetColumnIJ(). 7670 7671 Collective on Mat 7672 7673 Input Parameters: 7674 + mat - the matrix 7675 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7676 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7677 symmetrized 7678 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7679 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7680 always used. 7681 7682 Output Parameters: 7683 + n - size of (possibly compressed) matrix 7684 . ia - the column pointers 7685 . ja - the row indices 7686 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7687 7688 Level: developer 7689 7690 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7691 @*/ 7692 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7693 { 7694 PetscErrorCode ierr; 7695 7696 PetscFunctionBegin; 7697 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7698 PetscValidType(mat,1); 7699 if (ia) PetscValidIntPointer(ia,5); 7700 if (ja) PetscValidIntPointer(ja,6); 7701 PetscValidIntPointer(done,7); 7702 MatCheckPreallocated(mat,1); 7703 7704 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7705 else { 7706 *done = PETSC_TRUE; 7707 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7708 if (n) *n = 0; 7709 if (ia) *ia = NULL; 7710 if (ja) *ja = NULL; 7711 } 7712 PetscFunctionReturn(0); 7713 } 7714 7715 /*@C 7716 MatColoringPatch -Used inside matrix coloring routines that 7717 use MatGetRowIJ() and/or MatGetColumnIJ(). 7718 7719 Collective on Mat 7720 7721 Input Parameters: 7722 + mat - the matrix 7723 . ncolors - max color value 7724 . n - number of entries in colorarray 7725 - colorarray - array indicating color for each column 7726 7727 Output Parameters: 7728 . iscoloring - coloring generated using colorarray information 7729 7730 Level: developer 7731 7732 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7733 7734 @*/ 7735 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7736 { 7737 PetscErrorCode ierr; 7738 7739 PetscFunctionBegin; 7740 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7741 PetscValidType(mat,1); 7742 PetscValidIntPointer(colorarray,4); 7743 PetscValidPointer(iscoloring,5); 7744 MatCheckPreallocated(mat,1); 7745 7746 if (!mat->ops->coloringpatch) { 7747 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7748 } else { 7749 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7750 } 7751 PetscFunctionReturn(0); 7752 } 7753 7754 7755 /*@ 7756 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7757 7758 Logically Collective on Mat 7759 7760 Input Parameter: 7761 . mat - the factored matrix to be reset 7762 7763 Notes: 7764 This routine should be used only with factored matrices formed by in-place 7765 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7766 format). This option can save memory, for example, when solving nonlinear 7767 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7768 ILU(0) preconditioner. 7769 7770 Note that one can specify in-place ILU(0) factorization by calling 7771 .vb 7772 PCType(pc,PCILU); 7773 PCFactorSeUseInPlace(pc); 7774 .ve 7775 or by using the options -pc_type ilu -pc_factor_in_place 7776 7777 In-place factorization ILU(0) can also be used as a local 7778 solver for the blocks within the block Jacobi or additive Schwarz 7779 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7780 for details on setting local solver options. 7781 7782 Most users should employ the simplified KSP interface for linear solvers 7783 instead of working directly with matrix algebra routines such as this. 7784 See, e.g., KSPCreate(). 7785 7786 Level: developer 7787 7788 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7789 7790 Concepts: matrices^unfactored 7791 7792 @*/ 7793 PetscErrorCode MatSetUnfactored(Mat mat) 7794 { 7795 PetscErrorCode ierr; 7796 7797 PetscFunctionBegin; 7798 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7799 PetscValidType(mat,1); 7800 MatCheckPreallocated(mat,1); 7801 mat->factortype = MAT_FACTOR_NONE; 7802 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7803 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7804 PetscFunctionReturn(0); 7805 } 7806 7807 /*MC 7808 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7809 7810 Synopsis: 7811 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7812 7813 Not collective 7814 7815 Input Parameter: 7816 . x - matrix 7817 7818 Output Parameters: 7819 + xx_v - the Fortran90 pointer to the array 7820 - ierr - error code 7821 7822 Example of Usage: 7823 .vb 7824 PetscScalar, pointer xx_v(:,:) 7825 .... 7826 call MatDenseGetArrayF90(x,xx_v,ierr) 7827 a = xx_v(3) 7828 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7829 .ve 7830 7831 Level: advanced 7832 7833 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7834 7835 Concepts: matrices^accessing array 7836 7837 M*/ 7838 7839 /*MC 7840 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7841 accessed with MatDenseGetArrayF90(). 7842 7843 Synopsis: 7844 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7845 7846 Not collective 7847 7848 Input Parameters: 7849 + x - matrix 7850 - xx_v - the Fortran90 pointer to the array 7851 7852 Output Parameter: 7853 . ierr - error code 7854 7855 Example of Usage: 7856 .vb 7857 PetscScalar, pointer xx_v(:,:) 7858 .... 7859 call MatDenseGetArrayF90(x,xx_v,ierr) 7860 a = xx_v(3) 7861 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7862 .ve 7863 7864 Level: advanced 7865 7866 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7867 7868 M*/ 7869 7870 7871 /*MC 7872 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7873 7874 Synopsis: 7875 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7876 7877 Not collective 7878 7879 Input Parameter: 7880 . x - matrix 7881 7882 Output Parameters: 7883 + xx_v - the Fortran90 pointer to the array 7884 - ierr - error code 7885 7886 Example of Usage: 7887 .vb 7888 PetscScalar, pointer xx_v(:) 7889 .... 7890 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7891 a = xx_v(3) 7892 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7893 .ve 7894 7895 Level: advanced 7896 7897 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7898 7899 Concepts: matrices^accessing array 7900 7901 M*/ 7902 7903 /*MC 7904 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7905 accessed with MatSeqAIJGetArrayF90(). 7906 7907 Synopsis: 7908 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7909 7910 Not collective 7911 7912 Input Parameters: 7913 + x - matrix 7914 - xx_v - the Fortran90 pointer to the array 7915 7916 Output Parameter: 7917 . ierr - error code 7918 7919 Example of Usage: 7920 .vb 7921 PetscScalar, pointer xx_v(:) 7922 .... 7923 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7924 a = xx_v(3) 7925 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7926 .ve 7927 7928 Level: advanced 7929 7930 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7931 7932 M*/ 7933 7934 7935 /*@ 7936 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7937 as the original matrix. 7938 7939 Collective on Mat 7940 7941 Input Parameters: 7942 + mat - the original matrix 7943 . isrow - parallel IS containing the rows this processor should obtain 7944 . 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. 7945 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7946 7947 Output Parameter: 7948 . newmat - the new submatrix, of the same type as the old 7949 7950 Level: advanced 7951 7952 Notes: 7953 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7954 7955 Some matrix types place restrictions on the row and column indices, such 7956 as that they be sorted or that they be equal to each other. 7957 7958 The index sets may not have duplicate entries. 7959 7960 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7961 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7962 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7963 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7964 you are finished using it. 7965 7966 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7967 the input matrix. 7968 7969 If iscol is NULL then all columns are obtained (not supported in Fortran). 7970 7971 Example usage: 7972 Consider the following 8x8 matrix with 34 non-zero values, that is 7973 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7974 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7975 as follows: 7976 7977 .vb 7978 1 2 0 | 0 3 0 | 0 4 7979 Proc0 0 5 6 | 7 0 0 | 8 0 7980 9 0 10 | 11 0 0 | 12 0 7981 ------------------------------------- 7982 13 0 14 | 15 16 17 | 0 0 7983 Proc1 0 18 0 | 19 20 21 | 0 0 7984 0 0 0 | 22 23 0 | 24 0 7985 ------------------------------------- 7986 Proc2 25 26 27 | 0 0 28 | 29 0 7987 30 0 0 | 31 32 33 | 0 34 7988 .ve 7989 7990 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7991 7992 .vb 7993 2 0 | 0 3 0 | 0 7994 Proc0 5 6 | 7 0 0 | 8 7995 ------------------------------- 7996 Proc1 18 0 | 19 20 21 | 0 7997 ------------------------------- 7998 Proc2 26 27 | 0 0 28 | 29 7999 0 0 | 31 32 33 | 0 8000 .ve 8001 8002 8003 Concepts: matrices^submatrices 8004 8005 .seealso: MatCreateSubMatrices() 8006 @*/ 8007 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8008 { 8009 PetscErrorCode ierr; 8010 PetscMPIInt size; 8011 Mat *local; 8012 IS iscoltmp; 8013 8014 PetscFunctionBegin; 8015 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8016 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8017 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8018 PetscValidPointer(newmat,5); 8019 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8020 PetscValidType(mat,1); 8021 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8022 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8023 8024 MatCheckPreallocated(mat,1); 8025 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8026 8027 if (!iscol || isrow == iscol) { 8028 PetscBool stride; 8029 PetscMPIInt grabentirematrix = 0,grab; 8030 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 8031 if (stride) { 8032 PetscInt first,step,n,rstart,rend; 8033 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 8034 if (step == 1) { 8035 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 8036 if (rstart == first) { 8037 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 8038 if (n == rend-rstart) { 8039 grabentirematrix = 1; 8040 } 8041 } 8042 } 8043 } 8044 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 8045 if (grab) { 8046 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 8047 if (cll == MAT_INITIAL_MATRIX) { 8048 *newmat = mat; 8049 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 8050 } 8051 PetscFunctionReturn(0); 8052 } 8053 } 8054 8055 if (!iscol) { 8056 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 8057 } else { 8058 iscoltmp = iscol; 8059 } 8060 8061 /* if original matrix is on just one processor then use submatrix generated */ 8062 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8063 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 8064 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8065 PetscFunctionReturn(0); 8066 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8067 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 8068 *newmat = *local; 8069 ierr = PetscFree(local);CHKERRQ(ierr); 8070 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8071 PetscFunctionReturn(0); 8072 } else if (!mat->ops->createsubmatrix) { 8073 /* Create a new matrix type that implements the operation using the full matrix */ 8074 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8075 switch (cll) { 8076 case MAT_INITIAL_MATRIX: 8077 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 8078 break; 8079 case MAT_REUSE_MATRIX: 8080 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 8081 break; 8082 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8083 } 8084 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8085 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8086 PetscFunctionReturn(0); 8087 } 8088 8089 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8090 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8091 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 8092 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8093 8094 /* Propagate symmetry information for diagonal blocks */ 8095 if (isrow == iscoltmp) { 8096 if (mat->symmetric_set && mat->symmetric) { 8097 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8098 } 8099 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 8100 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8101 } 8102 if (mat->hermitian_set && mat->hermitian) { 8103 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 8104 } 8105 if (mat->spd_set && mat->spd) { 8106 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 8107 } 8108 } 8109 8110 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8111 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 8112 PetscFunctionReturn(0); 8113 } 8114 8115 /*@ 8116 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8117 used during the assembly process to store values that belong to 8118 other processors. 8119 8120 Not Collective 8121 8122 Input Parameters: 8123 + mat - the matrix 8124 . size - the initial size of the stash. 8125 - bsize - the initial size of the block-stash(if used). 8126 8127 Options Database Keys: 8128 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8129 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8130 8131 Level: intermediate 8132 8133 Notes: 8134 The block-stash is used for values set with MatSetValuesBlocked() while 8135 the stash is used for values set with MatSetValues() 8136 8137 Run with the option -info and look for output of the form 8138 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8139 to determine the appropriate value, MM, to use for size and 8140 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8141 to determine the value, BMM to use for bsize 8142 8143 Concepts: stash^setting matrix size 8144 Concepts: matrices^stash 8145 8146 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 8147 8148 @*/ 8149 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8150 { 8151 PetscErrorCode ierr; 8152 8153 PetscFunctionBegin; 8154 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8155 PetscValidType(mat,1); 8156 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 8157 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 8158 PetscFunctionReturn(0); 8159 } 8160 8161 /*@ 8162 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8163 the matrix 8164 8165 Neighbor-wise Collective on Mat 8166 8167 Input Parameters: 8168 + mat - the matrix 8169 . x,y - the vectors 8170 - w - where the result is stored 8171 8172 Level: intermediate 8173 8174 Notes: 8175 w may be the same vector as y. 8176 8177 This allows one to use either the restriction or interpolation (its transpose) 8178 matrix to do the interpolation 8179 8180 Concepts: interpolation 8181 8182 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8183 8184 @*/ 8185 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8186 { 8187 PetscErrorCode ierr; 8188 PetscInt M,N,Ny; 8189 8190 PetscFunctionBegin; 8191 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8192 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8193 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8194 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8195 PetscValidType(A,1); 8196 MatCheckPreallocated(A,1); 8197 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8198 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8199 if (M == Ny) { 8200 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8201 } else { 8202 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8203 } 8204 PetscFunctionReturn(0); 8205 } 8206 8207 /*@ 8208 MatInterpolate - y = A*x or A'*x depending on the shape of 8209 the matrix 8210 8211 Neighbor-wise Collective on Mat 8212 8213 Input Parameters: 8214 + mat - the matrix 8215 - x,y - the vectors 8216 8217 Level: intermediate 8218 8219 Notes: 8220 This allows one to use either the restriction or interpolation (its transpose) 8221 matrix to do the interpolation 8222 8223 Concepts: matrices^interpolation 8224 8225 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8226 8227 @*/ 8228 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8229 { 8230 PetscErrorCode ierr; 8231 PetscInt M,N,Ny; 8232 8233 PetscFunctionBegin; 8234 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8235 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8236 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8237 PetscValidType(A,1); 8238 MatCheckPreallocated(A,1); 8239 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8240 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8241 if (M == Ny) { 8242 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8243 } else { 8244 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8245 } 8246 PetscFunctionReturn(0); 8247 } 8248 8249 /*@ 8250 MatRestrict - y = A*x or A'*x 8251 8252 Neighbor-wise Collective on Mat 8253 8254 Input Parameters: 8255 + mat - the matrix 8256 - x,y - the vectors 8257 8258 Level: intermediate 8259 8260 Notes: 8261 This allows one to use either the restriction or interpolation (its transpose) 8262 matrix to do the restriction 8263 8264 Concepts: matrices^restriction 8265 8266 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8267 8268 @*/ 8269 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8270 { 8271 PetscErrorCode ierr; 8272 PetscInt M,N,Ny; 8273 8274 PetscFunctionBegin; 8275 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8276 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8277 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8278 PetscValidType(A,1); 8279 MatCheckPreallocated(A,1); 8280 8281 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8282 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8283 if (M == Ny) { 8284 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8285 } else { 8286 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8287 } 8288 PetscFunctionReturn(0); 8289 } 8290 8291 /*@ 8292 MatGetNullSpace - retrieves the null space of a matrix. 8293 8294 Logically Collective on Mat and MatNullSpace 8295 8296 Input Parameters: 8297 + mat - the matrix 8298 - nullsp - the null space object 8299 8300 Level: developer 8301 8302 Concepts: null space^attaching to matrix 8303 8304 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8305 @*/ 8306 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8307 { 8308 PetscFunctionBegin; 8309 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8310 PetscValidPointer(nullsp,2); 8311 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8312 PetscFunctionReturn(0); 8313 } 8314 8315 /*@ 8316 MatSetNullSpace - attaches a null space to a matrix. 8317 8318 Logically Collective on Mat and MatNullSpace 8319 8320 Input Parameters: 8321 + mat - the matrix 8322 - nullsp - the null space object 8323 8324 Level: advanced 8325 8326 Notes: 8327 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8328 8329 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8330 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8331 8332 You can remove the null space by calling this routine with an nullsp of NULL 8333 8334 8335 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8336 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). 8337 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 8338 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 8339 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). 8340 8341 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8342 8343 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 8344 routine also automatically calls MatSetTransposeNullSpace(). 8345 8346 Concepts: null space^attaching to matrix 8347 8348 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8349 @*/ 8350 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8351 { 8352 PetscErrorCode ierr; 8353 8354 PetscFunctionBegin; 8355 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8356 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8357 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8358 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8359 mat->nullsp = nullsp; 8360 if (mat->symmetric_set && mat->symmetric) { 8361 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8362 } 8363 PetscFunctionReturn(0); 8364 } 8365 8366 /*@ 8367 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8368 8369 Logically Collective on Mat and MatNullSpace 8370 8371 Input Parameters: 8372 + mat - the matrix 8373 - nullsp - the null space object 8374 8375 Level: developer 8376 8377 Concepts: null space^attaching to matrix 8378 8379 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8380 @*/ 8381 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8382 { 8383 PetscFunctionBegin; 8384 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8385 PetscValidType(mat,1); 8386 PetscValidPointer(nullsp,2); 8387 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8388 PetscFunctionReturn(0); 8389 } 8390 8391 /*@ 8392 MatSetTransposeNullSpace - attaches a null space to a matrix. 8393 8394 Logically Collective on Mat and MatNullSpace 8395 8396 Input Parameters: 8397 + mat - the matrix 8398 - nullsp - the null space object 8399 8400 Level: advanced 8401 8402 Notes: 8403 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. 8404 You must also call MatSetNullSpace() 8405 8406 8407 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8408 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). 8409 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 8410 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 8411 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). 8412 8413 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8414 8415 Concepts: null space^attaching to matrix 8416 8417 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8418 @*/ 8419 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8420 { 8421 PetscErrorCode ierr; 8422 8423 PetscFunctionBegin; 8424 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8425 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8426 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8427 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8428 mat->transnullsp = nullsp; 8429 PetscFunctionReturn(0); 8430 } 8431 8432 /*@ 8433 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8434 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8435 8436 Logically Collective on Mat and MatNullSpace 8437 8438 Input Parameters: 8439 + mat - the matrix 8440 - nullsp - the null space object 8441 8442 Level: advanced 8443 8444 Notes: 8445 Overwrites any previous near null space that may have been attached 8446 8447 You can remove the null space by calling this routine with an nullsp of NULL 8448 8449 Concepts: null space^attaching to matrix 8450 8451 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8452 @*/ 8453 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8454 { 8455 PetscErrorCode ierr; 8456 8457 PetscFunctionBegin; 8458 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8459 PetscValidType(mat,1); 8460 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8461 MatCheckPreallocated(mat,1); 8462 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8463 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8464 mat->nearnullsp = nullsp; 8465 PetscFunctionReturn(0); 8466 } 8467 8468 /*@ 8469 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8470 8471 Not Collective 8472 8473 Input Parameters: 8474 . mat - the matrix 8475 8476 Output Parameters: 8477 . nullsp - the null space object, NULL if not set 8478 8479 Level: developer 8480 8481 Concepts: null space^attaching to matrix 8482 8483 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8484 @*/ 8485 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8486 { 8487 PetscFunctionBegin; 8488 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8489 PetscValidType(mat,1); 8490 PetscValidPointer(nullsp,2); 8491 MatCheckPreallocated(mat,1); 8492 *nullsp = mat->nearnullsp; 8493 PetscFunctionReturn(0); 8494 } 8495 8496 /*@C 8497 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8498 8499 Collective on Mat 8500 8501 Input Parameters: 8502 + mat - the matrix 8503 . row - row/column permutation 8504 . fill - expected fill factor >= 1.0 8505 - level - level of fill, for ICC(k) 8506 8507 Notes: 8508 Probably really in-place only when level of fill is zero, otherwise allocates 8509 new space to store factored matrix and deletes previous memory. 8510 8511 Most users should employ the simplified KSP interface for linear solvers 8512 instead of working directly with matrix algebra routines such as this. 8513 See, e.g., KSPCreate(). 8514 8515 Level: developer 8516 8517 Concepts: matrices^incomplete Cholesky factorization 8518 Concepts: Cholesky factorization 8519 8520 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8521 8522 Developer Note: fortran interface is not autogenerated as the f90 8523 interface defintion cannot be generated correctly [due to MatFactorInfo] 8524 8525 @*/ 8526 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8527 { 8528 PetscErrorCode ierr; 8529 8530 PetscFunctionBegin; 8531 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8532 PetscValidType(mat,1); 8533 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8534 PetscValidPointer(info,3); 8535 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8536 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8537 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8538 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8539 MatCheckPreallocated(mat,1); 8540 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8541 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8542 PetscFunctionReturn(0); 8543 } 8544 8545 /*@ 8546 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8547 ghosted ones. 8548 8549 Not Collective 8550 8551 Input Parameters: 8552 + mat - the matrix 8553 - diag = the diagonal values, including ghost ones 8554 8555 Level: developer 8556 8557 Notes: 8558 Works only for MPIAIJ and MPIBAIJ matrices 8559 8560 .seealso: MatDiagonalScale() 8561 @*/ 8562 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8563 { 8564 PetscErrorCode ierr; 8565 PetscMPIInt size; 8566 8567 PetscFunctionBegin; 8568 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8569 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8570 PetscValidType(mat,1); 8571 8572 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8573 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8574 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8575 if (size == 1) { 8576 PetscInt n,m; 8577 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8578 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8579 if (m == n) { 8580 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8581 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8582 } else { 8583 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8584 } 8585 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8586 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8587 PetscFunctionReturn(0); 8588 } 8589 8590 /*@ 8591 MatGetInertia - Gets the inertia from a factored matrix 8592 8593 Collective on Mat 8594 8595 Input Parameter: 8596 . mat - the matrix 8597 8598 Output Parameters: 8599 + nneg - number of negative eigenvalues 8600 . nzero - number of zero eigenvalues 8601 - npos - number of positive eigenvalues 8602 8603 Level: advanced 8604 8605 Notes: 8606 Matrix must have been factored by MatCholeskyFactor() 8607 8608 8609 @*/ 8610 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8611 { 8612 PetscErrorCode ierr; 8613 8614 PetscFunctionBegin; 8615 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8616 PetscValidType(mat,1); 8617 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8618 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8619 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8620 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8621 PetscFunctionReturn(0); 8622 } 8623 8624 /* ----------------------------------------------------------------*/ 8625 /*@C 8626 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8627 8628 Neighbor-wise Collective on Mat and Vecs 8629 8630 Input Parameters: 8631 + mat - the factored matrix 8632 - b - the right-hand-side vectors 8633 8634 Output Parameter: 8635 . x - the result vectors 8636 8637 Notes: 8638 The vectors b and x cannot be the same. I.e., one cannot 8639 call MatSolves(A,x,x). 8640 8641 Notes: 8642 Most users should employ the simplified KSP interface for linear solvers 8643 instead of working directly with matrix algebra routines such as this. 8644 See, e.g., KSPCreate(). 8645 8646 Level: developer 8647 8648 Concepts: matrices^triangular solves 8649 8650 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8651 @*/ 8652 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8653 { 8654 PetscErrorCode ierr; 8655 8656 PetscFunctionBegin; 8657 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8658 PetscValidType(mat,1); 8659 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8660 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8661 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8662 8663 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8664 MatCheckPreallocated(mat,1); 8665 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8666 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8667 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8668 PetscFunctionReturn(0); 8669 } 8670 8671 /*@ 8672 MatIsSymmetric - Test whether a matrix is symmetric 8673 8674 Collective on Mat 8675 8676 Input Parameter: 8677 + A - the matrix to test 8678 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8679 8680 Output Parameters: 8681 . flg - the result 8682 8683 Notes: 8684 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8685 8686 Level: intermediate 8687 8688 Concepts: matrix^symmetry 8689 8690 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8691 @*/ 8692 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8693 { 8694 PetscErrorCode ierr; 8695 8696 PetscFunctionBegin; 8697 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8698 PetscValidPointer(flg,2); 8699 8700 if (!A->symmetric_set) { 8701 if (!A->ops->issymmetric) { 8702 MatType mattype; 8703 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8704 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8705 } 8706 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8707 if (!tol) { 8708 A->symmetric_set = PETSC_TRUE; 8709 A->symmetric = *flg; 8710 if (A->symmetric) { 8711 A->structurally_symmetric_set = PETSC_TRUE; 8712 A->structurally_symmetric = PETSC_TRUE; 8713 } 8714 } 8715 } else if (A->symmetric) { 8716 *flg = PETSC_TRUE; 8717 } else if (!tol) { 8718 *flg = PETSC_FALSE; 8719 } else { 8720 if (!A->ops->issymmetric) { 8721 MatType mattype; 8722 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8723 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8724 } 8725 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8726 } 8727 PetscFunctionReturn(0); 8728 } 8729 8730 /*@ 8731 MatIsHermitian - Test whether a matrix is Hermitian 8732 8733 Collective on Mat 8734 8735 Input Parameter: 8736 + A - the matrix to test 8737 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8738 8739 Output Parameters: 8740 . flg - the result 8741 8742 Level: intermediate 8743 8744 Concepts: matrix^symmetry 8745 8746 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8747 MatIsSymmetricKnown(), MatIsSymmetric() 8748 @*/ 8749 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8750 { 8751 PetscErrorCode ierr; 8752 8753 PetscFunctionBegin; 8754 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8755 PetscValidPointer(flg,2); 8756 8757 if (!A->hermitian_set) { 8758 if (!A->ops->ishermitian) { 8759 MatType mattype; 8760 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8761 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8762 } 8763 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8764 if (!tol) { 8765 A->hermitian_set = PETSC_TRUE; 8766 A->hermitian = *flg; 8767 if (A->hermitian) { 8768 A->structurally_symmetric_set = PETSC_TRUE; 8769 A->structurally_symmetric = PETSC_TRUE; 8770 } 8771 } 8772 } else if (A->hermitian) { 8773 *flg = PETSC_TRUE; 8774 } else if (!tol) { 8775 *flg = PETSC_FALSE; 8776 } else { 8777 if (!A->ops->ishermitian) { 8778 MatType mattype; 8779 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8780 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8781 } 8782 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8783 } 8784 PetscFunctionReturn(0); 8785 } 8786 8787 /*@ 8788 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8789 8790 Not Collective 8791 8792 Input Parameter: 8793 . A - the matrix to check 8794 8795 Output Parameters: 8796 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8797 - flg - the result 8798 8799 Level: advanced 8800 8801 Concepts: matrix^symmetry 8802 8803 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8804 if you want it explicitly checked 8805 8806 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8807 @*/ 8808 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8809 { 8810 PetscFunctionBegin; 8811 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8812 PetscValidPointer(set,2); 8813 PetscValidPointer(flg,3); 8814 if (A->symmetric_set) { 8815 *set = PETSC_TRUE; 8816 *flg = A->symmetric; 8817 } else { 8818 *set = PETSC_FALSE; 8819 } 8820 PetscFunctionReturn(0); 8821 } 8822 8823 /*@ 8824 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8825 8826 Not Collective 8827 8828 Input Parameter: 8829 . A - the matrix to check 8830 8831 Output Parameters: 8832 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8833 - flg - the result 8834 8835 Level: advanced 8836 8837 Concepts: matrix^symmetry 8838 8839 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8840 if you want it explicitly checked 8841 8842 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8843 @*/ 8844 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8845 { 8846 PetscFunctionBegin; 8847 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8848 PetscValidPointer(set,2); 8849 PetscValidPointer(flg,3); 8850 if (A->hermitian_set) { 8851 *set = PETSC_TRUE; 8852 *flg = A->hermitian; 8853 } else { 8854 *set = PETSC_FALSE; 8855 } 8856 PetscFunctionReturn(0); 8857 } 8858 8859 /*@ 8860 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8861 8862 Collective on Mat 8863 8864 Input Parameter: 8865 . A - the matrix to test 8866 8867 Output Parameters: 8868 . flg - the result 8869 8870 Level: intermediate 8871 8872 Concepts: matrix^symmetry 8873 8874 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8875 @*/ 8876 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8877 { 8878 PetscErrorCode ierr; 8879 8880 PetscFunctionBegin; 8881 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8882 PetscValidPointer(flg,2); 8883 if (!A->structurally_symmetric_set) { 8884 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8885 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8886 8887 A->structurally_symmetric_set = PETSC_TRUE; 8888 } 8889 *flg = A->structurally_symmetric; 8890 PetscFunctionReturn(0); 8891 } 8892 8893 /*@ 8894 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8895 to be communicated to other processors during the MatAssemblyBegin/End() process 8896 8897 Not collective 8898 8899 Input Parameter: 8900 . vec - the vector 8901 8902 Output Parameters: 8903 + nstash - the size of the stash 8904 . reallocs - the number of additional mallocs incurred. 8905 . bnstash - the size of the block stash 8906 - breallocs - the number of additional mallocs incurred.in the block stash 8907 8908 Level: advanced 8909 8910 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8911 8912 @*/ 8913 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8914 { 8915 PetscErrorCode ierr; 8916 8917 PetscFunctionBegin; 8918 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8919 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8920 PetscFunctionReturn(0); 8921 } 8922 8923 /*@C 8924 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8925 parallel layout 8926 8927 Collective on Mat 8928 8929 Input Parameter: 8930 . mat - the matrix 8931 8932 Output Parameter: 8933 + right - (optional) vector that the matrix can be multiplied against 8934 - left - (optional) vector that the matrix vector product can be stored in 8935 8936 Notes: 8937 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(). 8938 8939 Notes: 8940 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8941 8942 Level: advanced 8943 8944 .seealso: MatCreate(), VecDestroy() 8945 @*/ 8946 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8947 { 8948 PetscErrorCode ierr; 8949 8950 PetscFunctionBegin; 8951 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8952 PetscValidType(mat,1); 8953 if (mat->ops->getvecs) { 8954 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8955 } else { 8956 PetscInt rbs,cbs; 8957 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8958 if (right) { 8959 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8960 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8961 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8962 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8963 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8964 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8965 } 8966 if (left) { 8967 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8968 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8969 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8970 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8971 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8972 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8973 } 8974 } 8975 PetscFunctionReturn(0); 8976 } 8977 8978 /*@C 8979 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8980 with default values. 8981 8982 Not Collective 8983 8984 Input Parameters: 8985 . info - the MatFactorInfo data structure 8986 8987 8988 Notes: 8989 The solvers are generally used through the KSP and PC objects, for example 8990 PCLU, PCILU, PCCHOLESKY, PCICC 8991 8992 Level: developer 8993 8994 .seealso: MatFactorInfo 8995 8996 Developer Note: fortran interface is not autogenerated as the f90 8997 interface defintion cannot be generated correctly [due to MatFactorInfo] 8998 8999 @*/ 9000 9001 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9002 { 9003 PetscErrorCode ierr; 9004 9005 PetscFunctionBegin; 9006 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 9007 PetscFunctionReturn(0); 9008 } 9009 9010 /*@ 9011 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9012 9013 Collective on Mat 9014 9015 Input Parameters: 9016 + mat - the factored matrix 9017 - is - the index set defining the Schur indices (0-based) 9018 9019 Notes: 9020 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9021 9022 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9023 9024 Level: developer 9025 9026 Concepts: 9027 9028 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 9029 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 9030 9031 @*/ 9032 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9033 { 9034 PetscErrorCode ierr,(*f)(Mat,IS); 9035 9036 PetscFunctionBegin; 9037 PetscValidType(mat,1); 9038 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9039 PetscValidType(is,2); 9040 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9041 PetscCheckSameComm(mat,1,is,2); 9042 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9043 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 9044 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"); 9045 if (mat->schur) { 9046 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 9047 } 9048 ierr = (*f)(mat,is);CHKERRQ(ierr); 9049 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9050 ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr); 9051 PetscFunctionReturn(0); 9052 } 9053 9054 /*@ 9055 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9056 9057 Logically Collective on Mat 9058 9059 Input Parameters: 9060 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9061 . S - location where to return the Schur complement, can be NULL 9062 - status - the status of the Schur complement matrix, can be NULL 9063 9064 Notes: 9065 You must call MatFactorSetSchurIS() before calling this routine. 9066 9067 The routine provides a copy of the Schur matrix stored within the solver data structures. 9068 The caller must destroy the object when it is no longer needed. 9069 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9070 9071 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) 9072 9073 Developer Notes: 9074 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9075 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9076 9077 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9078 9079 Level: advanced 9080 9081 References: 9082 9083 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 9084 @*/ 9085 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9086 { 9087 PetscErrorCode ierr; 9088 9089 PetscFunctionBegin; 9090 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9091 if (S) PetscValidPointer(S,2); 9092 if (status) PetscValidPointer(status,3); 9093 if (S) { 9094 PetscErrorCode (*f)(Mat,Mat*); 9095 9096 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 9097 if (f) { 9098 ierr = (*f)(F,S);CHKERRQ(ierr); 9099 } else { 9100 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 9101 } 9102 } 9103 if (status) *status = F->schur_status; 9104 PetscFunctionReturn(0); 9105 } 9106 9107 /*@ 9108 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9109 9110 Logically Collective on Mat 9111 9112 Input Parameters: 9113 + F - the factored matrix obtained by calling MatGetFactor() 9114 . *S - location where to return the Schur complement, can be NULL 9115 - status - the status of the Schur complement matrix, can be NULL 9116 9117 Notes: 9118 You must call MatFactorSetSchurIS() before calling this routine. 9119 9120 Schur complement mode is currently implemented for sequential matrices. 9121 The routine returns a the Schur Complement stored within the data strutures of the solver. 9122 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9123 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9124 9125 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9126 9127 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9128 9129 Level: advanced 9130 9131 References: 9132 9133 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9134 @*/ 9135 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9136 { 9137 PetscFunctionBegin; 9138 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9139 if (S) PetscValidPointer(S,2); 9140 if (status) PetscValidPointer(status,3); 9141 if (S) *S = F->schur; 9142 if (status) *status = F->schur_status; 9143 PetscFunctionReturn(0); 9144 } 9145 9146 /*@ 9147 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9148 9149 Logically Collective on Mat 9150 9151 Input Parameters: 9152 + F - the factored matrix obtained by calling MatGetFactor() 9153 . *S - location where the Schur complement is stored 9154 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9155 9156 Notes: 9157 9158 Level: advanced 9159 9160 References: 9161 9162 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9163 @*/ 9164 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9165 { 9166 PetscErrorCode ierr; 9167 9168 PetscFunctionBegin; 9169 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9170 if (S) { 9171 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9172 *S = NULL; 9173 } 9174 F->schur_status = status; 9175 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 9176 PetscFunctionReturn(0); 9177 } 9178 9179 /*@ 9180 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9181 9182 Logically Collective on Mat 9183 9184 Input Parameters: 9185 + F - the factored matrix obtained by calling MatGetFactor() 9186 . rhs - location where the right hand side of the Schur complement system is stored 9187 - sol - location where the solution of the Schur complement system has to be returned 9188 9189 Notes: 9190 The sizes of the vectors should match the size of the Schur complement 9191 9192 Must be called after MatFactorSetSchurIS() 9193 9194 Level: advanced 9195 9196 References: 9197 9198 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 9199 @*/ 9200 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9201 { 9202 PetscErrorCode ierr; 9203 9204 PetscFunctionBegin; 9205 PetscValidType(F,1); 9206 PetscValidType(rhs,2); 9207 PetscValidType(sol,3); 9208 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9209 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9210 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9211 PetscCheckSameComm(F,1,rhs,2); 9212 PetscCheckSameComm(F,1,sol,3); 9213 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9214 switch (F->schur_status) { 9215 case MAT_FACTOR_SCHUR_FACTORED: 9216 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9217 break; 9218 case MAT_FACTOR_SCHUR_INVERTED: 9219 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9220 break; 9221 default: 9222 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9223 break; 9224 } 9225 PetscFunctionReturn(0); 9226 } 9227 9228 /*@ 9229 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9230 9231 Logically Collective on Mat 9232 9233 Input Parameters: 9234 + F - the factored matrix obtained by calling MatGetFactor() 9235 . rhs - location where the right hand side of the Schur complement system is stored 9236 - sol - location where the solution of the Schur complement system has to be returned 9237 9238 Notes: 9239 The sizes of the vectors should match the size of the Schur complement 9240 9241 Must be called after MatFactorSetSchurIS() 9242 9243 Level: advanced 9244 9245 References: 9246 9247 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9248 @*/ 9249 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9250 { 9251 PetscErrorCode ierr; 9252 9253 PetscFunctionBegin; 9254 PetscValidType(F,1); 9255 PetscValidType(rhs,2); 9256 PetscValidType(sol,3); 9257 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9258 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9259 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9260 PetscCheckSameComm(F,1,rhs,2); 9261 PetscCheckSameComm(F,1,sol,3); 9262 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9263 switch (F->schur_status) { 9264 case MAT_FACTOR_SCHUR_FACTORED: 9265 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9266 break; 9267 case MAT_FACTOR_SCHUR_INVERTED: 9268 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9269 break; 9270 default: 9271 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9272 break; 9273 } 9274 PetscFunctionReturn(0); 9275 } 9276 9277 /*@ 9278 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9279 9280 Logically Collective on Mat 9281 9282 Input Parameters: 9283 + F - the factored matrix obtained by calling MatGetFactor() 9284 9285 Notes: 9286 Must be called after MatFactorSetSchurIS(). 9287 9288 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9289 9290 Level: advanced 9291 9292 References: 9293 9294 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9295 @*/ 9296 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9297 { 9298 PetscErrorCode ierr; 9299 9300 PetscFunctionBegin; 9301 PetscValidType(F,1); 9302 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9303 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9304 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9305 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9306 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9307 PetscFunctionReturn(0); 9308 } 9309 9310 /*@ 9311 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9312 9313 Logically Collective on Mat 9314 9315 Input Parameters: 9316 + F - the factored matrix obtained by calling MatGetFactor() 9317 9318 Notes: 9319 Must be called after MatFactorSetSchurIS(). 9320 9321 Level: advanced 9322 9323 References: 9324 9325 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9326 @*/ 9327 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9328 { 9329 PetscErrorCode ierr; 9330 9331 PetscFunctionBegin; 9332 PetscValidType(F,1); 9333 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9334 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9335 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9336 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9337 PetscFunctionReturn(0); 9338 } 9339 9340 /*@ 9341 MatPtAP - Creates the matrix product C = P^T * A * P 9342 9343 Neighbor-wise Collective on Mat 9344 9345 Input Parameters: 9346 + A - the matrix 9347 . P - the projection matrix 9348 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9349 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9350 if the result is a dense matrix this is irrelevent 9351 9352 Output Parameters: 9353 . C - the product matrix 9354 9355 Notes: 9356 C will be created and must be destroyed by the user with MatDestroy(). 9357 9358 This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes 9359 which inherit from AIJ. 9360 9361 Level: intermediate 9362 9363 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9364 @*/ 9365 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9366 { 9367 PetscErrorCode ierr; 9368 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9369 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9370 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9371 PetscBool sametype; 9372 9373 PetscFunctionBegin; 9374 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9375 PetscValidType(A,1); 9376 MatCheckPreallocated(A,1); 9377 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9378 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9379 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9380 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9381 PetscValidType(P,2); 9382 MatCheckPreallocated(P,2); 9383 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9384 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9385 9386 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); 9387 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); 9388 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9389 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9390 9391 if (scall == MAT_REUSE_MATRIX) { 9392 PetscValidPointer(*C,5); 9393 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9394 9395 if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX"); 9396 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9397 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9398 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9399 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9400 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9401 PetscFunctionReturn(0); 9402 } 9403 9404 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9405 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9406 9407 fA = A->ops->ptap; 9408 fP = P->ops->ptap; 9409 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9410 if (fP == fA && sametype) { 9411 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 9412 ptap = fA; 9413 } else { 9414 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9415 char ptapname[256]; 9416 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9417 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9418 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9419 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9420 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9421 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9422 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); 9423 } 9424 9425 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9426 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9427 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9428 if (A->symmetric_set && A->symmetric) { 9429 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9430 } 9431 PetscFunctionReturn(0); 9432 } 9433 9434 /*@ 9435 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9436 9437 Neighbor-wise Collective on Mat 9438 9439 Input Parameters: 9440 + A - the matrix 9441 - P - the projection matrix 9442 9443 Output Parameters: 9444 . C - the product matrix 9445 9446 Notes: 9447 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9448 the user using MatDeatroy(). 9449 9450 This routine is currently only implemented for pairs of AIJ matrices and classes 9451 which inherit from AIJ. C will be of type MATAIJ. 9452 9453 Level: intermediate 9454 9455 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9456 @*/ 9457 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9458 { 9459 PetscErrorCode ierr; 9460 9461 PetscFunctionBegin; 9462 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9463 PetscValidType(A,1); 9464 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9465 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9466 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9467 PetscValidType(P,2); 9468 MatCheckPreallocated(P,2); 9469 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9470 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9471 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9472 PetscValidType(C,3); 9473 MatCheckPreallocated(C,3); 9474 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9475 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); 9476 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); 9477 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); 9478 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); 9479 MatCheckPreallocated(A,1); 9480 9481 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9482 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9483 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9484 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9485 PetscFunctionReturn(0); 9486 } 9487 9488 /*@ 9489 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9490 9491 Neighbor-wise Collective on Mat 9492 9493 Input Parameters: 9494 + A - the matrix 9495 - P - the projection matrix 9496 9497 Output Parameters: 9498 . C - the (i,j) structure of the product matrix 9499 9500 Notes: 9501 C will be created and must be destroyed by the user with MatDestroy(). 9502 9503 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9504 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9505 this (i,j) structure by calling MatPtAPNumeric(). 9506 9507 Level: intermediate 9508 9509 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9510 @*/ 9511 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9512 { 9513 PetscErrorCode ierr; 9514 9515 PetscFunctionBegin; 9516 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9517 PetscValidType(A,1); 9518 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9519 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9520 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9521 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9522 PetscValidType(P,2); 9523 MatCheckPreallocated(P,2); 9524 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9525 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9526 PetscValidPointer(C,3); 9527 9528 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); 9529 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); 9530 MatCheckPreallocated(A,1); 9531 9532 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9533 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9534 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9535 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9536 9537 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9538 PetscFunctionReturn(0); 9539 } 9540 9541 /*@ 9542 MatRARt - Creates the matrix product C = R * A * R^T 9543 9544 Neighbor-wise Collective on Mat 9545 9546 Input Parameters: 9547 + A - the matrix 9548 . R - the projection matrix 9549 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9550 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9551 if the result is a dense matrix this is irrelevent 9552 9553 Output Parameters: 9554 . C - the product matrix 9555 9556 Notes: 9557 C will be created and must be destroyed by the user with MatDestroy(). 9558 9559 This routine is currently only implemented for pairs of AIJ matrices and classes 9560 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9561 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9562 We recommend using MatPtAP(). 9563 9564 Level: intermediate 9565 9566 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9567 @*/ 9568 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9569 { 9570 PetscErrorCode ierr; 9571 9572 PetscFunctionBegin; 9573 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9574 PetscValidType(A,1); 9575 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9576 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9577 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9578 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9579 PetscValidType(R,2); 9580 MatCheckPreallocated(R,2); 9581 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9582 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9583 PetscValidPointer(C,3); 9584 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); 9585 9586 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9587 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9588 MatCheckPreallocated(A,1); 9589 9590 if (!A->ops->rart) { 9591 Mat Rt; 9592 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9593 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9594 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9595 PetscFunctionReturn(0); 9596 } 9597 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9598 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9599 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9600 PetscFunctionReturn(0); 9601 } 9602 9603 /*@ 9604 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9605 9606 Neighbor-wise Collective on Mat 9607 9608 Input Parameters: 9609 + A - the matrix 9610 - R - the projection matrix 9611 9612 Output Parameters: 9613 . C - the product matrix 9614 9615 Notes: 9616 C must have been created by calling MatRARtSymbolic and must be destroyed by 9617 the user using MatDestroy(). 9618 9619 This routine is currently only implemented for pairs of AIJ matrices and classes 9620 which inherit from AIJ. C will be of type MATAIJ. 9621 9622 Level: intermediate 9623 9624 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9625 @*/ 9626 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9627 { 9628 PetscErrorCode ierr; 9629 9630 PetscFunctionBegin; 9631 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9632 PetscValidType(A,1); 9633 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9634 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9635 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9636 PetscValidType(R,2); 9637 MatCheckPreallocated(R,2); 9638 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9639 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9640 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9641 PetscValidType(C,3); 9642 MatCheckPreallocated(C,3); 9643 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9644 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); 9645 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); 9646 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); 9647 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); 9648 MatCheckPreallocated(A,1); 9649 9650 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9651 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9652 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9653 PetscFunctionReturn(0); 9654 } 9655 9656 /*@ 9657 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9658 9659 Neighbor-wise Collective on Mat 9660 9661 Input Parameters: 9662 + A - the matrix 9663 - R - the projection matrix 9664 9665 Output Parameters: 9666 . C - the (i,j) structure of the product matrix 9667 9668 Notes: 9669 C will be created and must be destroyed by the user with MatDestroy(). 9670 9671 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9672 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9673 this (i,j) structure by calling MatRARtNumeric(). 9674 9675 Level: intermediate 9676 9677 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9678 @*/ 9679 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9680 { 9681 PetscErrorCode ierr; 9682 9683 PetscFunctionBegin; 9684 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9685 PetscValidType(A,1); 9686 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9687 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9688 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9689 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9690 PetscValidType(R,2); 9691 MatCheckPreallocated(R,2); 9692 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9693 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9694 PetscValidPointer(C,3); 9695 9696 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); 9697 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); 9698 MatCheckPreallocated(A,1); 9699 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9700 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9701 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9702 9703 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9704 PetscFunctionReturn(0); 9705 } 9706 9707 /*@ 9708 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9709 9710 Neighbor-wise Collective on Mat 9711 9712 Input Parameters: 9713 + A - the left matrix 9714 . B - the right matrix 9715 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9716 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9717 if the result is a dense matrix this is irrelevent 9718 9719 Output Parameters: 9720 . C - the product matrix 9721 9722 Notes: 9723 Unless scall is MAT_REUSE_MATRIX C will be created. 9724 9725 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 9726 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9727 9728 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9729 actually needed. 9730 9731 If you have many matrices with the same non-zero structure to multiply, you 9732 should either 9733 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9734 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9735 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 9736 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9737 9738 Level: intermediate 9739 9740 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9741 @*/ 9742 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9743 { 9744 PetscErrorCode ierr; 9745 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9746 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9747 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9748 9749 PetscFunctionBegin; 9750 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9751 PetscValidType(A,1); 9752 MatCheckPreallocated(A,1); 9753 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9754 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9755 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9756 PetscValidType(B,2); 9757 MatCheckPreallocated(B,2); 9758 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9759 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9760 PetscValidPointer(C,3); 9761 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9762 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); 9763 if (scall == MAT_REUSE_MATRIX) { 9764 PetscValidPointer(*C,5); 9765 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9766 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9767 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9768 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9769 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9770 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9771 PetscFunctionReturn(0); 9772 } 9773 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9774 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9775 9776 fA = A->ops->matmult; 9777 fB = B->ops->matmult; 9778 if (fB == fA) { 9779 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9780 mult = fB; 9781 } else { 9782 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9783 char multname[256]; 9784 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9785 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9786 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9787 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9788 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9789 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9790 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); 9791 } 9792 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9793 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9794 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9795 PetscFunctionReturn(0); 9796 } 9797 9798 /*@ 9799 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9800 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9801 9802 Neighbor-wise Collective on Mat 9803 9804 Input Parameters: 9805 + A - the left matrix 9806 . B - the right matrix 9807 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9808 if C is a dense matrix this is irrelevent 9809 9810 Output Parameters: 9811 . C - the product matrix 9812 9813 Notes: 9814 Unless scall is MAT_REUSE_MATRIX C will be created. 9815 9816 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9817 actually needed. 9818 9819 This routine is currently implemented for 9820 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9821 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9822 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9823 9824 Level: intermediate 9825 9826 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 9827 We should incorporate them into PETSc. 9828 9829 .seealso: MatMatMult(), MatMatMultNumeric() 9830 @*/ 9831 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9832 { 9833 PetscErrorCode ierr; 9834 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9835 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9836 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9837 9838 PetscFunctionBegin; 9839 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9840 PetscValidType(A,1); 9841 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9842 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9843 9844 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9845 PetscValidType(B,2); 9846 MatCheckPreallocated(B,2); 9847 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9848 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9849 PetscValidPointer(C,3); 9850 9851 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); 9852 if (fill == PETSC_DEFAULT) fill = 2.0; 9853 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9854 MatCheckPreallocated(A,1); 9855 9856 Asymbolic = A->ops->matmultsymbolic; 9857 Bsymbolic = B->ops->matmultsymbolic; 9858 if (Asymbolic == Bsymbolic) { 9859 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9860 symbolic = Bsymbolic; 9861 } else { /* dispatch based on the type of A and B */ 9862 char symbolicname[256]; 9863 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9864 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9865 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9866 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9867 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9868 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9869 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); 9870 } 9871 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9872 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9873 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9874 PetscFunctionReturn(0); 9875 } 9876 9877 /*@ 9878 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9879 Call this routine after first calling MatMatMultSymbolic(). 9880 9881 Neighbor-wise Collective on Mat 9882 9883 Input Parameters: 9884 + A - the left matrix 9885 - B - the right matrix 9886 9887 Output Parameters: 9888 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9889 9890 Notes: 9891 C must have been created with MatMatMultSymbolic(). 9892 9893 This routine is currently implemented for 9894 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9895 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9896 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9897 9898 Level: intermediate 9899 9900 .seealso: MatMatMult(), MatMatMultSymbolic() 9901 @*/ 9902 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9903 { 9904 PetscErrorCode ierr; 9905 9906 PetscFunctionBegin; 9907 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9908 PetscFunctionReturn(0); 9909 } 9910 9911 /*@ 9912 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9913 9914 Neighbor-wise Collective on Mat 9915 9916 Input Parameters: 9917 + A - the left matrix 9918 . B - the right matrix 9919 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9920 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9921 9922 Output Parameters: 9923 . C - the product matrix 9924 9925 Notes: 9926 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9927 9928 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9929 9930 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9931 actually needed. 9932 9933 This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class. 9934 9935 Level: intermediate 9936 9937 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9938 @*/ 9939 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9940 { 9941 PetscErrorCode ierr; 9942 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9943 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9944 9945 PetscFunctionBegin; 9946 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9947 PetscValidType(A,1); 9948 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9949 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9950 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9951 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9952 PetscValidType(B,2); 9953 MatCheckPreallocated(B,2); 9954 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9955 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9956 PetscValidPointer(C,3); 9957 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); 9958 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9959 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9960 MatCheckPreallocated(A,1); 9961 9962 fA = A->ops->mattransposemult; 9963 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9964 fB = B->ops->mattransposemult; 9965 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9966 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); 9967 9968 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9969 if (scall == MAT_INITIAL_MATRIX) { 9970 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9971 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9972 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9973 } 9974 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9975 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9976 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9977 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9978 PetscFunctionReturn(0); 9979 } 9980 9981 /*@ 9982 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9983 9984 Neighbor-wise Collective on Mat 9985 9986 Input Parameters: 9987 + A - the left matrix 9988 . B - the right matrix 9989 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9990 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9991 9992 Output Parameters: 9993 . C - the product matrix 9994 9995 Notes: 9996 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9997 9998 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9999 10000 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10001 actually needed. 10002 10003 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 10004 which inherit from SeqAIJ. C will be of same type as the input matrices. 10005 10006 Level: intermediate 10007 10008 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 10009 @*/ 10010 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10011 { 10012 PetscErrorCode ierr; 10013 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 10014 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 10015 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 10016 10017 PetscFunctionBegin; 10018 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10019 PetscValidType(A,1); 10020 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10021 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10022 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10023 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10024 PetscValidType(B,2); 10025 MatCheckPreallocated(B,2); 10026 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10027 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10028 PetscValidPointer(C,3); 10029 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); 10030 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10031 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 10032 MatCheckPreallocated(A,1); 10033 10034 fA = A->ops->transposematmult; 10035 fB = B->ops->transposematmult; 10036 if (fB==fA) { 10037 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 10038 transposematmult = fA; 10039 } else { 10040 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 10041 char multname[256]; 10042 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 10043 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10044 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10045 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10046 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 10047 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 10048 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); 10049 } 10050 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 10051 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 10052 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 10053 PetscFunctionReturn(0); 10054 } 10055 10056 /*@ 10057 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 10058 10059 Neighbor-wise Collective on Mat 10060 10061 Input Parameters: 10062 + A - the left matrix 10063 . B - the middle matrix 10064 . C - the right matrix 10065 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10066 - 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 10067 if the result is a dense matrix this is irrelevent 10068 10069 Output Parameters: 10070 . D - the product matrix 10071 10072 Notes: 10073 Unless scall is MAT_REUSE_MATRIX D will be created. 10074 10075 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10076 10077 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10078 actually needed. 10079 10080 If you have many matrices with the same non-zero structure to multiply, you 10081 should use MAT_REUSE_MATRIX in all calls but the first or 10082 10083 Level: intermediate 10084 10085 .seealso: MatMatMult, MatPtAP() 10086 @*/ 10087 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10088 { 10089 PetscErrorCode ierr; 10090 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10091 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10092 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10093 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 10094 10095 PetscFunctionBegin; 10096 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10097 PetscValidType(A,1); 10098 MatCheckPreallocated(A,1); 10099 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10100 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10101 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10102 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10103 PetscValidType(B,2); 10104 MatCheckPreallocated(B,2); 10105 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10106 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10107 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10108 PetscValidPointer(C,3); 10109 MatCheckPreallocated(C,3); 10110 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10111 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10112 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); 10113 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); 10114 if (scall == MAT_REUSE_MATRIX) { 10115 PetscValidPointer(*D,6); 10116 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 10117 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10118 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10119 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10120 PetscFunctionReturn(0); 10121 } 10122 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10123 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 10124 10125 fA = A->ops->matmatmult; 10126 fB = B->ops->matmatmult; 10127 fC = C->ops->matmatmult; 10128 if (fA == fB && fA == fC) { 10129 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 10130 mult = fA; 10131 } else { 10132 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 10133 char multname[256]; 10134 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 10135 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10136 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10137 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10138 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10139 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 10140 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 10141 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 10142 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); 10143 } 10144 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10145 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10146 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10147 PetscFunctionReturn(0); 10148 } 10149 10150 /*@ 10151 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10152 10153 Collective on Mat 10154 10155 Input Parameters: 10156 + mat - the matrix 10157 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10158 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10159 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10160 10161 Output Parameter: 10162 . matredundant - redundant matrix 10163 10164 Notes: 10165 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10166 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10167 10168 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 10169 calling it. 10170 10171 Level: advanced 10172 10173 Concepts: subcommunicator 10174 Concepts: duplicate matrix 10175 10176 .seealso: MatDestroy() 10177 @*/ 10178 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10179 { 10180 PetscErrorCode ierr; 10181 MPI_Comm comm; 10182 PetscMPIInt size; 10183 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10184 Mat_Redundant *redund=NULL; 10185 PetscSubcomm psubcomm=NULL; 10186 MPI_Comm subcomm_in=subcomm; 10187 Mat *matseq; 10188 IS isrow,iscol; 10189 PetscBool newsubcomm=PETSC_FALSE; 10190 10191 PetscFunctionBegin; 10192 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10193 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10194 PetscValidPointer(*matredundant,5); 10195 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10196 } 10197 10198 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10199 if (size == 1 || nsubcomm == 1) { 10200 if (reuse == MAT_INITIAL_MATRIX) { 10201 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10202 } else { 10203 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"); 10204 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10205 } 10206 PetscFunctionReturn(0); 10207 } 10208 10209 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10210 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10211 MatCheckPreallocated(mat,1); 10212 10213 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10214 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10215 /* create psubcomm, then get subcomm */ 10216 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10217 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10218 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10219 10220 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10221 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10222 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10223 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10224 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10225 newsubcomm = PETSC_TRUE; 10226 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10227 } 10228 10229 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10230 if (reuse == MAT_INITIAL_MATRIX) { 10231 mloc_sub = PETSC_DECIDE; 10232 nloc_sub = PETSC_DECIDE; 10233 if (bs < 1) { 10234 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10235 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10236 } else { 10237 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10238 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10239 } 10240 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10241 rstart = rend - mloc_sub; 10242 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10243 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10244 } else { /* reuse == MAT_REUSE_MATRIX */ 10245 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"); 10246 /* retrieve subcomm */ 10247 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10248 redund = (*matredundant)->redundant; 10249 isrow = redund->isrow; 10250 iscol = redund->iscol; 10251 matseq = redund->matseq; 10252 } 10253 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10254 10255 /* get matredundant over subcomm */ 10256 if (reuse == MAT_INITIAL_MATRIX) { 10257 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10258 10259 /* create a supporting struct and attach it to C for reuse */ 10260 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10261 (*matredundant)->redundant = redund; 10262 redund->isrow = isrow; 10263 redund->iscol = iscol; 10264 redund->matseq = matseq; 10265 if (newsubcomm) { 10266 redund->subcomm = subcomm; 10267 } else { 10268 redund->subcomm = MPI_COMM_NULL; 10269 } 10270 } else { 10271 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10272 } 10273 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10274 PetscFunctionReturn(0); 10275 } 10276 10277 /*@C 10278 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10279 a given 'mat' object. Each submatrix can span multiple procs. 10280 10281 Collective on Mat 10282 10283 Input Parameters: 10284 + mat - the matrix 10285 . subcomm - the subcommunicator obtained by com_split(comm) 10286 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10287 10288 Output Parameter: 10289 . subMat - 'parallel submatrices each spans a given subcomm 10290 10291 Notes: 10292 The submatrix partition across processors is dictated by 'subComm' a 10293 communicator obtained by com_split(comm). The comm_split 10294 is not restriced to be grouped with consecutive original ranks. 10295 10296 Due the comm_split() usage, the parallel layout of the submatrices 10297 map directly to the layout of the original matrix [wrt the local 10298 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10299 into the 'DiagonalMat' of the subMat, hence it is used directly from 10300 the subMat. However the offDiagMat looses some columns - and this is 10301 reconstructed with MatSetValues() 10302 10303 Level: advanced 10304 10305 Concepts: subcommunicator 10306 Concepts: submatrices 10307 10308 .seealso: MatCreateSubMatrices() 10309 @*/ 10310 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10311 { 10312 PetscErrorCode ierr; 10313 PetscMPIInt commsize,subCommSize; 10314 10315 PetscFunctionBegin; 10316 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10317 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10318 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10319 10320 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"); 10321 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10322 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10323 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10324 PetscFunctionReturn(0); 10325 } 10326 10327 /*@ 10328 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10329 10330 Not Collective 10331 10332 Input Arguments: 10333 mat - matrix to extract local submatrix from 10334 isrow - local row indices for submatrix 10335 iscol - local column indices for submatrix 10336 10337 Output Arguments: 10338 submat - the submatrix 10339 10340 Level: intermediate 10341 10342 Notes: 10343 The submat should be returned with MatRestoreLocalSubMatrix(). 10344 10345 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10346 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10347 10348 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10349 MatSetValuesBlockedLocal() will also be implemented. 10350 10351 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10352 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10353 10354 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10355 @*/ 10356 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10357 { 10358 PetscErrorCode ierr; 10359 10360 PetscFunctionBegin; 10361 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10362 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10363 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10364 PetscCheckSameComm(isrow,2,iscol,3); 10365 PetscValidPointer(submat,4); 10366 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10367 10368 if (mat->ops->getlocalsubmatrix) { 10369 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10370 } else { 10371 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10372 } 10373 PetscFunctionReturn(0); 10374 } 10375 10376 /*@ 10377 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10378 10379 Not Collective 10380 10381 Input Arguments: 10382 mat - matrix to extract local submatrix from 10383 isrow - local row indices for submatrix 10384 iscol - local column indices for submatrix 10385 submat - the submatrix 10386 10387 Level: intermediate 10388 10389 .seealso: MatGetLocalSubMatrix() 10390 @*/ 10391 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10392 { 10393 PetscErrorCode ierr; 10394 10395 PetscFunctionBegin; 10396 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10397 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10398 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10399 PetscCheckSameComm(isrow,2,iscol,3); 10400 PetscValidPointer(submat,4); 10401 if (*submat) { 10402 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10403 } 10404 10405 if (mat->ops->restorelocalsubmatrix) { 10406 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10407 } else { 10408 ierr = MatDestroy(submat);CHKERRQ(ierr); 10409 } 10410 *submat = NULL; 10411 PetscFunctionReturn(0); 10412 } 10413 10414 /* --------------------------------------------------------*/ 10415 /*@ 10416 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10417 10418 Collective on Mat 10419 10420 Input Parameter: 10421 . mat - the matrix 10422 10423 Output Parameter: 10424 . is - if any rows have zero diagonals this contains the list of them 10425 10426 Level: developer 10427 10428 Concepts: matrix-vector product 10429 10430 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10431 @*/ 10432 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10433 { 10434 PetscErrorCode ierr; 10435 10436 PetscFunctionBegin; 10437 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10438 PetscValidType(mat,1); 10439 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10440 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10441 10442 if (!mat->ops->findzerodiagonals) { 10443 Vec diag; 10444 const PetscScalar *a; 10445 PetscInt *rows; 10446 PetscInt rStart, rEnd, r, nrow = 0; 10447 10448 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10449 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10450 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10451 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10452 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10453 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10454 nrow = 0; 10455 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10456 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10457 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10458 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10459 } else { 10460 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10461 } 10462 PetscFunctionReturn(0); 10463 } 10464 10465 /*@ 10466 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10467 10468 Collective on Mat 10469 10470 Input Parameter: 10471 . mat - the matrix 10472 10473 Output Parameter: 10474 . is - contains the list of rows with off block diagonal entries 10475 10476 Level: developer 10477 10478 Concepts: matrix-vector product 10479 10480 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10481 @*/ 10482 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10483 { 10484 PetscErrorCode ierr; 10485 10486 PetscFunctionBegin; 10487 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10488 PetscValidType(mat,1); 10489 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10490 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10491 10492 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10493 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10494 PetscFunctionReturn(0); 10495 } 10496 10497 /*@C 10498 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10499 10500 Collective on Mat 10501 10502 Input Parameters: 10503 . mat - the matrix 10504 10505 Output Parameters: 10506 . values - the block inverses in column major order (FORTRAN-like) 10507 10508 Note: 10509 This routine is not available from Fortran. 10510 10511 Level: advanced 10512 10513 .seealso: MatInvertBockDiagonalMat 10514 @*/ 10515 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10516 { 10517 PetscErrorCode ierr; 10518 10519 PetscFunctionBegin; 10520 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10521 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10522 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10523 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10524 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10525 PetscFunctionReturn(0); 10526 } 10527 10528 /*@C 10529 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10530 10531 Collective on Mat 10532 10533 Input Parameters: 10534 + mat - the matrix 10535 . nblocks - the number of blocks 10536 - bsizes - the size of each block 10537 10538 Output Parameters: 10539 . values - the block inverses in column major order (FORTRAN-like) 10540 10541 Note: 10542 This routine is not available from Fortran. 10543 10544 Level: advanced 10545 10546 .seealso: MatInvertBockDiagonal() 10547 @*/ 10548 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10549 { 10550 PetscErrorCode ierr; 10551 10552 PetscFunctionBegin; 10553 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10554 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10555 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10556 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10557 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10558 PetscFunctionReturn(0); 10559 } 10560 10561 /*@ 10562 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10563 10564 Collective on Mat 10565 10566 Input Parameters: 10567 . A - the matrix 10568 10569 Output Parameters: 10570 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10571 10572 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10573 10574 Level: advanced 10575 10576 .seealso: MatInvertBockDiagonal() 10577 @*/ 10578 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10579 { 10580 PetscErrorCode ierr; 10581 const PetscScalar *vals; 10582 PetscInt *dnnz; 10583 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10584 10585 PetscFunctionBegin; 10586 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10587 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10588 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10589 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10590 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10591 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10592 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10593 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10594 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10595 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10596 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10597 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10598 for (i = rstart/bs; i < rend/bs; i++) { 10599 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10600 } 10601 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10602 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10603 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10604 PetscFunctionReturn(0); 10605 } 10606 10607 /*@C 10608 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10609 via MatTransposeColoringCreate(). 10610 10611 Collective on MatTransposeColoring 10612 10613 Input Parameter: 10614 . c - coloring context 10615 10616 Level: intermediate 10617 10618 .seealso: MatTransposeColoringCreate() 10619 @*/ 10620 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10621 { 10622 PetscErrorCode ierr; 10623 MatTransposeColoring matcolor=*c; 10624 10625 PetscFunctionBegin; 10626 if (!matcolor) PetscFunctionReturn(0); 10627 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10628 10629 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10630 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10631 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10632 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10633 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10634 if (matcolor->brows>0) { 10635 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10636 } 10637 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10638 PetscFunctionReturn(0); 10639 } 10640 10641 /*@C 10642 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10643 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10644 MatTransposeColoring to sparse B. 10645 10646 Collective on MatTransposeColoring 10647 10648 Input Parameters: 10649 + B - sparse matrix B 10650 . Btdense - symbolic dense matrix B^T 10651 - coloring - coloring context created with MatTransposeColoringCreate() 10652 10653 Output Parameter: 10654 . Btdense - dense matrix B^T 10655 10656 Level: advanced 10657 10658 Notes: 10659 These are used internally for some implementations of MatRARt() 10660 10661 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10662 10663 .keywords: coloring 10664 @*/ 10665 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10666 { 10667 PetscErrorCode ierr; 10668 10669 PetscFunctionBegin; 10670 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10671 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10672 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10673 10674 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10675 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10676 PetscFunctionReturn(0); 10677 } 10678 10679 /*@C 10680 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10681 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10682 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10683 Csp from Cden. 10684 10685 Collective on MatTransposeColoring 10686 10687 Input Parameters: 10688 + coloring - coloring context created with MatTransposeColoringCreate() 10689 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10690 10691 Output Parameter: 10692 . Csp - sparse matrix 10693 10694 Level: advanced 10695 10696 Notes: 10697 These are used internally for some implementations of MatRARt() 10698 10699 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10700 10701 .keywords: coloring 10702 @*/ 10703 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10704 { 10705 PetscErrorCode ierr; 10706 10707 PetscFunctionBegin; 10708 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10709 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10710 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10711 10712 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10713 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10714 PetscFunctionReturn(0); 10715 } 10716 10717 /*@C 10718 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10719 10720 Collective on Mat 10721 10722 Input Parameters: 10723 + mat - the matrix product C 10724 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10725 10726 Output Parameter: 10727 . color - the new coloring context 10728 10729 Level: intermediate 10730 10731 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10732 MatTransColoringApplyDenToSp() 10733 @*/ 10734 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10735 { 10736 MatTransposeColoring c; 10737 MPI_Comm comm; 10738 PetscErrorCode ierr; 10739 10740 PetscFunctionBegin; 10741 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10742 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10743 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10744 10745 c->ctype = iscoloring->ctype; 10746 if (mat->ops->transposecoloringcreate) { 10747 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10748 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10749 10750 *color = c; 10751 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10752 PetscFunctionReturn(0); 10753 } 10754 10755 /*@ 10756 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10757 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10758 same, otherwise it will be larger 10759 10760 Not Collective 10761 10762 Input Parameter: 10763 . A - the matrix 10764 10765 Output Parameter: 10766 . state - the current state 10767 10768 Notes: 10769 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10770 different matrices 10771 10772 Level: intermediate 10773 10774 @*/ 10775 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10776 { 10777 PetscFunctionBegin; 10778 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10779 *state = mat->nonzerostate; 10780 PetscFunctionReturn(0); 10781 } 10782 10783 /*@ 10784 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10785 matrices from each processor 10786 10787 Collective on MPI_Comm 10788 10789 Input Parameters: 10790 + comm - the communicators the parallel matrix will live on 10791 . seqmat - the input sequential matrices 10792 . n - number of local columns (or PETSC_DECIDE) 10793 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10794 10795 Output Parameter: 10796 . mpimat - the parallel matrix generated 10797 10798 Level: advanced 10799 10800 Notes: 10801 The number of columns of the matrix in EACH processor MUST be the same. 10802 10803 @*/ 10804 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10805 { 10806 PetscErrorCode ierr; 10807 10808 PetscFunctionBegin; 10809 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10810 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"); 10811 10812 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10813 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10814 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10815 PetscFunctionReturn(0); 10816 } 10817 10818 /*@ 10819 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10820 ranks' ownership ranges. 10821 10822 Collective on A 10823 10824 Input Parameters: 10825 + A - the matrix to create subdomains from 10826 - N - requested number of subdomains 10827 10828 10829 Output Parameters: 10830 + n - number of subdomains resulting on this rank 10831 - iss - IS list with indices of subdomains on this rank 10832 10833 Level: advanced 10834 10835 Notes: 10836 number of subdomains must be smaller than the communicator size 10837 @*/ 10838 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10839 { 10840 MPI_Comm comm,subcomm; 10841 PetscMPIInt size,rank,color; 10842 PetscInt rstart,rend,k; 10843 PetscErrorCode ierr; 10844 10845 PetscFunctionBegin; 10846 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10847 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10848 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10849 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); 10850 *n = 1; 10851 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10852 color = rank/k; 10853 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10854 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10855 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10856 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10857 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10858 PetscFunctionReturn(0); 10859 } 10860 10861 /*@ 10862 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10863 10864 If the interpolation and restriction operators are the same, uses MatPtAP. 10865 If they are not the same, use MatMatMatMult. 10866 10867 Once the coarse grid problem is constructed, correct for interpolation operators 10868 that are not of full rank, which can legitimately happen in the case of non-nested 10869 geometric multigrid. 10870 10871 Input Parameters: 10872 + restrct - restriction operator 10873 . dA - fine grid matrix 10874 . interpolate - interpolation operator 10875 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10876 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10877 10878 Output Parameters: 10879 . A - the Galerkin coarse matrix 10880 10881 Options Database Key: 10882 . -pc_mg_galerkin <both,pmat,mat,none> 10883 10884 Level: developer 10885 10886 .keywords: MG, multigrid, Galerkin 10887 10888 .seealso: MatPtAP(), MatMatMatMult() 10889 @*/ 10890 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10891 { 10892 PetscErrorCode ierr; 10893 IS zerorows; 10894 Vec diag; 10895 10896 PetscFunctionBegin; 10897 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10898 /* Construct the coarse grid matrix */ 10899 if (interpolate == restrct) { 10900 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10901 } else { 10902 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10903 } 10904 10905 /* If the interpolation matrix is not of full rank, A will have zero rows. 10906 This can legitimately happen in the case of non-nested geometric multigrid. 10907 In that event, we set the rows of the matrix to the rows of the identity, 10908 ignoring the equations (as the RHS will also be zero). */ 10909 10910 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10911 10912 if (zerorows != NULL) { /* if there are any zero rows */ 10913 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10914 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10915 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10916 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10917 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10918 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10919 } 10920 PetscFunctionReturn(0); 10921 } 10922 10923 /*@C 10924 MatSetOperation - Allows user to set a matrix operation for any matrix type 10925 10926 Logically Collective on Mat 10927 10928 Input Parameters: 10929 + mat - the matrix 10930 . op - the name of the operation 10931 - f - the function that provides the operation 10932 10933 Level: developer 10934 10935 Usage: 10936 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10937 $ ierr = MatCreateXXX(comm,...&A); 10938 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10939 10940 Notes: 10941 See the file include/petscmat.h for a complete list of matrix 10942 operations, which all have the form MATOP_<OPERATION>, where 10943 <OPERATION> is the name (in all capital letters) of the 10944 user interface routine (e.g., MatMult() -> MATOP_MULT). 10945 10946 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10947 sequence as the usual matrix interface routines, since they 10948 are intended to be accessed via the usual matrix interface 10949 routines, e.g., 10950 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10951 10952 In particular each function MUST return an error code of 0 on success and 10953 nonzero on failure. 10954 10955 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10956 10957 .keywords: matrix, set, operation 10958 10959 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10960 @*/ 10961 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10962 { 10963 PetscFunctionBegin; 10964 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10965 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10966 mat->ops->viewnative = mat->ops->view; 10967 } 10968 (((void(**)(void))mat->ops)[op]) = f; 10969 PetscFunctionReturn(0); 10970 } 10971 10972 /*@C 10973 MatGetOperation - Gets a matrix operation for any matrix type. 10974 10975 Not Collective 10976 10977 Input Parameters: 10978 + mat - the matrix 10979 - op - the name of the operation 10980 10981 Output Parameter: 10982 . f - the function that provides the operation 10983 10984 Level: developer 10985 10986 Usage: 10987 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10988 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10989 10990 Notes: 10991 See the file include/petscmat.h for a complete list of matrix 10992 operations, which all have the form MATOP_<OPERATION>, where 10993 <OPERATION> is the name (in all capital letters) of the 10994 user interface routine (e.g., MatMult() -> MATOP_MULT). 10995 10996 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10997 10998 .keywords: matrix, get, operation 10999 11000 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 11001 @*/ 11002 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 11003 { 11004 PetscFunctionBegin; 11005 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11006 *f = (((void (**)(void))mat->ops)[op]); 11007 PetscFunctionReturn(0); 11008 } 11009 11010 /*@ 11011 MatHasOperation - Determines whether the given matrix supports the particular 11012 operation. 11013 11014 Not Collective 11015 11016 Input Parameters: 11017 + mat - the matrix 11018 - op - the operation, for example, MATOP_GET_DIAGONAL 11019 11020 Output Parameter: 11021 . has - either PETSC_TRUE or PETSC_FALSE 11022 11023 Level: advanced 11024 11025 Notes: 11026 See the file include/petscmat.h for a complete list of matrix 11027 operations, which all have the form MATOP_<OPERATION>, where 11028 <OPERATION> is the name (in all capital letters) of the 11029 user-level routine. E.g., MatNorm() -> MATOP_NORM. 11030 11031 .keywords: matrix, has, operation 11032 11033 .seealso: MatCreateShell() 11034 @*/ 11035 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 11036 { 11037 PetscErrorCode ierr; 11038 11039 PetscFunctionBegin; 11040 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11041 PetscValidType(mat,1); 11042 PetscValidPointer(has,3); 11043 if (mat->ops->hasoperation) { 11044 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 11045 } else { 11046 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 11047 else { 11048 *has = PETSC_FALSE; 11049 if (op == MATOP_CREATE_SUBMATRIX) { 11050 PetscMPIInt size; 11051 11052 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 11053 if (size == 1) { 11054 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 11055 } 11056 } 11057 } 11058 } 11059 PetscFunctionReturn(0); 11060 } 11061 11062 /*@ 11063 MatHasCongruentLayouts - Determines whether the rows and columns layouts 11064 of the matrix are congruent 11065 11066 Collective on mat 11067 11068 Input Parameters: 11069 . mat - the matrix 11070 11071 Output Parameter: 11072 . cong - either PETSC_TRUE or PETSC_FALSE 11073 11074 Level: beginner 11075 11076 Notes: 11077 11078 .keywords: matrix, has 11079 11080 .seealso: MatCreate(), MatSetSizes() 11081 @*/ 11082 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 11083 { 11084 PetscErrorCode ierr; 11085 11086 PetscFunctionBegin; 11087 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11088 PetscValidType(mat,1); 11089 PetscValidPointer(cong,2); 11090 if (!mat->rmap || !mat->cmap) { 11091 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11092 PetscFunctionReturn(0); 11093 } 11094 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11095 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 11096 if (*cong) mat->congruentlayouts = 1; 11097 else mat->congruentlayouts = 0; 11098 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11099 PetscFunctionReturn(0); 11100 } 11101