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