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 [of length n+1] 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 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 Note: 7545 This routine zeros out n, ia, and ja. This is to prevent accidental 7546 us of the array after it has been restored. If you pass NULL, it will 7547 not zero the pointers. Use of ia or ja after MatRestoreColumnIJ() is invalid. 7548 7549 Level: developer 7550 7551 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7552 @*/ 7553 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7554 { 7555 PetscErrorCode ierr; 7556 7557 PetscFunctionBegin; 7558 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7559 PetscValidType(mat,1); 7560 PetscValidIntPointer(n,4); 7561 if (ia) PetscValidIntPointer(ia,5); 7562 if (ja) PetscValidIntPointer(ja,6); 7563 PetscValidIntPointer(done,7); 7564 MatCheckPreallocated(mat,1); 7565 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7566 else { 7567 *done = PETSC_TRUE; 7568 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7569 } 7570 PetscFunctionReturn(0); 7571 } 7572 7573 /*@C 7574 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7575 MatGetRowIJ(). 7576 7577 Collective on Mat 7578 7579 Input Parameters: 7580 + mat - the matrix 7581 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7582 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7583 symmetrized 7584 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7585 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7586 always used. 7587 . n - size of (possibly compressed) matrix 7588 . ia - the row pointers 7589 - ja - the column indices 7590 7591 Output Parameters: 7592 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7593 7594 Note: 7595 This routine zeros out n, ia, and ja. This is to prevent accidental 7596 us of the array after it has been restored. If you pass NULL, it will 7597 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7598 7599 Level: developer 7600 7601 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7602 @*/ 7603 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7604 { 7605 PetscErrorCode ierr; 7606 7607 PetscFunctionBegin; 7608 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7609 PetscValidType(mat,1); 7610 if (ia) PetscValidIntPointer(ia,6); 7611 if (ja) PetscValidIntPointer(ja,7); 7612 PetscValidIntPointer(done,8); 7613 MatCheckPreallocated(mat,1); 7614 7615 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7616 else { 7617 *done = PETSC_TRUE; 7618 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7619 if (n) *n = 0; 7620 if (ia) *ia = NULL; 7621 if (ja) *ja = NULL; 7622 } 7623 PetscFunctionReturn(0); 7624 } 7625 7626 /*@C 7627 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7628 MatGetColumnIJ(). 7629 7630 Collective on Mat 7631 7632 Input Parameters: 7633 + mat - the matrix 7634 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7635 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7636 symmetrized 7637 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7638 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7639 always used. 7640 7641 Output Parameters: 7642 + n - size of (possibly compressed) matrix 7643 . ia - the column pointers 7644 . ja - the row indices 7645 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7646 7647 Level: developer 7648 7649 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7650 @*/ 7651 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7652 { 7653 PetscErrorCode ierr; 7654 7655 PetscFunctionBegin; 7656 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7657 PetscValidType(mat,1); 7658 if (ia) PetscValidIntPointer(ia,5); 7659 if (ja) PetscValidIntPointer(ja,6); 7660 PetscValidIntPointer(done,7); 7661 MatCheckPreallocated(mat,1); 7662 7663 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7664 else { 7665 *done = PETSC_TRUE; 7666 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7667 if (n) *n = 0; 7668 if (ia) *ia = NULL; 7669 if (ja) *ja = NULL; 7670 } 7671 PetscFunctionReturn(0); 7672 } 7673 7674 /*@C 7675 MatColoringPatch -Used inside matrix coloring routines that 7676 use MatGetRowIJ() and/or MatGetColumnIJ(). 7677 7678 Collective on Mat 7679 7680 Input Parameters: 7681 + mat - the matrix 7682 . ncolors - max color value 7683 . n - number of entries in colorarray 7684 - colorarray - array indicating color for each column 7685 7686 Output Parameters: 7687 . iscoloring - coloring generated using colorarray information 7688 7689 Level: developer 7690 7691 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7692 7693 @*/ 7694 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7695 { 7696 PetscErrorCode ierr; 7697 7698 PetscFunctionBegin; 7699 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7700 PetscValidType(mat,1); 7701 PetscValidIntPointer(colorarray,4); 7702 PetscValidPointer(iscoloring,5); 7703 MatCheckPreallocated(mat,1); 7704 7705 if (!mat->ops->coloringpatch) { 7706 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7707 } else { 7708 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7709 } 7710 PetscFunctionReturn(0); 7711 } 7712 7713 7714 /*@ 7715 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7716 7717 Logically Collective on Mat 7718 7719 Input Parameter: 7720 . mat - the factored matrix to be reset 7721 7722 Notes: 7723 This routine should be used only with factored matrices formed by in-place 7724 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7725 format). This option can save memory, for example, when solving nonlinear 7726 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7727 ILU(0) preconditioner. 7728 7729 Note that one can specify in-place ILU(0) factorization by calling 7730 .vb 7731 PCType(pc,PCILU); 7732 PCFactorSeUseInPlace(pc); 7733 .ve 7734 or by using the options -pc_type ilu -pc_factor_in_place 7735 7736 In-place factorization ILU(0) can also be used as a local 7737 solver for the blocks within the block Jacobi or additive Schwarz 7738 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7739 for details on setting local solver options. 7740 7741 Most users should employ the simplified KSP interface for linear solvers 7742 instead of working directly with matrix algebra routines such as this. 7743 See, e.g., KSPCreate(). 7744 7745 Level: developer 7746 7747 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7748 7749 Concepts: matrices^unfactored 7750 7751 @*/ 7752 PetscErrorCode MatSetUnfactored(Mat mat) 7753 { 7754 PetscErrorCode ierr; 7755 7756 PetscFunctionBegin; 7757 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7758 PetscValidType(mat,1); 7759 MatCheckPreallocated(mat,1); 7760 mat->factortype = MAT_FACTOR_NONE; 7761 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7762 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7763 PetscFunctionReturn(0); 7764 } 7765 7766 /*MC 7767 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7768 7769 Synopsis: 7770 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7771 7772 Not collective 7773 7774 Input Parameter: 7775 . x - matrix 7776 7777 Output Parameters: 7778 + xx_v - the Fortran90 pointer to the array 7779 - ierr - error code 7780 7781 Example of Usage: 7782 .vb 7783 PetscScalar, pointer xx_v(:,:) 7784 .... 7785 call MatDenseGetArrayF90(x,xx_v,ierr) 7786 a = xx_v(3) 7787 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7788 .ve 7789 7790 Level: advanced 7791 7792 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7793 7794 Concepts: matrices^accessing array 7795 7796 M*/ 7797 7798 /*MC 7799 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7800 accessed with MatDenseGetArrayF90(). 7801 7802 Synopsis: 7803 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7804 7805 Not collective 7806 7807 Input Parameters: 7808 + x - matrix 7809 - xx_v - the Fortran90 pointer to the array 7810 7811 Output Parameter: 7812 . ierr - error code 7813 7814 Example of Usage: 7815 .vb 7816 PetscScalar, pointer xx_v(:,:) 7817 .... 7818 call MatDenseGetArrayF90(x,xx_v,ierr) 7819 a = xx_v(3) 7820 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7821 .ve 7822 7823 Level: advanced 7824 7825 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7826 7827 M*/ 7828 7829 7830 /*MC 7831 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7832 7833 Synopsis: 7834 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7835 7836 Not collective 7837 7838 Input Parameter: 7839 . x - matrix 7840 7841 Output Parameters: 7842 + xx_v - the Fortran90 pointer to the array 7843 - ierr - error code 7844 7845 Example of Usage: 7846 .vb 7847 PetscScalar, pointer xx_v(:) 7848 .... 7849 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7850 a = xx_v(3) 7851 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7852 .ve 7853 7854 Level: advanced 7855 7856 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7857 7858 Concepts: matrices^accessing array 7859 7860 M*/ 7861 7862 /*MC 7863 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7864 accessed with MatSeqAIJGetArrayF90(). 7865 7866 Synopsis: 7867 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7868 7869 Not collective 7870 7871 Input Parameters: 7872 + x - matrix 7873 - xx_v - the Fortran90 pointer to the array 7874 7875 Output Parameter: 7876 . ierr - error code 7877 7878 Example of Usage: 7879 .vb 7880 PetscScalar, pointer xx_v(:) 7881 .... 7882 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7883 a = xx_v(3) 7884 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7885 .ve 7886 7887 Level: advanced 7888 7889 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7890 7891 M*/ 7892 7893 7894 /*@ 7895 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7896 as the original matrix. 7897 7898 Collective on Mat 7899 7900 Input Parameters: 7901 + mat - the original matrix 7902 . isrow - parallel IS containing the rows this processor should obtain 7903 . 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. 7904 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7905 7906 Output Parameter: 7907 . newmat - the new submatrix, of the same type as the old 7908 7909 Level: advanced 7910 7911 Notes: 7912 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7913 7914 Some matrix types place restrictions on the row and column indices, such 7915 as that they be sorted or that they be equal to each other. 7916 7917 The index sets may not have duplicate entries. 7918 7919 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7920 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7921 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7922 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7923 you are finished using it. 7924 7925 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7926 the input matrix. 7927 7928 If iscol is NULL then all columns are obtained (not supported in Fortran). 7929 7930 Example usage: 7931 Consider the following 8x8 matrix with 34 non-zero values, that is 7932 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7933 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7934 as follows: 7935 7936 .vb 7937 1 2 0 | 0 3 0 | 0 4 7938 Proc0 0 5 6 | 7 0 0 | 8 0 7939 9 0 10 | 11 0 0 | 12 0 7940 ------------------------------------- 7941 13 0 14 | 15 16 17 | 0 0 7942 Proc1 0 18 0 | 19 20 21 | 0 0 7943 0 0 0 | 22 23 0 | 24 0 7944 ------------------------------------- 7945 Proc2 25 26 27 | 0 0 28 | 29 0 7946 30 0 0 | 31 32 33 | 0 34 7947 .ve 7948 7949 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7950 7951 .vb 7952 2 0 | 0 3 0 | 0 7953 Proc0 5 6 | 7 0 0 | 8 7954 ------------------------------- 7955 Proc1 18 0 | 19 20 21 | 0 7956 ------------------------------- 7957 Proc2 26 27 | 0 0 28 | 29 7958 0 0 | 31 32 33 | 0 7959 .ve 7960 7961 7962 Concepts: matrices^submatrices 7963 7964 .seealso: MatCreateSubMatrices() 7965 @*/ 7966 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7967 { 7968 PetscErrorCode ierr; 7969 PetscMPIInt size; 7970 Mat *local; 7971 IS iscoltmp; 7972 7973 PetscFunctionBegin; 7974 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7975 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7976 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7977 PetscValidPointer(newmat,5); 7978 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7979 PetscValidType(mat,1); 7980 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7981 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7982 7983 MatCheckPreallocated(mat,1); 7984 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7985 7986 if (!iscol || isrow == iscol) { 7987 PetscBool stride; 7988 PetscMPIInt grabentirematrix = 0,grab; 7989 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7990 if (stride) { 7991 PetscInt first,step,n,rstart,rend; 7992 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7993 if (step == 1) { 7994 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7995 if (rstart == first) { 7996 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7997 if (n == rend-rstart) { 7998 grabentirematrix = 1; 7999 } 8000 } 8001 } 8002 } 8003 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 8004 if (grab) { 8005 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 8006 if (cll == MAT_INITIAL_MATRIX) { 8007 *newmat = mat; 8008 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 8009 } 8010 PetscFunctionReturn(0); 8011 } 8012 } 8013 8014 if (!iscol) { 8015 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 8016 } else { 8017 iscoltmp = iscol; 8018 } 8019 8020 /* if original matrix is on just one processor then use submatrix generated */ 8021 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8022 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 8023 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8024 PetscFunctionReturn(0); 8025 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8026 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 8027 *newmat = *local; 8028 ierr = PetscFree(local);CHKERRQ(ierr); 8029 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8030 PetscFunctionReturn(0); 8031 } else if (!mat->ops->createsubmatrix) { 8032 /* Create a new matrix type that implements the operation using the full matrix */ 8033 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8034 switch (cll) { 8035 case MAT_INITIAL_MATRIX: 8036 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 8037 break; 8038 case MAT_REUSE_MATRIX: 8039 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 8040 break; 8041 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8042 } 8043 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8044 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8045 PetscFunctionReturn(0); 8046 } 8047 8048 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8049 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8050 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 8051 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8052 8053 /* Propagate symmetry information for diagonal blocks */ 8054 if (isrow == iscoltmp) { 8055 if (mat->symmetric_set && mat->symmetric) { 8056 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8057 } 8058 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 8059 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8060 } 8061 if (mat->hermitian_set && mat->hermitian) { 8062 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 8063 } 8064 if (mat->spd_set && mat->spd) { 8065 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 8066 } 8067 } 8068 8069 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8070 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 8071 PetscFunctionReturn(0); 8072 } 8073 8074 /*@ 8075 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8076 used during the assembly process to store values that belong to 8077 other processors. 8078 8079 Not Collective 8080 8081 Input Parameters: 8082 + mat - the matrix 8083 . size - the initial size of the stash. 8084 - bsize - the initial size of the block-stash(if used). 8085 8086 Options Database Keys: 8087 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8088 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8089 8090 Level: intermediate 8091 8092 Notes: 8093 The block-stash is used for values set with MatSetValuesBlocked() while 8094 the stash is used for values set with MatSetValues() 8095 8096 Run with the option -info and look for output of the form 8097 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8098 to determine the appropriate value, MM, to use for size and 8099 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8100 to determine the value, BMM to use for bsize 8101 8102 Concepts: stash^setting matrix size 8103 Concepts: matrices^stash 8104 8105 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 8106 8107 @*/ 8108 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8109 { 8110 PetscErrorCode ierr; 8111 8112 PetscFunctionBegin; 8113 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8114 PetscValidType(mat,1); 8115 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 8116 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 8117 PetscFunctionReturn(0); 8118 } 8119 8120 /*@ 8121 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8122 the matrix 8123 8124 Neighbor-wise Collective on Mat 8125 8126 Input Parameters: 8127 + mat - the matrix 8128 . x,y - the vectors 8129 - w - where the result is stored 8130 8131 Level: intermediate 8132 8133 Notes: 8134 w may be the same vector as y. 8135 8136 This allows one to use either the restriction or interpolation (its transpose) 8137 matrix to do the interpolation 8138 8139 Concepts: interpolation 8140 8141 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8142 8143 @*/ 8144 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8145 { 8146 PetscErrorCode ierr; 8147 PetscInt M,N,Ny; 8148 8149 PetscFunctionBegin; 8150 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8151 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8152 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8153 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8154 PetscValidType(A,1); 8155 MatCheckPreallocated(A,1); 8156 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8157 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8158 if (M == Ny) { 8159 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8160 } else { 8161 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8162 } 8163 PetscFunctionReturn(0); 8164 } 8165 8166 /*@ 8167 MatInterpolate - y = A*x or A'*x depending on the shape of 8168 the matrix 8169 8170 Neighbor-wise Collective on Mat 8171 8172 Input Parameters: 8173 + mat - the matrix 8174 - x,y - the vectors 8175 8176 Level: intermediate 8177 8178 Notes: 8179 This allows one to use either the restriction or interpolation (its transpose) 8180 matrix to do the interpolation 8181 8182 Concepts: matrices^interpolation 8183 8184 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8185 8186 @*/ 8187 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8188 { 8189 PetscErrorCode ierr; 8190 PetscInt M,N,Ny; 8191 8192 PetscFunctionBegin; 8193 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8194 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8195 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8196 PetscValidType(A,1); 8197 MatCheckPreallocated(A,1); 8198 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8199 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8200 if (M == Ny) { 8201 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8202 } else { 8203 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8204 } 8205 PetscFunctionReturn(0); 8206 } 8207 8208 /*@ 8209 MatRestrict - y = A*x or A'*x 8210 8211 Neighbor-wise Collective on Mat 8212 8213 Input Parameters: 8214 + mat - the matrix 8215 - x,y - the vectors 8216 8217 Level: intermediate 8218 8219 Notes: 8220 This allows one to use either the restriction or interpolation (its transpose) 8221 matrix to do the restriction 8222 8223 Concepts: matrices^restriction 8224 8225 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8226 8227 @*/ 8228 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8229 { 8230 PetscErrorCode ierr; 8231 PetscInt M,N,Ny; 8232 8233 PetscFunctionBegin; 8234 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8235 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8236 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8237 PetscValidType(A,1); 8238 MatCheckPreallocated(A,1); 8239 8240 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8241 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8242 if (M == Ny) { 8243 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8244 } else { 8245 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8246 } 8247 PetscFunctionReturn(0); 8248 } 8249 8250 /*@ 8251 MatGetNullSpace - retrieves the null space of a matrix. 8252 8253 Logically Collective on Mat and MatNullSpace 8254 8255 Input Parameters: 8256 + mat - the matrix 8257 - nullsp - the null space object 8258 8259 Level: developer 8260 8261 Concepts: null space^attaching to matrix 8262 8263 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8264 @*/ 8265 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8266 { 8267 PetscFunctionBegin; 8268 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8269 PetscValidPointer(nullsp,2); 8270 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8271 PetscFunctionReturn(0); 8272 } 8273 8274 /*@ 8275 MatSetNullSpace - attaches a null space to a matrix. 8276 8277 Logically Collective on Mat and MatNullSpace 8278 8279 Input Parameters: 8280 + mat - the matrix 8281 - nullsp - the null space object 8282 8283 Level: advanced 8284 8285 Notes: 8286 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8287 8288 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8289 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8290 8291 You can remove the null space by calling this routine with an nullsp of NULL 8292 8293 8294 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8295 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). 8296 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 8297 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 8298 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). 8299 8300 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8301 8302 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 8303 routine also automatically calls MatSetTransposeNullSpace(). 8304 8305 Concepts: null space^attaching to matrix 8306 8307 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8308 @*/ 8309 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8310 { 8311 PetscErrorCode ierr; 8312 8313 PetscFunctionBegin; 8314 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8315 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8316 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8317 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8318 mat->nullsp = nullsp; 8319 if (mat->symmetric_set && mat->symmetric) { 8320 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8321 } 8322 PetscFunctionReturn(0); 8323 } 8324 8325 /*@ 8326 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8327 8328 Logically Collective on Mat and MatNullSpace 8329 8330 Input Parameters: 8331 + mat - the matrix 8332 - nullsp - the null space object 8333 8334 Level: developer 8335 8336 Concepts: null space^attaching to matrix 8337 8338 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8339 @*/ 8340 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8341 { 8342 PetscFunctionBegin; 8343 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8344 PetscValidType(mat,1); 8345 PetscValidPointer(nullsp,2); 8346 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8347 PetscFunctionReturn(0); 8348 } 8349 8350 /*@ 8351 MatSetTransposeNullSpace - attaches a null space to a matrix. 8352 8353 Logically Collective on Mat and MatNullSpace 8354 8355 Input Parameters: 8356 + mat - the matrix 8357 - nullsp - the null space object 8358 8359 Level: advanced 8360 8361 Notes: 8362 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. 8363 You must also call MatSetNullSpace() 8364 8365 8366 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8367 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). 8368 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 8369 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 8370 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). 8371 8372 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8373 8374 Concepts: null space^attaching to matrix 8375 8376 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8377 @*/ 8378 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8379 { 8380 PetscErrorCode ierr; 8381 8382 PetscFunctionBegin; 8383 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8384 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8385 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8386 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8387 mat->transnullsp = nullsp; 8388 PetscFunctionReturn(0); 8389 } 8390 8391 /*@ 8392 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8393 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8394 8395 Logically Collective on Mat and MatNullSpace 8396 8397 Input Parameters: 8398 + mat - the matrix 8399 - nullsp - the null space object 8400 8401 Level: advanced 8402 8403 Notes: 8404 Overwrites any previous near null space that may have been attached 8405 8406 You can remove the null space by calling this routine with an nullsp of NULL 8407 8408 Concepts: null space^attaching to matrix 8409 8410 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8411 @*/ 8412 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8413 { 8414 PetscErrorCode ierr; 8415 8416 PetscFunctionBegin; 8417 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8418 PetscValidType(mat,1); 8419 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8420 MatCheckPreallocated(mat,1); 8421 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8422 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8423 mat->nearnullsp = nullsp; 8424 PetscFunctionReturn(0); 8425 } 8426 8427 /*@ 8428 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8429 8430 Not Collective 8431 8432 Input Parameters: 8433 . mat - the matrix 8434 8435 Output Parameters: 8436 . nullsp - the null space object, NULL if not set 8437 8438 Level: developer 8439 8440 Concepts: null space^attaching to matrix 8441 8442 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8443 @*/ 8444 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8445 { 8446 PetscFunctionBegin; 8447 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8448 PetscValidType(mat,1); 8449 PetscValidPointer(nullsp,2); 8450 MatCheckPreallocated(mat,1); 8451 *nullsp = mat->nearnullsp; 8452 PetscFunctionReturn(0); 8453 } 8454 8455 /*@C 8456 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8457 8458 Collective on Mat 8459 8460 Input Parameters: 8461 + mat - the matrix 8462 . row - row/column permutation 8463 . fill - expected fill factor >= 1.0 8464 - level - level of fill, for ICC(k) 8465 8466 Notes: 8467 Probably really in-place only when level of fill is zero, otherwise allocates 8468 new space to store factored matrix and deletes previous memory. 8469 8470 Most users should employ the simplified KSP interface for linear solvers 8471 instead of working directly with matrix algebra routines such as this. 8472 See, e.g., KSPCreate(). 8473 8474 Level: developer 8475 8476 Concepts: matrices^incomplete Cholesky factorization 8477 Concepts: Cholesky factorization 8478 8479 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8480 8481 Developer Note: fortran interface is not autogenerated as the f90 8482 interface defintion cannot be generated correctly [due to MatFactorInfo] 8483 8484 @*/ 8485 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8486 { 8487 PetscErrorCode ierr; 8488 8489 PetscFunctionBegin; 8490 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8491 PetscValidType(mat,1); 8492 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8493 PetscValidPointer(info,3); 8494 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8495 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8496 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8497 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8498 MatCheckPreallocated(mat,1); 8499 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8500 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8501 PetscFunctionReturn(0); 8502 } 8503 8504 /*@ 8505 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8506 ghosted ones. 8507 8508 Not Collective 8509 8510 Input Parameters: 8511 + mat - the matrix 8512 - diag = the diagonal values, including ghost ones 8513 8514 Level: developer 8515 8516 Notes: 8517 Works only for MPIAIJ and MPIBAIJ matrices 8518 8519 .seealso: MatDiagonalScale() 8520 @*/ 8521 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8522 { 8523 PetscErrorCode ierr; 8524 PetscMPIInt size; 8525 8526 PetscFunctionBegin; 8527 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8528 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8529 PetscValidType(mat,1); 8530 8531 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8532 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8533 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8534 if (size == 1) { 8535 PetscInt n,m; 8536 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8537 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8538 if (m == n) { 8539 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8540 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8541 } else { 8542 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8543 } 8544 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8545 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8546 PetscFunctionReturn(0); 8547 } 8548 8549 /*@ 8550 MatGetInertia - Gets the inertia from a factored matrix 8551 8552 Collective on Mat 8553 8554 Input Parameter: 8555 . mat - the matrix 8556 8557 Output Parameters: 8558 + nneg - number of negative eigenvalues 8559 . nzero - number of zero eigenvalues 8560 - npos - number of positive eigenvalues 8561 8562 Level: advanced 8563 8564 Notes: 8565 Matrix must have been factored by MatCholeskyFactor() 8566 8567 8568 @*/ 8569 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8570 { 8571 PetscErrorCode ierr; 8572 8573 PetscFunctionBegin; 8574 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8575 PetscValidType(mat,1); 8576 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8577 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8578 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8579 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8580 PetscFunctionReturn(0); 8581 } 8582 8583 /* ----------------------------------------------------------------*/ 8584 /*@C 8585 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8586 8587 Neighbor-wise Collective on Mat and Vecs 8588 8589 Input Parameters: 8590 + mat - the factored matrix 8591 - b - the right-hand-side vectors 8592 8593 Output Parameter: 8594 . x - the result vectors 8595 8596 Notes: 8597 The vectors b and x cannot be the same. I.e., one cannot 8598 call MatSolves(A,x,x). 8599 8600 Notes: 8601 Most users should employ the simplified KSP interface for linear solvers 8602 instead of working directly with matrix algebra routines such as this. 8603 See, e.g., KSPCreate(). 8604 8605 Level: developer 8606 8607 Concepts: matrices^triangular solves 8608 8609 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8610 @*/ 8611 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8612 { 8613 PetscErrorCode ierr; 8614 8615 PetscFunctionBegin; 8616 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8617 PetscValidType(mat,1); 8618 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8619 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8620 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8621 8622 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8623 MatCheckPreallocated(mat,1); 8624 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8625 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8626 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8627 PetscFunctionReturn(0); 8628 } 8629 8630 /*@ 8631 MatIsSymmetric - Test whether a matrix is symmetric 8632 8633 Collective on Mat 8634 8635 Input Parameter: 8636 + A - the matrix to test 8637 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8638 8639 Output Parameters: 8640 . flg - the result 8641 8642 Notes: 8643 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8644 8645 Level: intermediate 8646 8647 Concepts: matrix^symmetry 8648 8649 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8650 @*/ 8651 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8652 { 8653 PetscErrorCode ierr; 8654 8655 PetscFunctionBegin; 8656 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8657 PetscValidPointer(flg,2); 8658 8659 if (!A->symmetric_set) { 8660 if (!A->ops->issymmetric) { 8661 MatType mattype; 8662 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8663 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8664 } 8665 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8666 if (!tol) { 8667 A->symmetric_set = PETSC_TRUE; 8668 A->symmetric = *flg; 8669 if (A->symmetric) { 8670 A->structurally_symmetric_set = PETSC_TRUE; 8671 A->structurally_symmetric = PETSC_TRUE; 8672 } 8673 } 8674 } else if (A->symmetric) { 8675 *flg = PETSC_TRUE; 8676 } else if (!tol) { 8677 *flg = PETSC_FALSE; 8678 } else { 8679 if (!A->ops->issymmetric) { 8680 MatType mattype; 8681 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8682 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8683 } 8684 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8685 } 8686 PetscFunctionReturn(0); 8687 } 8688 8689 /*@ 8690 MatIsHermitian - Test whether a matrix is Hermitian 8691 8692 Collective on Mat 8693 8694 Input Parameter: 8695 + A - the matrix to test 8696 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8697 8698 Output Parameters: 8699 . flg - the result 8700 8701 Level: intermediate 8702 8703 Concepts: matrix^symmetry 8704 8705 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8706 MatIsSymmetricKnown(), MatIsSymmetric() 8707 @*/ 8708 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8709 { 8710 PetscErrorCode ierr; 8711 8712 PetscFunctionBegin; 8713 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8714 PetscValidPointer(flg,2); 8715 8716 if (!A->hermitian_set) { 8717 if (!A->ops->ishermitian) { 8718 MatType mattype; 8719 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8720 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8721 } 8722 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8723 if (!tol) { 8724 A->hermitian_set = PETSC_TRUE; 8725 A->hermitian = *flg; 8726 if (A->hermitian) { 8727 A->structurally_symmetric_set = PETSC_TRUE; 8728 A->structurally_symmetric = PETSC_TRUE; 8729 } 8730 } 8731 } else if (A->hermitian) { 8732 *flg = PETSC_TRUE; 8733 } else if (!tol) { 8734 *flg = PETSC_FALSE; 8735 } else { 8736 if (!A->ops->ishermitian) { 8737 MatType mattype; 8738 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8739 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8740 } 8741 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8742 } 8743 PetscFunctionReturn(0); 8744 } 8745 8746 /*@ 8747 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8748 8749 Not Collective 8750 8751 Input Parameter: 8752 . A - the matrix to check 8753 8754 Output Parameters: 8755 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8756 - flg - the result 8757 8758 Level: advanced 8759 8760 Concepts: matrix^symmetry 8761 8762 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8763 if you want it explicitly checked 8764 8765 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8766 @*/ 8767 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8768 { 8769 PetscFunctionBegin; 8770 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8771 PetscValidPointer(set,2); 8772 PetscValidPointer(flg,3); 8773 if (A->symmetric_set) { 8774 *set = PETSC_TRUE; 8775 *flg = A->symmetric; 8776 } else { 8777 *set = PETSC_FALSE; 8778 } 8779 PetscFunctionReturn(0); 8780 } 8781 8782 /*@ 8783 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8784 8785 Not Collective 8786 8787 Input Parameter: 8788 . A - the matrix to check 8789 8790 Output Parameters: 8791 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8792 - flg - the result 8793 8794 Level: advanced 8795 8796 Concepts: matrix^symmetry 8797 8798 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8799 if you want it explicitly checked 8800 8801 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8802 @*/ 8803 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8804 { 8805 PetscFunctionBegin; 8806 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8807 PetscValidPointer(set,2); 8808 PetscValidPointer(flg,3); 8809 if (A->hermitian_set) { 8810 *set = PETSC_TRUE; 8811 *flg = A->hermitian; 8812 } else { 8813 *set = PETSC_FALSE; 8814 } 8815 PetscFunctionReturn(0); 8816 } 8817 8818 /*@ 8819 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8820 8821 Collective on Mat 8822 8823 Input Parameter: 8824 . A - the matrix to test 8825 8826 Output Parameters: 8827 . flg - the result 8828 8829 Level: intermediate 8830 8831 Concepts: matrix^symmetry 8832 8833 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8834 @*/ 8835 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8836 { 8837 PetscErrorCode ierr; 8838 8839 PetscFunctionBegin; 8840 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8841 PetscValidPointer(flg,2); 8842 if (!A->structurally_symmetric_set) { 8843 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8844 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8845 8846 A->structurally_symmetric_set = PETSC_TRUE; 8847 } 8848 *flg = A->structurally_symmetric; 8849 PetscFunctionReturn(0); 8850 } 8851 8852 /*@ 8853 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8854 to be communicated to other processors during the MatAssemblyBegin/End() process 8855 8856 Not collective 8857 8858 Input Parameter: 8859 . vec - the vector 8860 8861 Output Parameters: 8862 + nstash - the size of the stash 8863 . reallocs - the number of additional mallocs incurred. 8864 . bnstash - the size of the block stash 8865 - breallocs - the number of additional mallocs incurred.in the block stash 8866 8867 Level: advanced 8868 8869 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8870 8871 @*/ 8872 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8873 { 8874 PetscErrorCode ierr; 8875 8876 PetscFunctionBegin; 8877 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8878 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8879 PetscFunctionReturn(0); 8880 } 8881 8882 /*@C 8883 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8884 parallel layout 8885 8886 Collective on Mat 8887 8888 Input Parameter: 8889 . mat - the matrix 8890 8891 Output Parameter: 8892 + right - (optional) vector that the matrix can be multiplied against 8893 - left - (optional) vector that the matrix vector product can be stored in 8894 8895 Notes: 8896 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(). 8897 8898 Notes: 8899 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8900 8901 Level: advanced 8902 8903 .seealso: MatCreate(), VecDestroy() 8904 @*/ 8905 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8906 { 8907 PetscErrorCode ierr; 8908 8909 PetscFunctionBegin; 8910 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8911 PetscValidType(mat,1); 8912 if (mat->ops->getvecs) { 8913 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8914 } else { 8915 PetscInt rbs,cbs; 8916 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8917 if (right) { 8918 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8919 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8920 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8921 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8922 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8923 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8924 } 8925 if (left) { 8926 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8927 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8928 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8929 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8930 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8931 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8932 } 8933 } 8934 PetscFunctionReturn(0); 8935 } 8936 8937 /*@C 8938 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8939 with default values. 8940 8941 Not Collective 8942 8943 Input Parameters: 8944 . info - the MatFactorInfo data structure 8945 8946 8947 Notes: 8948 The solvers are generally used through the KSP and PC objects, for example 8949 PCLU, PCILU, PCCHOLESKY, PCICC 8950 8951 Level: developer 8952 8953 .seealso: MatFactorInfo 8954 8955 Developer Note: fortran interface is not autogenerated as the f90 8956 interface defintion cannot be generated correctly [due to MatFactorInfo] 8957 8958 @*/ 8959 8960 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8961 { 8962 PetscErrorCode ierr; 8963 8964 PetscFunctionBegin; 8965 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8966 PetscFunctionReturn(0); 8967 } 8968 8969 /*@ 8970 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 8971 8972 Collective on Mat 8973 8974 Input Parameters: 8975 + mat - the factored matrix 8976 - is - the index set defining the Schur indices (0-based) 8977 8978 Notes: 8979 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 8980 8981 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 8982 8983 Level: developer 8984 8985 Concepts: 8986 8987 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 8988 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 8989 8990 @*/ 8991 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8992 { 8993 PetscErrorCode ierr,(*f)(Mat,IS); 8994 8995 PetscFunctionBegin; 8996 PetscValidType(mat,1); 8997 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8998 PetscValidType(is,2); 8999 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9000 PetscCheckSameComm(mat,1,is,2); 9001 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9002 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 9003 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"); 9004 if (mat->schur) { 9005 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 9006 } 9007 ierr = (*f)(mat,is);CHKERRQ(ierr); 9008 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9009 ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr); 9010 PetscFunctionReturn(0); 9011 } 9012 9013 /*@ 9014 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9015 9016 Logically Collective on Mat 9017 9018 Input Parameters: 9019 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9020 . S - location where to return the Schur complement, can be NULL 9021 - status - the status of the Schur complement matrix, can be NULL 9022 9023 Notes: 9024 You must call MatFactorSetSchurIS() before calling this routine. 9025 9026 The routine provides a copy of the Schur matrix stored within the solver data structures. 9027 The caller must destroy the object when it is no longer needed. 9028 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9029 9030 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) 9031 9032 Developer Notes: 9033 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9034 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9035 9036 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9037 9038 Level: advanced 9039 9040 References: 9041 9042 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 9043 @*/ 9044 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9045 { 9046 PetscErrorCode ierr; 9047 9048 PetscFunctionBegin; 9049 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9050 if (S) PetscValidPointer(S,2); 9051 if (status) PetscValidPointer(status,3); 9052 if (S) { 9053 PetscErrorCode (*f)(Mat,Mat*); 9054 9055 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 9056 if (f) { 9057 ierr = (*f)(F,S);CHKERRQ(ierr); 9058 } else { 9059 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 9060 } 9061 } 9062 if (status) *status = F->schur_status; 9063 PetscFunctionReturn(0); 9064 } 9065 9066 /*@ 9067 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9068 9069 Logically Collective on Mat 9070 9071 Input Parameters: 9072 + F - the factored matrix obtained by calling MatGetFactor() 9073 . *S - location where to return the Schur complement, can be NULL 9074 - status - the status of the Schur complement matrix, can be NULL 9075 9076 Notes: 9077 You must call MatFactorSetSchurIS() before calling this routine. 9078 9079 Schur complement mode is currently implemented for sequential matrices. 9080 The routine returns a the Schur Complement stored within the data strutures of the solver. 9081 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9082 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9083 9084 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9085 9086 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9087 9088 Level: advanced 9089 9090 References: 9091 9092 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9093 @*/ 9094 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9095 { 9096 PetscFunctionBegin; 9097 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9098 if (S) PetscValidPointer(S,2); 9099 if (status) PetscValidPointer(status,3); 9100 if (S) *S = F->schur; 9101 if (status) *status = F->schur_status; 9102 PetscFunctionReturn(0); 9103 } 9104 9105 /*@ 9106 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9107 9108 Logically Collective on Mat 9109 9110 Input Parameters: 9111 + F - the factored matrix obtained by calling MatGetFactor() 9112 . *S - location where the Schur complement is stored 9113 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9114 9115 Notes: 9116 9117 Level: advanced 9118 9119 References: 9120 9121 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9122 @*/ 9123 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9124 { 9125 PetscErrorCode ierr; 9126 9127 PetscFunctionBegin; 9128 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9129 if (S) { 9130 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9131 *S = NULL; 9132 } 9133 F->schur_status = status; 9134 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 9135 PetscFunctionReturn(0); 9136 } 9137 9138 /*@ 9139 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9140 9141 Logically Collective on Mat 9142 9143 Input Parameters: 9144 + F - the factored matrix obtained by calling MatGetFactor() 9145 . rhs - location where the right hand side of the Schur complement system is stored 9146 - sol - location where the solution of the Schur complement system has to be returned 9147 9148 Notes: 9149 The sizes of the vectors should match the size of the Schur complement 9150 9151 Must be called after MatFactorSetSchurIS() 9152 9153 Level: advanced 9154 9155 References: 9156 9157 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 9158 @*/ 9159 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9160 { 9161 PetscErrorCode ierr; 9162 9163 PetscFunctionBegin; 9164 PetscValidType(F,1); 9165 PetscValidType(rhs,2); 9166 PetscValidType(sol,3); 9167 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9168 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9169 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9170 PetscCheckSameComm(F,1,rhs,2); 9171 PetscCheckSameComm(F,1,sol,3); 9172 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9173 switch (F->schur_status) { 9174 case MAT_FACTOR_SCHUR_FACTORED: 9175 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9176 break; 9177 case MAT_FACTOR_SCHUR_INVERTED: 9178 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9179 break; 9180 default: 9181 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9182 break; 9183 } 9184 PetscFunctionReturn(0); 9185 } 9186 9187 /*@ 9188 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9189 9190 Logically Collective on Mat 9191 9192 Input Parameters: 9193 + F - the factored matrix obtained by calling MatGetFactor() 9194 . rhs - location where the right hand side of the Schur complement system is stored 9195 - sol - location where the solution of the Schur complement system has to be returned 9196 9197 Notes: 9198 The sizes of the vectors should match the size of the Schur complement 9199 9200 Must be called after MatFactorSetSchurIS() 9201 9202 Level: advanced 9203 9204 References: 9205 9206 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9207 @*/ 9208 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9209 { 9210 PetscErrorCode ierr; 9211 9212 PetscFunctionBegin; 9213 PetscValidType(F,1); 9214 PetscValidType(rhs,2); 9215 PetscValidType(sol,3); 9216 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9217 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9218 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9219 PetscCheckSameComm(F,1,rhs,2); 9220 PetscCheckSameComm(F,1,sol,3); 9221 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9222 switch (F->schur_status) { 9223 case MAT_FACTOR_SCHUR_FACTORED: 9224 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9225 break; 9226 case MAT_FACTOR_SCHUR_INVERTED: 9227 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9228 break; 9229 default: 9230 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9231 break; 9232 } 9233 PetscFunctionReturn(0); 9234 } 9235 9236 /*@ 9237 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9238 9239 Logically Collective on Mat 9240 9241 Input Parameters: 9242 + F - the factored matrix obtained by calling MatGetFactor() 9243 9244 Notes: 9245 Must be called after MatFactorSetSchurIS(). 9246 9247 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9248 9249 Level: advanced 9250 9251 References: 9252 9253 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9254 @*/ 9255 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9256 { 9257 PetscErrorCode ierr; 9258 9259 PetscFunctionBegin; 9260 PetscValidType(F,1); 9261 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9262 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9263 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9264 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9265 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9266 PetscFunctionReturn(0); 9267 } 9268 9269 /*@ 9270 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9271 9272 Logically Collective on Mat 9273 9274 Input Parameters: 9275 + F - the factored matrix obtained by calling MatGetFactor() 9276 9277 Notes: 9278 Must be called after MatFactorSetSchurIS(). 9279 9280 Level: advanced 9281 9282 References: 9283 9284 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9285 @*/ 9286 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9287 { 9288 PetscErrorCode ierr; 9289 9290 PetscFunctionBegin; 9291 PetscValidType(F,1); 9292 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9293 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9294 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9295 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9296 PetscFunctionReturn(0); 9297 } 9298 9299 /*@ 9300 MatPtAP - Creates the matrix product C = P^T * A * P 9301 9302 Neighbor-wise Collective on Mat 9303 9304 Input Parameters: 9305 + A - the matrix 9306 . P - the projection matrix 9307 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9308 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9309 if the result is a dense matrix this is irrelevent 9310 9311 Output Parameters: 9312 . C - the product matrix 9313 9314 Notes: 9315 C will be created and must be destroyed by the user with MatDestroy(). 9316 9317 This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes 9318 which inherit from AIJ. 9319 9320 Level: intermediate 9321 9322 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9323 @*/ 9324 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9325 { 9326 PetscErrorCode ierr; 9327 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9328 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9329 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9330 PetscBool sametype; 9331 9332 PetscFunctionBegin; 9333 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9334 PetscValidType(A,1); 9335 MatCheckPreallocated(A,1); 9336 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9337 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9338 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9339 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9340 PetscValidType(P,2); 9341 MatCheckPreallocated(P,2); 9342 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9343 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9344 9345 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); 9346 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); 9347 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9348 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9349 9350 if (scall == MAT_REUSE_MATRIX) { 9351 PetscValidPointer(*C,5); 9352 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9353 9354 if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX"); 9355 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9356 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9357 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9358 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9359 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9360 PetscFunctionReturn(0); 9361 } 9362 9363 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9364 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9365 9366 fA = A->ops->ptap; 9367 fP = P->ops->ptap; 9368 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9369 if (fP == fA && sametype) { 9370 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 9371 ptap = fA; 9372 } else { 9373 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9374 char ptapname[256]; 9375 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9376 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9377 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9378 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9379 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9380 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9381 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); 9382 } 9383 9384 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9385 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9386 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9387 if (A->symmetric_set && A->symmetric) { 9388 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9389 } 9390 PetscFunctionReturn(0); 9391 } 9392 9393 /*@ 9394 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9395 9396 Neighbor-wise Collective on Mat 9397 9398 Input Parameters: 9399 + A - the matrix 9400 - P - the projection matrix 9401 9402 Output Parameters: 9403 . C - the product matrix 9404 9405 Notes: 9406 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9407 the user using MatDeatroy(). 9408 9409 This routine is currently only implemented for pairs of AIJ matrices and classes 9410 which inherit from AIJ. C will be of type MATAIJ. 9411 9412 Level: intermediate 9413 9414 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9415 @*/ 9416 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9417 { 9418 PetscErrorCode ierr; 9419 9420 PetscFunctionBegin; 9421 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9422 PetscValidType(A,1); 9423 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9424 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9425 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9426 PetscValidType(P,2); 9427 MatCheckPreallocated(P,2); 9428 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9429 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9430 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9431 PetscValidType(C,3); 9432 MatCheckPreallocated(C,3); 9433 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9434 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); 9435 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); 9436 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); 9437 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); 9438 MatCheckPreallocated(A,1); 9439 9440 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9441 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9442 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9443 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9444 PetscFunctionReturn(0); 9445 } 9446 9447 /*@ 9448 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9449 9450 Neighbor-wise Collective on Mat 9451 9452 Input Parameters: 9453 + A - the matrix 9454 - P - the projection matrix 9455 9456 Output Parameters: 9457 . C - the (i,j) structure of the product matrix 9458 9459 Notes: 9460 C will be created and must be destroyed by the user with MatDestroy(). 9461 9462 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9463 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9464 this (i,j) structure by calling MatPtAPNumeric(). 9465 9466 Level: intermediate 9467 9468 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9469 @*/ 9470 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9471 { 9472 PetscErrorCode ierr; 9473 9474 PetscFunctionBegin; 9475 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9476 PetscValidType(A,1); 9477 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9478 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9479 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9480 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9481 PetscValidType(P,2); 9482 MatCheckPreallocated(P,2); 9483 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9484 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9485 PetscValidPointer(C,3); 9486 9487 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); 9488 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); 9489 MatCheckPreallocated(A,1); 9490 9491 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9492 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9493 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9494 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9495 9496 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9497 PetscFunctionReturn(0); 9498 } 9499 9500 /*@ 9501 MatRARt - Creates the matrix product C = R * A * R^T 9502 9503 Neighbor-wise Collective on Mat 9504 9505 Input Parameters: 9506 + A - the matrix 9507 . R - the projection matrix 9508 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9509 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9510 if the result is a dense matrix this is irrelevent 9511 9512 Output Parameters: 9513 . C - the product matrix 9514 9515 Notes: 9516 C will be created and must be destroyed by the user with MatDestroy(). 9517 9518 This routine is currently only implemented for pairs of AIJ matrices and classes 9519 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9520 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9521 We recommend using MatPtAP(). 9522 9523 Level: intermediate 9524 9525 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9526 @*/ 9527 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9528 { 9529 PetscErrorCode ierr; 9530 9531 PetscFunctionBegin; 9532 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9533 PetscValidType(A,1); 9534 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9535 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9536 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9537 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9538 PetscValidType(R,2); 9539 MatCheckPreallocated(R,2); 9540 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9541 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9542 PetscValidPointer(C,3); 9543 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); 9544 9545 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9546 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9547 MatCheckPreallocated(A,1); 9548 9549 if (!A->ops->rart) { 9550 Mat Rt; 9551 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9552 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9553 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9554 PetscFunctionReturn(0); 9555 } 9556 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9557 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9558 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9559 PetscFunctionReturn(0); 9560 } 9561 9562 /*@ 9563 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9564 9565 Neighbor-wise Collective on Mat 9566 9567 Input Parameters: 9568 + A - the matrix 9569 - R - the projection matrix 9570 9571 Output Parameters: 9572 . C - the product matrix 9573 9574 Notes: 9575 C must have been created by calling MatRARtSymbolic and must be destroyed by 9576 the user using MatDestroy(). 9577 9578 This routine is currently only implemented for pairs of AIJ matrices and classes 9579 which inherit from AIJ. C will be of type MATAIJ. 9580 9581 Level: intermediate 9582 9583 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9584 @*/ 9585 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9586 { 9587 PetscErrorCode ierr; 9588 9589 PetscFunctionBegin; 9590 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9591 PetscValidType(A,1); 9592 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9593 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9594 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9595 PetscValidType(R,2); 9596 MatCheckPreallocated(R,2); 9597 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9598 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9599 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9600 PetscValidType(C,3); 9601 MatCheckPreallocated(C,3); 9602 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9603 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); 9604 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); 9605 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); 9606 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); 9607 MatCheckPreallocated(A,1); 9608 9609 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9610 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9611 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9612 PetscFunctionReturn(0); 9613 } 9614 9615 /*@ 9616 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9617 9618 Neighbor-wise Collective on Mat 9619 9620 Input Parameters: 9621 + A - the matrix 9622 - R - the projection matrix 9623 9624 Output Parameters: 9625 . C - the (i,j) structure of the product matrix 9626 9627 Notes: 9628 C will be created and must be destroyed by the user with MatDestroy(). 9629 9630 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9631 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9632 this (i,j) structure by calling MatRARtNumeric(). 9633 9634 Level: intermediate 9635 9636 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9637 @*/ 9638 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9639 { 9640 PetscErrorCode ierr; 9641 9642 PetscFunctionBegin; 9643 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9644 PetscValidType(A,1); 9645 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9646 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9647 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9648 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9649 PetscValidType(R,2); 9650 MatCheckPreallocated(R,2); 9651 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9652 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9653 PetscValidPointer(C,3); 9654 9655 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); 9656 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); 9657 MatCheckPreallocated(A,1); 9658 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9659 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9660 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9661 9662 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9663 PetscFunctionReturn(0); 9664 } 9665 9666 /*@ 9667 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9668 9669 Neighbor-wise Collective on Mat 9670 9671 Input Parameters: 9672 + A - the left matrix 9673 . B - the right matrix 9674 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9675 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9676 if the result is a dense matrix this is irrelevent 9677 9678 Output Parameters: 9679 . C - the product matrix 9680 9681 Notes: 9682 Unless scall is MAT_REUSE_MATRIX C will be created. 9683 9684 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 9685 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9686 9687 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9688 actually needed. 9689 9690 If you have many matrices with the same non-zero structure to multiply, you 9691 should either 9692 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9693 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9694 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 9695 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9696 9697 Level: intermediate 9698 9699 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9700 @*/ 9701 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9702 { 9703 PetscErrorCode ierr; 9704 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9705 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9706 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9707 9708 PetscFunctionBegin; 9709 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9710 PetscValidType(A,1); 9711 MatCheckPreallocated(A,1); 9712 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9713 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9714 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9715 PetscValidType(B,2); 9716 MatCheckPreallocated(B,2); 9717 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9718 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9719 PetscValidPointer(C,3); 9720 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9721 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); 9722 if (scall == MAT_REUSE_MATRIX) { 9723 PetscValidPointer(*C,5); 9724 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9725 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9726 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9727 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9728 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9729 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9730 PetscFunctionReturn(0); 9731 } 9732 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9733 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9734 9735 fA = A->ops->matmult; 9736 fB = B->ops->matmult; 9737 if (fB == fA) { 9738 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9739 mult = fB; 9740 } else { 9741 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9742 char multname[256]; 9743 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9744 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9745 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9746 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9747 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9748 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9749 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); 9750 } 9751 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9752 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9753 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9754 PetscFunctionReturn(0); 9755 } 9756 9757 /*@ 9758 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9759 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9760 9761 Neighbor-wise Collective on Mat 9762 9763 Input Parameters: 9764 + A - the left matrix 9765 . B - the right matrix 9766 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9767 if C is a dense matrix this is irrelevent 9768 9769 Output Parameters: 9770 . C - the product matrix 9771 9772 Notes: 9773 Unless scall is MAT_REUSE_MATRIX C will be created. 9774 9775 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9776 actually needed. 9777 9778 This routine is currently implemented for 9779 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9780 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9781 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9782 9783 Level: intermediate 9784 9785 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 9786 We should incorporate them into PETSc. 9787 9788 .seealso: MatMatMult(), MatMatMultNumeric() 9789 @*/ 9790 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9791 { 9792 PetscErrorCode ierr; 9793 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9794 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9795 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9796 9797 PetscFunctionBegin; 9798 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9799 PetscValidType(A,1); 9800 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9801 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9802 9803 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9804 PetscValidType(B,2); 9805 MatCheckPreallocated(B,2); 9806 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9807 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9808 PetscValidPointer(C,3); 9809 9810 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); 9811 if (fill == PETSC_DEFAULT) fill = 2.0; 9812 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9813 MatCheckPreallocated(A,1); 9814 9815 Asymbolic = A->ops->matmultsymbolic; 9816 Bsymbolic = B->ops->matmultsymbolic; 9817 if (Asymbolic == Bsymbolic) { 9818 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9819 symbolic = Bsymbolic; 9820 } else { /* dispatch based on the type of A and B */ 9821 char symbolicname[256]; 9822 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9823 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9824 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9825 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9826 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9827 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9828 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); 9829 } 9830 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9831 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9832 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9833 PetscFunctionReturn(0); 9834 } 9835 9836 /*@ 9837 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9838 Call this routine after first calling MatMatMultSymbolic(). 9839 9840 Neighbor-wise Collective on Mat 9841 9842 Input Parameters: 9843 + A - the left matrix 9844 - B - the right matrix 9845 9846 Output Parameters: 9847 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9848 9849 Notes: 9850 C must have been created with MatMatMultSymbolic(). 9851 9852 This routine is currently implemented for 9853 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9854 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9855 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9856 9857 Level: intermediate 9858 9859 .seealso: MatMatMult(), MatMatMultSymbolic() 9860 @*/ 9861 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9862 { 9863 PetscErrorCode ierr; 9864 9865 PetscFunctionBegin; 9866 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9867 PetscFunctionReturn(0); 9868 } 9869 9870 /*@ 9871 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9872 9873 Neighbor-wise Collective on Mat 9874 9875 Input Parameters: 9876 + A - the left matrix 9877 . B - the right matrix 9878 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9879 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9880 9881 Output Parameters: 9882 . C - the product matrix 9883 9884 Notes: 9885 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9886 9887 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9888 9889 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9890 actually needed. 9891 9892 This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class. 9893 9894 Level: intermediate 9895 9896 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9897 @*/ 9898 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9899 { 9900 PetscErrorCode ierr; 9901 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9902 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9903 9904 PetscFunctionBegin; 9905 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9906 PetscValidType(A,1); 9907 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9908 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9909 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9910 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9911 PetscValidType(B,2); 9912 MatCheckPreallocated(B,2); 9913 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9914 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9915 PetscValidPointer(C,3); 9916 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); 9917 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9918 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9919 MatCheckPreallocated(A,1); 9920 9921 fA = A->ops->mattransposemult; 9922 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9923 fB = B->ops->mattransposemult; 9924 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9925 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); 9926 9927 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9928 if (scall == MAT_INITIAL_MATRIX) { 9929 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9930 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9931 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9932 } 9933 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9934 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9935 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9936 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9937 PetscFunctionReturn(0); 9938 } 9939 9940 /*@ 9941 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9942 9943 Neighbor-wise Collective on Mat 9944 9945 Input Parameters: 9946 + A - the left matrix 9947 . B - the right matrix 9948 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9949 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9950 9951 Output Parameters: 9952 . C - the product matrix 9953 9954 Notes: 9955 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9956 9957 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9958 9959 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9960 actually needed. 9961 9962 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9963 which inherit from SeqAIJ. C will be of same type as the input matrices. 9964 9965 Level: intermediate 9966 9967 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 9968 @*/ 9969 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9970 { 9971 PetscErrorCode ierr; 9972 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9973 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9974 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 9975 9976 PetscFunctionBegin; 9977 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9978 PetscValidType(A,1); 9979 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9980 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9981 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9982 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9983 PetscValidType(B,2); 9984 MatCheckPreallocated(B,2); 9985 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9986 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9987 PetscValidPointer(C,3); 9988 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); 9989 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9990 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9991 MatCheckPreallocated(A,1); 9992 9993 fA = A->ops->transposematmult; 9994 fB = B->ops->transposematmult; 9995 if (fB==fA) { 9996 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9997 transposematmult = fA; 9998 } else { 9999 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 10000 char multname[256]; 10001 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 10002 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10003 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10004 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10005 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 10006 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 10007 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); 10008 } 10009 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 10010 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 10011 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 10012 PetscFunctionReturn(0); 10013 } 10014 10015 /*@ 10016 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 10017 10018 Neighbor-wise Collective on Mat 10019 10020 Input Parameters: 10021 + A - the left matrix 10022 . B - the middle matrix 10023 . C - the right matrix 10024 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10025 - 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 10026 if the result is a dense matrix this is irrelevent 10027 10028 Output Parameters: 10029 . D - the product matrix 10030 10031 Notes: 10032 Unless scall is MAT_REUSE_MATRIX D will be created. 10033 10034 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10035 10036 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10037 actually needed. 10038 10039 If you have many matrices with the same non-zero structure to multiply, you 10040 should use MAT_REUSE_MATRIX in all calls but the first or 10041 10042 Level: intermediate 10043 10044 .seealso: MatMatMult, MatPtAP() 10045 @*/ 10046 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10047 { 10048 PetscErrorCode ierr; 10049 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10050 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10051 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10052 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 10053 10054 PetscFunctionBegin; 10055 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10056 PetscValidType(A,1); 10057 MatCheckPreallocated(A,1); 10058 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10059 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10060 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10061 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10062 PetscValidType(B,2); 10063 MatCheckPreallocated(B,2); 10064 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10065 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10066 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10067 PetscValidPointer(C,3); 10068 MatCheckPreallocated(C,3); 10069 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10070 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10071 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); 10072 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); 10073 if (scall == MAT_REUSE_MATRIX) { 10074 PetscValidPointer(*D,6); 10075 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 10076 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10077 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10078 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10079 PetscFunctionReturn(0); 10080 } 10081 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10082 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 10083 10084 fA = A->ops->matmatmult; 10085 fB = B->ops->matmatmult; 10086 fC = C->ops->matmatmult; 10087 if (fA == fB && fA == fC) { 10088 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 10089 mult = fA; 10090 } else { 10091 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 10092 char multname[256]; 10093 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 10094 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10095 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10096 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10097 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10098 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 10099 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 10100 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 10101 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); 10102 } 10103 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10104 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10105 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10106 PetscFunctionReturn(0); 10107 } 10108 10109 /*@ 10110 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10111 10112 Collective on Mat 10113 10114 Input Parameters: 10115 + mat - the matrix 10116 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10117 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10118 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10119 10120 Output Parameter: 10121 . matredundant - redundant matrix 10122 10123 Notes: 10124 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10125 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10126 10127 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 10128 calling it. 10129 10130 Level: advanced 10131 10132 Concepts: subcommunicator 10133 Concepts: duplicate matrix 10134 10135 .seealso: MatDestroy() 10136 @*/ 10137 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10138 { 10139 PetscErrorCode ierr; 10140 MPI_Comm comm; 10141 PetscMPIInt size; 10142 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10143 Mat_Redundant *redund=NULL; 10144 PetscSubcomm psubcomm=NULL; 10145 MPI_Comm subcomm_in=subcomm; 10146 Mat *matseq; 10147 IS isrow,iscol; 10148 PetscBool newsubcomm=PETSC_FALSE; 10149 10150 PetscFunctionBegin; 10151 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10152 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10153 PetscValidPointer(*matredundant,5); 10154 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10155 } 10156 10157 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10158 if (size == 1 || nsubcomm == 1) { 10159 if (reuse == MAT_INITIAL_MATRIX) { 10160 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10161 } else { 10162 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"); 10163 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10164 } 10165 PetscFunctionReturn(0); 10166 } 10167 10168 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10169 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10170 MatCheckPreallocated(mat,1); 10171 10172 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10173 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10174 /* create psubcomm, then get subcomm */ 10175 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10176 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10177 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10178 10179 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10180 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10181 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10182 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10183 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10184 newsubcomm = PETSC_TRUE; 10185 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10186 } 10187 10188 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10189 if (reuse == MAT_INITIAL_MATRIX) { 10190 mloc_sub = PETSC_DECIDE; 10191 nloc_sub = PETSC_DECIDE; 10192 if (bs < 1) { 10193 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10194 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10195 } else { 10196 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10197 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10198 } 10199 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10200 rstart = rend - mloc_sub; 10201 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10202 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10203 } else { /* reuse == MAT_REUSE_MATRIX */ 10204 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"); 10205 /* retrieve subcomm */ 10206 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10207 redund = (*matredundant)->redundant; 10208 isrow = redund->isrow; 10209 iscol = redund->iscol; 10210 matseq = redund->matseq; 10211 } 10212 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10213 10214 /* get matredundant over subcomm */ 10215 if (reuse == MAT_INITIAL_MATRIX) { 10216 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10217 10218 /* create a supporting struct and attach it to C for reuse */ 10219 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10220 (*matredundant)->redundant = redund; 10221 redund->isrow = isrow; 10222 redund->iscol = iscol; 10223 redund->matseq = matseq; 10224 if (newsubcomm) { 10225 redund->subcomm = subcomm; 10226 } else { 10227 redund->subcomm = MPI_COMM_NULL; 10228 } 10229 } else { 10230 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10231 } 10232 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10233 PetscFunctionReturn(0); 10234 } 10235 10236 /*@C 10237 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10238 a given 'mat' object. Each submatrix can span multiple procs. 10239 10240 Collective on Mat 10241 10242 Input Parameters: 10243 + mat - the matrix 10244 . subcomm - the subcommunicator obtained by com_split(comm) 10245 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10246 10247 Output Parameter: 10248 . subMat - 'parallel submatrices each spans a given subcomm 10249 10250 Notes: 10251 The submatrix partition across processors is dictated by 'subComm' a 10252 communicator obtained by com_split(comm). The comm_split 10253 is not restriced to be grouped with consecutive original ranks. 10254 10255 Due the comm_split() usage, the parallel layout of the submatrices 10256 map directly to the layout of the original matrix [wrt the local 10257 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10258 into the 'DiagonalMat' of the subMat, hence it is used directly from 10259 the subMat. However the offDiagMat looses some columns - and this is 10260 reconstructed with MatSetValues() 10261 10262 Level: advanced 10263 10264 Concepts: subcommunicator 10265 Concepts: submatrices 10266 10267 .seealso: MatCreateSubMatrices() 10268 @*/ 10269 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10270 { 10271 PetscErrorCode ierr; 10272 PetscMPIInt commsize,subCommSize; 10273 10274 PetscFunctionBegin; 10275 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10276 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10277 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10278 10279 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"); 10280 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10281 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10282 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10283 PetscFunctionReturn(0); 10284 } 10285 10286 /*@ 10287 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10288 10289 Not Collective 10290 10291 Input Arguments: 10292 mat - matrix to extract local submatrix from 10293 isrow - local row indices for submatrix 10294 iscol - local column indices for submatrix 10295 10296 Output Arguments: 10297 submat - the submatrix 10298 10299 Level: intermediate 10300 10301 Notes: 10302 The submat should be returned with MatRestoreLocalSubMatrix(). 10303 10304 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10305 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10306 10307 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10308 MatSetValuesBlockedLocal() will also be implemented. 10309 10310 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10311 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10312 10313 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10314 @*/ 10315 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10316 { 10317 PetscErrorCode ierr; 10318 10319 PetscFunctionBegin; 10320 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10321 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10322 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10323 PetscCheckSameComm(isrow,2,iscol,3); 10324 PetscValidPointer(submat,4); 10325 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10326 10327 if (mat->ops->getlocalsubmatrix) { 10328 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10329 } else { 10330 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10331 } 10332 PetscFunctionReturn(0); 10333 } 10334 10335 /*@ 10336 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10337 10338 Not Collective 10339 10340 Input Arguments: 10341 mat - matrix to extract local submatrix from 10342 isrow - local row indices for submatrix 10343 iscol - local column indices for submatrix 10344 submat - the submatrix 10345 10346 Level: intermediate 10347 10348 .seealso: MatGetLocalSubMatrix() 10349 @*/ 10350 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10351 { 10352 PetscErrorCode ierr; 10353 10354 PetscFunctionBegin; 10355 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10356 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10357 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10358 PetscCheckSameComm(isrow,2,iscol,3); 10359 PetscValidPointer(submat,4); 10360 if (*submat) { 10361 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10362 } 10363 10364 if (mat->ops->restorelocalsubmatrix) { 10365 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10366 } else { 10367 ierr = MatDestroy(submat);CHKERRQ(ierr); 10368 } 10369 *submat = NULL; 10370 PetscFunctionReturn(0); 10371 } 10372 10373 /* --------------------------------------------------------*/ 10374 /*@ 10375 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10376 10377 Collective on Mat 10378 10379 Input Parameter: 10380 . mat - the matrix 10381 10382 Output Parameter: 10383 . is - if any rows have zero diagonals this contains the list of them 10384 10385 Level: developer 10386 10387 Concepts: matrix-vector product 10388 10389 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10390 @*/ 10391 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10392 { 10393 PetscErrorCode ierr; 10394 10395 PetscFunctionBegin; 10396 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10397 PetscValidType(mat,1); 10398 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10399 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10400 10401 if (!mat->ops->findzerodiagonals) { 10402 Vec diag; 10403 const PetscScalar *a; 10404 PetscInt *rows; 10405 PetscInt rStart, rEnd, r, nrow = 0; 10406 10407 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10408 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10409 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10410 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10411 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10412 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10413 nrow = 0; 10414 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10415 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10416 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10417 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10418 } else { 10419 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10420 } 10421 PetscFunctionReturn(0); 10422 } 10423 10424 /*@ 10425 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10426 10427 Collective on Mat 10428 10429 Input Parameter: 10430 . mat - the matrix 10431 10432 Output Parameter: 10433 . is - contains the list of rows with off block diagonal entries 10434 10435 Level: developer 10436 10437 Concepts: matrix-vector product 10438 10439 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10440 @*/ 10441 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10442 { 10443 PetscErrorCode ierr; 10444 10445 PetscFunctionBegin; 10446 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10447 PetscValidType(mat,1); 10448 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10449 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10450 10451 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10452 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10453 PetscFunctionReturn(0); 10454 } 10455 10456 /*@C 10457 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10458 10459 Collective on Mat 10460 10461 Input Parameters: 10462 . mat - the matrix 10463 10464 Output Parameters: 10465 . values - the block inverses in column major order (FORTRAN-like) 10466 10467 Note: 10468 This routine is not available from Fortran. 10469 10470 Level: advanced 10471 10472 .seealso: MatInvertBockDiagonalMat 10473 @*/ 10474 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10475 { 10476 PetscErrorCode ierr; 10477 10478 PetscFunctionBegin; 10479 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10480 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10481 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10482 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10483 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10484 PetscFunctionReturn(0); 10485 } 10486 10487 /*@C 10488 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10489 10490 Collective on Mat 10491 10492 Input Parameters: 10493 + mat - the matrix 10494 . nblocks - the number of blocks 10495 - bsizes - the size of each block 10496 10497 Output Parameters: 10498 . values - the block inverses in column major order (FORTRAN-like) 10499 10500 Note: 10501 This routine is not available from Fortran. 10502 10503 Level: advanced 10504 10505 .seealso: MatInvertBockDiagonal() 10506 @*/ 10507 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10508 { 10509 PetscErrorCode ierr; 10510 10511 PetscFunctionBegin; 10512 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10513 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10514 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10515 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10516 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10517 PetscFunctionReturn(0); 10518 } 10519 10520 /*@ 10521 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10522 10523 Collective on Mat 10524 10525 Input Parameters: 10526 . A - the matrix 10527 10528 Output Parameters: 10529 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10530 10531 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10532 10533 Level: advanced 10534 10535 .seealso: MatInvertBockDiagonal() 10536 @*/ 10537 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10538 { 10539 PetscErrorCode ierr; 10540 const PetscScalar *vals; 10541 PetscInt *dnnz; 10542 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10543 10544 PetscFunctionBegin; 10545 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10546 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10547 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10548 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10549 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10550 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10551 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10552 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10553 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10554 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10555 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10556 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10557 for (i = rstart/bs; i < rend/bs; i++) { 10558 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10559 } 10560 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10561 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10562 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10563 PetscFunctionReturn(0); 10564 } 10565 10566 /*@C 10567 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10568 via MatTransposeColoringCreate(). 10569 10570 Collective on MatTransposeColoring 10571 10572 Input Parameter: 10573 . c - coloring context 10574 10575 Level: intermediate 10576 10577 .seealso: MatTransposeColoringCreate() 10578 @*/ 10579 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10580 { 10581 PetscErrorCode ierr; 10582 MatTransposeColoring matcolor=*c; 10583 10584 PetscFunctionBegin; 10585 if (!matcolor) PetscFunctionReturn(0); 10586 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10587 10588 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10589 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10590 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10591 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10592 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10593 if (matcolor->brows>0) { 10594 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10595 } 10596 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10597 PetscFunctionReturn(0); 10598 } 10599 10600 /*@C 10601 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10602 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10603 MatTransposeColoring to sparse B. 10604 10605 Collective on MatTransposeColoring 10606 10607 Input Parameters: 10608 + B - sparse matrix B 10609 . Btdense - symbolic dense matrix B^T 10610 - coloring - coloring context created with MatTransposeColoringCreate() 10611 10612 Output Parameter: 10613 . Btdense - dense matrix B^T 10614 10615 Level: advanced 10616 10617 Notes: 10618 These are used internally for some implementations of MatRARt() 10619 10620 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10621 10622 .keywords: coloring 10623 @*/ 10624 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10625 { 10626 PetscErrorCode ierr; 10627 10628 PetscFunctionBegin; 10629 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10630 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10631 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10632 10633 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10634 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10635 PetscFunctionReturn(0); 10636 } 10637 10638 /*@C 10639 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10640 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10641 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10642 Csp from Cden. 10643 10644 Collective on MatTransposeColoring 10645 10646 Input Parameters: 10647 + coloring - coloring context created with MatTransposeColoringCreate() 10648 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10649 10650 Output Parameter: 10651 . Csp - sparse matrix 10652 10653 Level: advanced 10654 10655 Notes: 10656 These are used internally for some implementations of MatRARt() 10657 10658 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10659 10660 .keywords: coloring 10661 @*/ 10662 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10663 { 10664 PetscErrorCode ierr; 10665 10666 PetscFunctionBegin; 10667 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10668 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10669 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10670 10671 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10672 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10673 PetscFunctionReturn(0); 10674 } 10675 10676 /*@C 10677 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10678 10679 Collective on Mat 10680 10681 Input Parameters: 10682 + mat - the matrix product C 10683 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10684 10685 Output Parameter: 10686 . color - the new coloring context 10687 10688 Level: intermediate 10689 10690 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10691 MatTransColoringApplyDenToSp() 10692 @*/ 10693 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10694 { 10695 MatTransposeColoring c; 10696 MPI_Comm comm; 10697 PetscErrorCode ierr; 10698 10699 PetscFunctionBegin; 10700 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10701 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10702 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10703 10704 c->ctype = iscoloring->ctype; 10705 if (mat->ops->transposecoloringcreate) { 10706 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10707 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10708 10709 *color = c; 10710 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10711 PetscFunctionReturn(0); 10712 } 10713 10714 /*@ 10715 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10716 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10717 same, otherwise it will be larger 10718 10719 Not Collective 10720 10721 Input Parameter: 10722 . A - the matrix 10723 10724 Output Parameter: 10725 . state - the current state 10726 10727 Notes: 10728 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10729 different matrices 10730 10731 Level: intermediate 10732 10733 @*/ 10734 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10735 { 10736 PetscFunctionBegin; 10737 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10738 *state = mat->nonzerostate; 10739 PetscFunctionReturn(0); 10740 } 10741 10742 /*@ 10743 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10744 matrices from each processor 10745 10746 Collective on MPI_Comm 10747 10748 Input Parameters: 10749 + comm - the communicators the parallel matrix will live on 10750 . seqmat - the input sequential matrices 10751 . n - number of local columns (or PETSC_DECIDE) 10752 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10753 10754 Output Parameter: 10755 . mpimat - the parallel matrix generated 10756 10757 Level: advanced 10758 10759 Notes: 10760 The number of columns of the matrix in EACH processor MUST be the same. 10761 10762 @*/ 10763 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10764 { 10765 PetscErrorCode ierr; 10766 10767 PetscFunctionBegin; 10768 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10769 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"); 10770 10771 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10772 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10773 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10774 PetscFunctionReturn(0); 10775 } 10776 10777 /*@ 10778 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10779 ranks' ownership ranges. 10780 10781 Collective on A 10782 10783 Input Parameters: 10784 + A - the matrix to create subdomains from 10785 - N - requested number of subdomains 10786 10787 10788 Output Parameters: 10789 + n - number of subdomains resulting on this rank 10790 - iss - IS list with indices of subdomains on this rank 10791 10792 Level: advanced 10793 10794 Notes: 10795 number of subdomains must be smaller than the communicator size 10796 @*/ 10797 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10798 { 10799 MPI_Comm comm,subcomm; 10800 PetscMPIInt size,rank,color; 10801 PetscInt rstart,rend,k; 10802 PetscErrorCode ierr; 10803 10804 PetscFunctionBegin; 10805 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10806 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10807 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10808 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); 10809 *n = 1; 10810 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10811 color = rank/k; 10812 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10813 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10814 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10815 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10816 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10817 PetscFunctionReturn(0); 10818 } 10819 10820 /*@ 10821 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10822 10823 If the interpolation and restriction operators are the same, uses MatPtAP. 10824 If they are not the same, use MatMatMatMult. 10825 10826 Once the coarse grid problem is constructed, correct for interpolation operators 10827 that are not of full rank, which can legitimately happen in the case of non-nested 10828 geometric multigrid. 10829 10830 Input Parameters: 10831 + restrct - restriction operator 10832 . dA - fine grid matrix 10833 . interpolate - interpolation operator 10834 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10835 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10836 10837 Output Parameters: 10838 . A - the Galerkin coarse matrix 10839 10840 Options Database Key: 10841 . -pc_mg_galerkin <both,pmat,mat,none> 10842 10843 Level: developer 10844 10845 .keywords: MG, multigrid, Galerkin 10846 10847 .seealso: MatPtAP(), MatMatMatMult() 10848 @*/ 10849 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10850 { 10851 PetscErrorCode ierr; 10852 IS zerorows; 10853 Vec diag; 10854 10855 PetscFunctionBegin; 10856 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10857 /* Construct the coarse grid matrix */ 10858 if (interpolate == restrct) { 10859 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10860 } else { 10861 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10862 } 10863 10864 /* If the interpolation matrix is not of full rank, A will have zero rows. 10865 This can legitimately happen in the case of non-nested geometric multigrid. 10866 In that event, we set the rows of the matrix to the rows of the identity, 10867 ignoring the equations (as the RHS will also be zero). */ 10868 10869 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10870 10871 if (zerorows != NULL) { /* if there are any zero rows */ 10872 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10873 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10874 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10875 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10876 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10877 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10878 } 10879 PetscFunctionReturn(0); 10880 } 10881 10882 /*@C 10883 MatSetOperation - Allows user to set a matrix operation for any matrix type 10884 10885 Logically Collective on Mat 10886 10887 Input Parameters: 10888 + mat - the matrix 10889 . op - the name of the operation 10890 - f - the function that provides the operation 10891 10892 Level: developer 10893 10894 Usage: 10895 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10896 $ ierr = MatCreateXXX(comm,...&A); 10897 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10898 10899 Notes: 10900 See the file include/petscmat.h for a complete list of matrix 10901 operations, which all have the form MATOP_<OPERATION>, where 10902 <OPERATION> is the name (in all capital letters) of the 10903 user interface routine (e.g., MatMult() -> MATOP_MULT). 10904 10905 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10906 sequence as the usual matrix interface routines, since they 10907 are intended to be accessed via the usual matrix interface 10908 routines, e.g., 10909 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10910 10911 In particular each function MUST return an error code of 0 on success and 10912 nonzero on failure. 10913 10914 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10915 10916 .keywords: matrix, set, operation 10917 10918 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10919 @*/ 10920 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10921 { 10922 PetscFunctionBegin; 10923 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10924 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10925 mat->ops->viewnative = mat->ops->view; 10926 } 10927 (((void(**)(void))mat->ops)[op]) = f; 10928 PetscFunctionReturn(0); 10929 } 10930 10931 /*@C 10932 MatGetOperation - Gets a matrix operation for any matrix type. 10933 10934 Not Collective 10935 10936 Input Parameters: 10937 + mat - the matrix 10938 - op - the name of the operation 10939 10940 Output Parameter: 10941 . f - the function that provides the operation 10942 10943 Level: developer 10944 10945 Usage: 10946 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10947 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10948 10949 Notes: 10950 See the file include/petscmat.h for a complete list of matrix 10951 operations, which all have the form MATOP_<OPERATION>, where 10952 <OPERATION> is the name (in all capital letters) of the 10953 user interface routine (e.g., MatMult() -> MATOP_MULT). 10954 10955 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10956 10957 .keywords: matrix, get, operation 10958 10959 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10960 @*/ 10961 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10962 { 10963 PetscFunctionBegin; 10964 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10965 *f = (((void (**)(void))mat->ops)[op]); 10966 PetscFunctionReturn(0); 10967 } 10968 10969 /*@ 10970 MatHasOperation - Determines whether the given matrix supports the particular 10971 operation. 10972 10973 Not Collective 10974 10975 Input Parameters: 10976 + mat - the matrix 10977 - op - the operation, for example, MATOP_GET_DIAGONAL 10978 10979 Output Parameter: 10980 . has - either PETSC_TRUE or PETSC_FALSE 10981 10982 Level: advanced 10983 10984 Notes: 10985 See the file include/petscmat.h for a complete list of matrix 10986 operations, which all have the form MATOP_<OPERATION>, where 10987 <OPERATION> is the name (in all capital letters) of the 10988 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10989 10990 .keywords: matrix, has, operation 10991 10992 .seealso: MatCreateShell() 10993 @*/ 10994 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10995 { 10996 PetscErrorCode ierr; 10997 10998 PetscFunctionBegin; 10999 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11000 PetscValidType(mat,1); 11001 PetscValidPointer(has,3); 11002 if (mat->ops->hasoperation) { 11003 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 11004 } else { 11005 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 11006 else { 11007 *has = PETSC_FALSE; 11008 if (op == MATOP_CREATE_SUBMATRIX) { 11009 PetscMPIInt size; 11010 11011 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 11012 if (size == 1) { 11013 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 11014 } 11015 } 11016 } 11017 } 11018 PetscFunctionReturn(0); 11019 } 11020 11021 /*@ 11022 MatHasCongruentLayouts - Determines whether the rows and columns layouts 11023 of the matrix are congruent 11024 11025 Collective on mat 11026 11027 Input Parameters: 11028 . mat - the matrix 11029 11030 Output Parameter: 11031 . cong - either PETSC_TRUE or PETSC_FALSE 11032 11033 Level: beginner 11034 11035 Notes: 11036 11037 .keywords: matrix, has 11038 11039 .seealso: MatCreate(), MatSetSizes() 11040 @*/ 11041 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 11042 { 11043 PetscErrorCode ierr; 11044 11045 PetscFunctionBegin; 11046 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11047 PetscValidType(mat,1); 11048 PetscValidPointer(cong,2); 11049 if (!mat->rmap || !mat->cmap) { 11050 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11051 PetscFunctionReturn(0); 11052 } 11053 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11054 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 11055 if (*cong) mat->congruentlayouts = 1; 11056 else mat->congruentlayouts = 0; 11057 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11058 PetscFunctionReturn(0); 11059 } 11060