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