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