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